chore: add specific error code for wrong invitee

This commit is contained in:
Zack Fu Zi Xiang 2024-09-13 21:02:09 +08:00
parent 78353f751f
commit 4b59574392
No known key found for this signature in database
5 changed files with 59 additions and 1 deletions

View File

@ -142,6 +142,9 @@ pub enum AppError {
#[error("{0}")]
InvalidFolderView(String),
#[error("{0}")]
NotInviteeOfWorkspaceInvitation(String),
}
impl AppError {
@ -208,6 +211,7 @@ impl AppError {
AppError::InvalidContentType(_) => ErrorCode::InvalidContentType,
AppError::InvalidPublishedOutline(_) => ErrorCode::InvalidPublishedOutline,
AppError::InvalidFolderView(_) => ErrorCode::InvalidFolderView,
AppError::NotInviteeOfWorkspaceInvitation(_) => ErrorCode::NotInviteeOfWorkspaceInvitation,
}
}
}
@ -328,6 +332,7 @@ pub enum ErrorCode {
AppleRevokeTokenError = 1038,
InvalidPublishedOutline = 1039,
InvalidFolderView = 1040,
NotInviteeOfWorkspaceInvitation = 1041,
}
impl ErrorCode {

View File

@ -1376,3 +1376,24 @@ pub async fn delete_reaction_from_comment<'a, E: Executor<'a, Database = Postgre
Ok(())
}
pub async fn select_user_is_invitee_for_workspace_invitation(
pg_pool: &PgPool,
invitee_uuid: &Uuid,
invite_id: &Uuid,
) -> Result<bool, AppError> {
let res = sqlx::query_scalar!(
r#"
SELECT EXISTS(
SELECT 1
FROM af_workspace_invitation
WHERE id = $1 AND invitee_email = (SELECT email FROM af_user WHERE uuid = $2)
)
"#,
invite_id,
invitee_uuid,
)
.fetch_one(pg_pool)
.await?;
res.map_or(Ok(false), Ok)
}

View File

@ -340,12 +340,14 @@ async fn post_accept_workspace_invite_handler(
) -> Result<JsonAppResponse<()>> {
let _is_new = verify_token(&auth.token, state.as_ref()).await?;
let user_uuid = auth.uuid()?;
let user_uid = state.user_cache.get_user_uid(&user_uuid).await?;
let invite_id = invite_id.into_inner();
// TODO(zack): insert a workspace member in the af_workspace_member by calling workspace::ops::add_workspace_members.
// Currently, when the server get restarted, the policy in access control will be lost.
workspace::ops::accept_workspace_invite(
&state.pg_pool,
&state.workspace_access_control,
user_uid,
&user_uuid,
&invite_id,
)

View File

@ -302,12 +302,21 @@ pub async fn open_workspace(
pub async fn accept_workspace_invite(
pg_pool: &PgPool,
workspace_access_control: &impl WorkspaceAccessControl,
user_uid: i64,
user_uuid: &Uuid,
invite_id: &Uuid,
) -> Result<(), AppError> {
let mut txn = pg_pool.begin().await?;
update_workspace_invitation_set_status_accepted(&mut txn, user_uuid, invite_id).await?;
let inv = get_invitation_by_id(&mut txn, invite_id).await?;
if let Some(invitee_uid) = inv.invitee_uid {
if invitee_uid != user_uid {
return Err(AppError::NotInviteeOfWorkspaceInvitation(format!(
"User with uid {} is not the invitee for invite_id {}",
user_uid, invite_id
)));
}
}
update_workspace_invitation_set_status_accepted(&mut txn, user_uuid, invite_id).await?;
let invited_uid = inv
.invitee_uid
.ok_or_else(|| AppError::Internal(anyhow::anyhow!("Invitee uid is missing for {:?}", inv)))?;
@ -469,6 +478,14 @@ pub async fn get_workspace_invitations_for_user(
user_uuid: &Uuid,
invite_id: &Uuid,
) -> Result<AFWorkspaceInvitation, AppError> {
let user_is_invitee =
select_user_is_invitee_for_workspace_invitation(pg_pool, user_uuid, invite_id).await?;
if !user_is_invitee {
return Err(AppError::NotInviteeOfWorkspaceInvitation(format!(
"User with uuid {} is not the invitee for invite_id {}",
user_uuid, invite_id
)));
}
let invitation = select_workspace_invitation_for_user(pg_pool, user_uuid, invite_id).await?;
Ok(invitation)
}

View File

@ -1,3 +1,4 @@
use app_error::ErrorCode;
use client_api_test::generate_unique_registered_user_client;
use database_entity::dto::{AFRole, AFWorkspaceInvitationStatus};
use shared_entity::dto::workspace_dto::{QueryWorkspaceParam, WorkspaceMemberInvitation};
@ -61,6 +62,18 @@ async fn invite_workspace_crud() {
assert_eq!(invitation.status, AFWorkspaceInvitationStatus::Pending);
assert_eq!(invitation.member_count.unwrap_or(0), 1);
let (charlie_client, _charlie) = generate_unique_registered_user_client().await;
let err = charlie_client
.get_workspace_invitation(&invite_id)
.await
.unwrap_err();
assert_eq!(err.code, ErrorCode::NotInviteeOfWorkspaceInvitation);
let err = charlie_client
.accept_workspace_invitation(&invite_id)
.await
.unwrap_err();
assert_eq!(err.code, ErrorCode::NotInviteeOfWorkspaceInvitation);
bob_client
.accept_workspace_invitation(&invite_id)
.await