wip: currently rewriting the project as a full stack application
tangled.org/kacaii.dev/sigo
gleam
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}