wip: currently rewriting the project as a full stack application tangled.org/kacaii.dev/sigo
gleam

:recycle: return nothing on `check_authorization` function

+29 -20
+13 -8
src/app/domain/user.gleam
··· 48 48 pub fn check_authorization( 49 49 request request: wisp.Request, 50 50 authorized roles: List(role.Role), 51 - ) -> Result(role.Role, AccessControlError) { 51 + ) -> Result(Nil, AccessControlError) { 52 52 use token <- result.try( 53 53 session.extract(request) 54 54 |> result.map_error(Session), 55 55 ) 56 56 57 - // 󰈞 Check if that role has authorization 58 - list.find(roles, fn(role) { token.user_role == role }) 59 - |> result.replace_error(NotAuthorized( 60 - user_uuid: token.user_id, 61 - user_role: token.user_role, 62 - authorized: roles, 63 - )) 57 + let not_authorized = 58 + NotAuthorized( 59 + user_uuid: token.user_id, 60 + user_role: token.user_role, 61 + authorized: roles, 62 + ) 63 + 64 + // 󰈞 Check if the given role is authorized 65 + fn(role) { token.user_role == role } 66 + |> list.find(roles, _) 67 + |> result.replace_error(not_authorized) 68 + |> result.replace(Nil) 64 69 } 65 70 66 71 pub fn handle_access_control_error(err: AccessControlError) -> wisp.Response {
+9
src/app/web.gleam
··· 26 26 import gleam/string 27 27 import pog 28 28 import wisp 29 + import youid/uuid 29 30 30 31 /// Middleware that runs before every request. 31 32 /// It sets up the request, and then calls the next handler. ··· 136 137 pog.UnexpectedResultType(err) -> handle_decode_error(err) 137 138 } 138 139 } 140 + 141 + pub fn uuid_decoder(expected: String) -> decode.Decoder(uuid.Uuid) { 142 + use field <- decode.then(decode.string) 143 + case uuid.from_string(field) { 144 + Error(_) -> decode.failure(uuid.v7(), expected:) 145 + Ok(value) -> decode.success(value) 146 + } 147 + }
+7 -12
src/app/web/session.gleam
··· 1 1 import app/domain/role 2 + import app/web 2 3 import gleam/dynamic/decode 3 4 import gleam/json 4 5 import gleam/result ··· 18 19 Session(user_id: uuid.Uuid, user_role: role.Role) 19 20 } 20 21 21 - pub fn extract(req: wisp.Request) { 22 + /// Extract the session token from the Request 23 + pub fn extract(req: wisp.Request) -> Result(Session, SessionError) { 22 24 use raw <- result.try( 23 25 wisp.get_cookie(request: req, name: cookie_name, security: wisp.Signed) 24 26 |> result.replace_error(MissingCookie), ··· 49 51 } 50 52 51 53 pub fn decoder() -> decode.Decoder(Session) { 52 - use user_id <- decode.field("user_id", uuid_decoder()) 53 - use user_role <- decode.field("user_role", role.decoder()) 54 - decode.success(Session(user_id:, user_role:)) 55 - } 56 - 57 - fn uuid_decoder() -> decode.Decoder(uuid.Uuid) { 58 - use field <- decode.then(decode.string) 59 - case uuid.from_string(field) { 60 - Error(_) -> decode.failure(uuid.v7(), "uuid") 61 - Ok(value) -> decode.success(value) 62 - } 54 + decode.field("user_id", web.uuid_decoder("user_uuid"), fn(user_id) { 55 + use user_role <- decode.field("user_role", role.decoder()) 56 + decode.success(Session(user_id:, user_role:)) 57 + }) 63 58 }