From 1a0347337ce7049364db43b60ca53c0e972d100c Mon Sep 17 00:00:00 2001 From: oxalica Date: Tue, 10 Sep 2024 07:56:25 -0400 Subject: [PATCH] feat(webapi): differentiate no-room-permission from not-a-member error - If a user is not a room member, HTTP 404 code=not_found will be returned. This also happen for posting into not-joined public rooms, and it can be interpreted as "room member is not found". - If a user is a member but lacks the member permission to perform an action, HTTP 403 code=permission_denied will be returned. --- blahd/src/lib.rs | 46 ++++++++++++++++++++++++++++++---------------- docs/webapi.yaml | 24 +++++++++++++++--------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/blahd/src/lib.rs b/blahd/src/lib.rs index abb32be..cb1fc2d 100644 --- a/blahd/src/lib.rs +++ b/blahd/src/lib.rs @@ -603,7 +603,13 @@ fn get_room_if_readable( f, ) .optional()? - .ok_or_else(|| error_response!(StatusCode::NOT_FOUND, "not_found", "room not found")) + .ok_or_else(|| { + error_response!( + StatusCode::NOT_FOUND, + "not_found", + "the room does not exist or the user is not a room member", + ) + }) } /// Get room items with pagination parameters, @@ -675,7 +681,7 @@ async fn room_item_post( let (cid, txs) = { let conn = st.db.get(); - let Some((uid, _perm)) = conn + let (uid, perm) = conn .query_row( r" SELECT `uid`, `room_member`.`permission` @@ -696,14 +702,21 @@ async fn room_item_post( }, ) .optional()? - .filter(|(_, perm)| perm.contains(MemberPermission::POST_CHAT)) - else { + .ok_or_else(|| { + error_response!( + StatusCode::NOT_FOUND, + "not_found", + "the room does not exist or the user is not a room member", + ) + })?; + + if !perm.contains(MemberPermission::POST_CHAT) { return Err(error_response!( StatusCode::FORBIDDEN, "permission_denied", - "the user does not have permission to post in this room", + "the user does not have permission to post item in the room", )); - }; + } let cid = Id::gen(); conn.execute( @@ -825,7 +838,7 @@ async fn room_join( return Err(error_response!( StatusCode::NOT_FOUND, "not_found", - "room does not exists or user is not allowed to join this room", + "the room does not exist or the user is not allowed to join the room", )); } @@ -866,7 +879,7 @@ async fn room_leave(st: &AppState, rid: Id, user: UserKey) -> Result<(), ApiErro let mut conn = st.db.get(); let txn = conn.transaction()?; - let Some(uid) = txn + let uid = txn .query_row( r" SELECT `uid` @@ -882,13 +895,14 @@ async fn room_leave(st: &AppState, rid: Id, user: UserKey) -> Result<(), ApiErro |row| row.get::<_, u64>("uid"), ) .optional()? - else { - return Err(error_response!( - StatusCode::NOT_FOUND, - "not_found", - "room does not exists or user is not a room member", - )); - }; + .ok_or_else(|| { + error_response!( + StatusCode::NOT_FOUND, + "not_found", + "the room does not exist or user is not a room member", + ) + })?; + txn.execute( r" DELETE FROM `room_member` @@ -929,7 +943,7 @@ async fn room_item_mark_seen( return Err(error_response!( StatusCode::NOT_FOUND, "not_found", - "room does not exists or user is not a room member", + "the room does not exist or the user is not a room member", )); } Ok(StatusCode::NO_CONTENT) diff --git a/docs/webapi.yaml b/docs/webapi.yaml index 3524076..e176bb9 100644 --- a/docs/webapi.yaml +++ b/docs/webapi.yaml @@ -170,17 +170,18 @@ paths: 204: description: Operation completed. - 409: - description: - Operation is already done, eg. joining an already joined room. + 404: + description: | + Room does not exist or the user does not have permission for the + operation. content: application/json: schema: $ref: '#/components/schemas/ApiError' - 404: - description: | - Room does not exist or the user does not have permission for management. + 409: + description: + Operation is already done, eg. joining an already joined room. content: application/json: schema: @@ -271,10 +272,15 @@ paths: type: string description: Newly created item `cid`. - # FIXME: Distinguish this from 404? 403: - description: | - The user does not have permission to post in this room, or the room does not exist. + description: The user does not have permission to post in this room. + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' + + 404: + description: The room does not exist or the user is not a room member. content: application/json: schema: