chore: get collab http (#463)

* chore: get collab http

* fix: use correct version

* fix: collab url

* feat: update collab access control middleware
This commit is contained in:
Zack 2024-04-12 11:08:38 +08:00 committed by GitHub
parent dd9cc8d4c7
commit 9a5636caec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 68 additions and 11 deletions

View File

@ -12,6 +12,7 @@ use gotrue::grant::{Grant, RefreshTokenGrant};
use parking_lot::RwLock; use parking_lot::RwLock;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use reqwest::Method; use reqwest::Method;
use shared_entity::dto::workspace_dto::CollabTypeParam;
use shared_entity::response::{AppResponse, AppResponseError}; use shared_entity::response::{AppResponse, AppResponseError};
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
@ -176,16 +177,17 @@ impl Action for GetCollabAction {
fn run(&mut self) -> Self::Future { fn run(&mut self) -> Self::Future {
let client = self.client.clone(); let client = self.client.clone();
let params = self.params.clone(); let params = self.params.clone();
let collab_type = self.params.collab_type.clone();
Box::pin(async move { Box::pin(async move {
let url = format!( let url = format!(
"{}/api/workspace/{}/collab/{}", "{}/api/workspace/v1/{}/collab/{}",
client.base_url, &params.workspace_id, &params.object_id client.base_url, &params.workspace_id, &params.object_id
); );
let resp = client let resp = client
.http_client_with_auth(Method::GET, &url) .http_client_with_auth(Method::GET, &url)
.await? .await?
.json(&params) .query(&CollabTypeParam { collab_type })
.send() .send()
.await?; .await?;
log_request_id(&resp); log_request_id(&resp);

View File

@ -1,4 +1,5 @@
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use collab_entity::CollabType;
use database_entity::dto::{AFRole, AFWorkspaceInvitationStatus}; use database_entity::dto::{AFRole, AFWorkspaceInvitationStatus};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::ops::Deref; use std::ops::Deref;
@ -100,3 +101,8 @@ pub struct PatchWorkspaceParam {
pub workspace_name: Option<String>, pub workspace_name: Option<String>,
pub workspace_icon: Option<String>, pub workspace_icon: Option<String>,
} }
#[derive(Serialize, Deserialize)]
pub struct CollabTypeParam {
pub collab_type: CollabType,
}

View File

@ -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_MEMBER_PATTERN: &str = "/api/workspace/{workspace_id}/member";
pub const WORKSPACE_INVITE_PATTERN: &str = "/api/workspace/{workspace_id}/invite"; 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 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 { pub fn workspace_scope() -> Scope {
web::scope("/api/workspace") web::scope("/api/workspace")
@ -86,6 +87,10 @@ pub fn workspace_scope() -> Scope {
.route(web::put().to(update_collab_handler)) .route(web::put().to(update_collab_handler))
.route(web::delete().to(delete_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( .service(
web::resource("/{workspace_id}/batch/collab") web::resource("/{workspace_id}/batch/collab")
.route(web::post().to(batch_create_collab_handler)), .route(web::post().to(batch_create_collab_handler)),
@ -576,6 +581,8 @@ async fn create_collab_list_handler(
Ok(Json(AppResponse::Ok())) Ok(Json(AppResponse::Ok()))
} }
// Deprecated
async fn get_collab_handler( async fn get_collab_handler(
user_uuid: UserUuid, user_uuid: UserUuid,
payload: Json<QueryCollabParams>, payload: Json<QueryCollabParams>,
@ -595,6 +602,37 @@ async fn get_collab_handler(
Ok(Json(AppResponse::Ok().with_data(data))) Ok(Json(AppResponse::Ok().with_data(data)))
} }
async fn v1_get_collab_handler(
user_uuid: UserUuid,
path: web::Path<(String, String)>,
query: web::Query<CollabTypeParam>,
state: Data<AppState>,
) -> Result<Json<AppResponse<EncodedCollab>>> {
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)] #[instrument(level = "trace", skip_all, err)]
async fn get_collab_snapshot_handler( async fn get_collab_snapshot_handler(
payload: Json<QuerySnapshotParams>, payload: Json<QuerySnapshotParams>,

View File

@ -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::biz::workspace::access_control::WorkspaceAccessControl;
use crate::middleware::access_control_mw::{AccessResource, MiddlewareAccessControl}; use crate::middleware::access_control_mw::{AccessResource, MiddlewareAccessControl};
use actix_router::{Path, ResourceDef, Url}; use actix_router::{Path, ResourceDef, Url};
@ -61,15 +61,26 @@ where
skip_resources: vec![ skip_resources: vec![
// Skip access control when trying to create a collab // Skip access control when trying to create a collab
(Method::POST, ResourceDef::new(COLLAB_PATTERN)), (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, access_control,
collab_cache, collab_cache,
} }