From 9a5636caec10ee453fea964e938e822648ddf0a3 Mon Sep 17 00:00:00 2001 From: Zack Date: Fri, 12 Apr 2024 11:08:38 +0800 Subject: [PATCH] chore: get collab http (#463) * chore: get collab http * fix: use correct version * fix: collab url * feat: update collab access control middleware --- libs/client-api/src/native/retry.rs | 6 ++-- libs/shared-entity/src/dto/workspace_dto.rs | 6 ++++ src/api/workspace.rs | 38 +++++++++++++++++++++ src/biz/collab/access_control.rs | 29 +++++++++++----- 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/libs/client-api/src/native/retry.rs b/libs/client-api/src/native/retry.rs index 4693bae8..1929135d 100644 --- a/libs/client-api/src/native/retry.rs +++ b/libs/client-api/src/native/retry.rs @@ -12,6 +12,7 @@ use gotrue::grant::{Grant, RefreshTokenGrant}; use parking_lot::RwLock; use reqwest::header::HeaderMap; use reqwest::Method; +use shared_entity::dto::workspace_dto::CollabTypeParam; use shared_entity::response::{AppResponse, AppResponseError}; use std::future::Future; use std::pin::Pin; @@ -176,16 +177,17 @@ impl Action for GetCollabAction { fn run(&mut self) -> Self::Future { let client = self.client.clone(); let params = self.params.clone(); + let collab_type = self.params.collab_type.clone(); Box::pin(async move { let url = format!( - "{}/api/workspace/{}/collab/{}", + "{}/api/workspace/v1/{}/collab/{}", client.base_url, ¶ms.workspace_id, ¶ms.object_id ); let resp = client .http_client_with_auth(Method::GET, &url) .await? - .json(¶ms) + .query(&CollabTypeParam { collab_type }) .send() .await?; log_request_id(&resp); diff --git a/libs/shared-entity/src/dto/workspace_dto.rs b/libs/shared-entity/src/dto/workspace_dto.rs index 7c95586e..3216c4ef 100644 --- a/libs/shared-entity/src/dto/workspace_dto.rs +++ b/libs/shared-entity/src/dto/workspace_dto.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use collab_entity::CollabType; use database_entity::dto::{AFRole, AFWorkspaceInvitationStatus}; use serde::{Deserialize, Serialize}; use std::ops::Deref; @@ -100,3 +101,8 @@ pub struct PatchWorkspaceParam { pub workspace_name: Option, pub workspace_icon: Option, } + +#[derive(Serialize, Deserialize)] +pub struct CollabTypeParam { + pub collab_type: CollabType, +} diff --git a/src/api/workspace.rs b/src/api/workspace.rs index 4131f77e..c9a4d5ca 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -41,6 +41,7 @@ pub const WORKSPACE_PATTERN: &str = "/api/workspace"; pub const WORKSPACE_MEMBER_PATTERN: &str = "/api/workspace/{workspace_id}/member"; pub const WORKSPACE_INVITE_PATTERN: &str = "/api/workspace/{workspace_id}/invite"; pub const COLLAB_PATTERN: &str = "/api/workspace/{workspace_id}/collab/{object_id}"; +pub const V1_COLLAB_PATTERN: &str = "/api/workspace/v1/{workspace_id}/collab/{object_id}"; pub fn workspace_scope() -> Scope { web::scope("/api/workspace") @@ -86,6 +87,10 @@ pub fn workspace_scope() -> Scope { .route(web::put().to(update_collab_handler)) .route(web::delete().to(delete_collab_handler)), ) + .service( + web::resource("/v1/{workspace_id}/collab/{object_id}") + .route(web::get().to(v1_get_collab_handler)) + ) .service( web::resource("/{workspace_id}/batch/collab") .route(web::post().to(batch_create_collab_handler)), @@ -576,6 +581,8 @@ async fn create_collab_list_handler( Ok(Json(AppResponse::Ok())) } + +// Deprecated async fn get_collab_handler( user_uuid: UserUuid, payload: Json, @@ -595,6 +602,37 @@ async fn get_collab_handler( Ok(Json(AppResponse::Ok().with_data(data))) } +async fn v1_get_collab_handler( + user_uuid: UserUuid, + path: web::Path<(String, String)>, + query: web::Query, + state: Data, +) -> Result>> { + let (workspace_id, object_id) = path.into_inner(); + let collab_type = query.into_inner().collab_type; + let uid = state + .user_cache + .get_user_uid(&user_uuid) + .await + .map_err(AppResponseError::from)?; + + let param = QueryCollabParams { + workspace_id, + inner: QueryCollab { + object_id, + collab_type, + }, + }; + + let data = state + .collab_access_control_storage + .get_collab_encoded(&uid, param, false) + .await + .map_err(AppResponseError::from)?; + + Ok(Json(AppResponse::Ok().with_data(data))) +} + #[instrument(level = "trace", skip_all, err)] async fn get_collab_snapshot_handler( payload: Json, diff --git a/src/biz/collab/access_control.rs b/src/biz/collab/access_control.rs index 5f0811a7..24046df4 100644 --- a/src/biz/collab/access_control.rs +++ b/src/biz/collab/access_control.rs @@ -1,4 +1,4 @@ -use crate::api::workspace::COLLAB_PATTERN; +use crate::api::workspace::{COLLAB_PATTERN, V1_COLLAB_PATTERN}; use crate::biz::workspace::access_control::WorkspaceAccessControl; use crate::middleware::access_control_mw::{AccessResource, MiddlewareAccessControl}; use actix_router::{Path, ResourceDef, Url}; @@ -61,15 +61,26 @@ where skip_resources: vec![ // Skip access control when trying to create a collab (Method::POST, ResourceDef::new(COLLAB_PATTERN)), + (Method::POST, ResourceDef::new(V1_COLLAB_PATTERN)), + ], + require_access_levels: vec![ + ( + ResourceDef::new(COLLAB_PATTERN), + [ + // Only the user with FullAccess can delete the collab + (Method::DELETE, AFAccessLevel::FullAccess), + ] + .into(), + ), + ( + ResourceDef::new(V1_COLLAB_PATTERN), + [ + // Only the user with FullAccess can delete the collab + (Method::DELETE, AFAccessLevel::FullAccess), + ] + .into(), + ), ], - require_access_levels: vec![( - ResourceDef::new(COLLAB_PATTERN), - [ - // Only the user with FullAccess can delete the collab - (Method::DELETE, AFAccessLevel::FullAccess), - ] - .into(), - )], access_control, collab_cache, }