wip: currently rewriting the project as a full stack application tangled.org/kacaii.dev/sigo
gleam
at main 108 lines 2.9 kB view raw
1import app/domain/role 2import app/domain/user 3import app/domain/user/sql 4import app/web 5import app/web/context.{type Context} 6import app/web/session 7import gleam/http 8import gleam/json 9import gleam/list 10import gleam/result 11import pog 12import wisp 13import youid/uuid 14 15/// 󰀕 Remove an user account from the database and 16/// return their uuid as a formatted JSON response. 17/// 18/// ```json 19/// { 20/// "id": "92ce4d0b-59e2-4437-bbf1-ebad7b59a9f1" 21/// } 22/// ``` 23pub fn handle_request( 24 request req: wisp.Request, 25 ctx ctx: Context, 26 id user_id: String, 27) -> wisp.Response { 28 use <- wisp.require_method(req, http.Delete) 29 30 case query_database(req, ctx, user_id) { 31 Ok(deleted_user) -> wisp.json_response(deleted_user, 200) 32 Error(err) -> handle_error(err) 33 } 34} 35 36///  Deleting an user can fail 37type DeleteUserError { 38 /// 󱙀 An error occurred while accessing the DataBase 39 DataBase(pog.QueryError) 40 /// 󰘨 Target user has invalid Uuid 41 InvalidUserUuid(String) 42 /// 󱋟 Errors related to authentication and authorization 43 AccessControl(user.AccessControlError) 44 /// 󰀒 User was not found in the Database 45 UserNotFound(uuid.Uuid) 46 /// 󱅞 An user should not be able to delete theirself 47 CantDeleteSelf 48 Authentication(session.SessionError) 49} 50 51fn handle_error(err: DeleteUserError) -> wisp.Response { 52 case err { 53 InvalidUserUuid(invalid_uuid) -> 54 wisp.bad_request("Usuário possui Uuid Inválido: " <> invalid_uuid) 55 UserNotFound(user_uuid) -> 56 wisp.bad_request("Usuário não encontrado: " <> uuid.to_string(user_uuid)) 57 AccessControl(err) -> user.handle_access_control_error(err) 58 DataBase(err) -> web.handle_database_error(err) 59 CantDeleteSelf -> wisp.bad_request("Um usuário não deve remover a si mesmo") 60 Authentication(err) -> session.handle_error(err) 61 } 62} 63 64fn query_database( 65 req: wisp.Request, 66 ctx: Context, 67 target_id: String, 68) -> Result(String, DeleteUserError) { 69 use token <- result.try( 70 session.extract(req) 71 |> result.map_error(Authentication), 72 ) 73 74 use target_user_uuid <- result.try( 75 uuid.from_string(target_id) 76 |> result.replace_error(InvalidUserUuid(target_id)), 77 ) 78 79 use _ <- result.try( 80 user.check_authorization(request: req, authorized: [ 81 role.Admin, 82 role.Developer, 83 ]) 84 |> result.map_error(AccessControl), 85 ) 86 87 case uuid.to_string(token.user_id) == target_id { 88 True -> Error(CantDeleteSelf) 89 False -> { 90 use returned <- result.try( 91 sql.delete_user_by_id(ctx.db, target_user_uuid) 92 |> result.map_error(DataBase), 93 ) 94 95 use row <- result.map( 96 list.first(returned.rows) 97 |> result.replace_error(UserNotFound(token.user_id)), 98 ) 99 100 [ 101 #("id", json.string(uuid.to_string(row.id))), 102 #("full_name", json.string(row.full_name)), 103 ] 104 |> json.object 105 |> json.to_string 106 } 107 } 108}