readonly role
This commit is contained in:
@@ -53,6 +53,14 @@ const USER_CAPABILITIES: [ApiCapability; 16] = [
|
||||
ApiCapability::WebdavRead,
|
||||
];
|
||||
|
||||
const READONLY_CAPABILITIES: [ApiCapability; 5] = [
|
||||
ApiCapability::CorrespondentsRead,
|
||||
ApiCapability::DocumentsRead,
|
||||
ApiCapability::FoldersRead,
|
||||
ApiCapability::TagsRead,
|
||||
ApiCapability::WebdavRead,
|
||||
];
|
||||
|
||||
const WEBDAV_CAPABILITIES: [ApiCapability; 1] = [ApiCapability::WebdavRead];
|
||||
|
||||
pub fn owner_capabilities() -> &'static [ApiCapability] {
|
||||
@@ -63,12 +71,16 @@ pub fn user_capabilities() -> &'static [ApiCapability] {
|
||||
&USER_CAPABILITIES
|
||||
}
|
||||
|
||||
pub fn readonly_capabilities() -> &'static [ApiCapability] {
|
||||
&READONLY_CAPABILITIES
|
||||
}
|
||||
|
||||
pub fn webdav_capabilities() -> &'static [ApiCapability] {
|
||||
&WEBDAV_CAPABILITIES
|
||||
}
|
||||
|
||||
pub fn is_system_slug(slug: &str) -> bool {
|
||||
matches!(slug, "owner" | "user" | "webdav")
|
||||
matches!(slug, "owner" | "user" | "readonly" | "webdav")
|
||||
}
|
||||
|
||||
pub fn create_capability_set<C>(
|
||||
@@ -175,7 +187,7 @@ where
|
||||
tenant_id,
|
||||
slug: slug.clone(),
|
||||
cap_version: 1,
|
||||
is_system: slug == "owner" || slug == "user" || slug == "webdav",
|
||||
is_system: matches!(slug.as_str(), "owner" | "user" | "readonly" | "webdav"),
|
||||
};
|
||||
|
||||
diesel::insert_into(capability_sets::table)
|
||||
@@ -243,6 +255,10 @@ pub fn compute_slug(capabilities: &[ApiCapability]) -> String {
|
||||
return "user".to_string();
|
||||
}
|
||||
|
||||
if capabilities == readonly_capabilities() {
|
||||
return "readonly".to_string();
|
||||
}
|
||||
|
||||
if capabilities == webdav_capabilities() {
|
||||
return "webdav".to_string();
|
||||
}
|
||||
|
||||
+32
-4
@@ -10,8 +10,8 @@ pub mod sql_types {
|
||||
pub struct TenantStatus;
|
||||
|
||||
#[derive(diesel::query_builder::QueryId, Clone, diesel::sql_types::SqlType)]
|
||||
#[diesel(postgres_type(name = "api_token_capability"))]
|
||||
pub struct ApiTokenCapability;
|
||||
#[diesel(postgres_type(name = "api_capability"))]
|
||||
pub struct ApiCapability;
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
@@ -204,6 +204,7 @@ diesel::table! {
|
||||
tenant_id -> Uuid,
|
||||
created_at -> Timestamptz,
|
||||
updated_at -> Timestamptz,
|
||||
capability_set_id -> Nullable<Uuid>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,8 +252,29 @@ diesel::table! {
|
||||
|
||||
diesel::table! {
|
||||
use diesel::sql_types::*;
|
||||
use super::sql_types::ApiTokenCapability;
|
||||
|
||||
capability_sets (id) {
|
||||
id -> Uuid,
|
||||
tenant_id -> Uuid,
|
||||
slug -> Text,
|
||||
cap_version -> Int4,
|
||||
is_system -> Bool,
|
||||
created_at -> Timestamptz,
|
||||
updated_at -> Timestamptz,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
use diesel::sql_types::*;
|
||||
use super::sql_types::ApiCapability;
|
||||
|
||||
capability_set_capabilities (capability_set_id, capability) {
|
||||
capability_set_id -> Uuid,
|
||||
capability -> ApiCapability,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
api_tokens (id) {
|
||||
id -> Uuid,
|
||||
user_id -> Uuid,
|
||||
@@ -264,11 +286,13 @@ diesel::table! {
|
||||
last_used_at -> Nullable<Timestamptz>,
|
||||
expires_at -> Nullable<Timestamptz>,
|
||||
revoked_at -> Nullable<Timestamptz>,
|
||||
capabilities -> Array<ApiTokenCapability>,
|
||||
capability_set_id -> Uuid,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(correspondents -> tenants (tenant_id));
|
||||
diesel::joinable!(capability_set_capabilities -> capability_sets (capability_set_id));
|
||||
diesel::joinable!(capability_sets -> tenants (tenant_id));
|
||||
diesel::joinable!(document_asset_objects -> document_assets (asset_id));
|
||||
diesel::joinable!(document_asset_objects -> tenants (tenant_id));
|
||||
diesel::joinable!(document_assets -> document_versions (document_version_id));
|
||||
@@ -289,15 +313,19 @@ diesel::joinable!(jobs -> tenants (tenant_id));
|
||||
diesel::joinable!(user_sessions -> tenants (tenant_id));
|
||||
diesel::joinable!(user_sessions -> users (user_id));
|
||||
diesel::joinable!(tags -> tenants (tenant_id));
|
||||
diesel::joinable!(user_memberships -> capability_sets (capability_set_id));
|
||||
diesel::joinable!(user_memberships -> tenants (tenant_id));
|
||||
diesel::joinable!(user_memberships -> users (user_id));
|
||||
diesel::joinable!(user_passkeys -> users (user_id));
|
||||
diesel::joinable!(webauthn_challenges -> users (user_id));
|
||||
diesel::joinable!(api_tokens -> tenants (tenant_id));
|
||||
diesel::joinable!(api_tokens -> capability_sets (capability_set_id));
|
||||
diesel::joinable!(api_tokens -> users (user_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
correspondents,
|
||||
capability_set_capabilities,
|
||||
capability_sets,
|
||||
document_asset_objects,
|
||||
document_assets,
|
||||
document_correspondents,
|
||||
|
||||
@@ -9,7 +9,8 @@ use tracing::warn;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::auth::capability_sets::{
|
||||
ensure_capability_set, owner_capabilities, user_capabilities, webdav_capabilities,
|
||||
ensure_capability_set, owner_capabilities, readonly_capabilities, user_capabilities,
|
||||
webdav_capabilities,
|
||||
};
|
||||
use crate::documents::search::ensure_quickwit_index;
|
||||
use crate::jobs::JOB_PROVISION_TENANT;
|
||||
@@ -161,6 +162,19 @@ impl JobHandler for ProvisionTenantJob {
|
||||
};
|
||||
}
|
||||
|
||||
if let Err(err) = ensure_capability_set(&mut conn, tenant.id, readonly_capabilities()) {
|
||||
warn!(
|
||||
job_id = %job.id,
|
||||
tenant_id = %tenant.id,
|
||||
error = ?err,
|
||||
"failed to ensure readonly capability set during provisioning"
|
||||
);
|
||||
return JobExecution::Retry {
|
||||
delay: std::time::Duration::from_secs(30),
|
||||
error: "readonly capability set unavailable".into(),
|
||||
};
|
||||
}
|
||||
|
||||
if let Err(err) = ensure_capability_set(&mut conn, tenant.id, webdav_capabilities()) {
|
||||
warn!(
|
||||
job_id = %job.id,
|
||||
|
||||
Reference in New Issue
Block a user