refactor(share,grants): migrate expiration from legacy share into grants, simplify legacy share, normalize shareModal for better UX

This commit is contained in:
Edouard Vanbelle
2026-05-28 19:56:31 +02:00
parent 84d57dd2ae
commit 8800353900
17 changed files with 693 additions and 597 deletions
+9
View File
@@ -191,6 +191,9 @@ pub struct CreateGrantDto {
pub permissions: Option<Vec<PermissionDto>>,
#[serde(default)]
pub role: Option<Role>,
/// Optional expiry for every grant in this request. RFC 3339 / ISO 8601.
#[serde(default)]
pub expires_at: Option<chrono::DateTime<chrono::Utc>>,
}
/// `PUT /api/grants/role` — reconcile a subject's role on a resource.
@@ -199,6 +202,9 @@ pub struct UpdateRoleDto {
pub subject: SubjectDto,
pub resource: ResourceDto,
pub role: Role,
/// Optional expiry applied to every grant written or updated by this call.
#[serde(default)]
pub expires_at: Option<chrono::DateTime<chrono::Utc>>,
}
// ════════════════════════════════════════════════════════════════════════════
@@ -213,6 +219,8 @@ pub struct GrantDto {
pub permission: PermissionDto,
pub granted_by: Uuid,
pub granted_at: chrono::DateTime<chrono::Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<chrono::DateTime<chrono::Utc>>,
}
impl From<Grant> for GrantDto {
@@ -224,6 +232,7 @@ impl From<Grant> for GrantDto {
permission: g.permission.into(),
granted_by: g.granted_by,
granted_at: g.granted_at,
expires_at: g.expires_at,
}
}
}
+1 -27
View File
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use crate::domain::entities::share::{Share, SharePermissions};
use crate::domain::entities::share::Share;
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ShareDto {
@@ -13,19 +13,11 @@ pub struct ShareDto {
pub url: String,
pub has_password: bool,
pub expires_at: Option<u64>,
pub permissions: SharePermissionsDto,
pub created_at: u64,
pub created_by: String,
pub access_count: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct SharePermissionsDto {
pub read: bool,
pub write: bool,
pub reshare: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateShareDto {
pub item_id: String,
@@ -33,17 +25,14 @@ pub struct CreateShareDto {
pub item_type: String,
pub password: Option<String>,
pub expires_at: Option<u64>,
pub permissions: Option<SharePermissionsDto>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UpdateShareDto {
pub password: Option<String>,
pub expires_at: Option<u64>,
pub permissions: Option<SharePermissionsDto>,
}
/// Extension methods to convert between DTOs and domain entities
impl ShareDto {
pub fn from_entity(share: &Share, base_url: &str) -> Self {
let url = format!("{}/s/{}", base_url, share.token());
@@ -57,24 +46,9 @@ impl ShareDto {
url,
has_password: share.has_password(),
expires_at: share.expires_at(),
permissions: SharePermissionsDto::from_entity(share.permissions()),
created_at: share.created_at(),
created_by: share.created_by().to_string(),
access_count: share.access_count(),
}
}
}
impl SharePermissionsDto {
pub fn from_entity(permissions: &SharePermissions) -> Self {
Self {
read: permissions.read(),
write: permissions.write(),
reshare: permissions.reshare(),
}
}
pub fn to_entity(&self) -> SharePermissions {
SharePermissions::new(self.read, self.write, self.reshare)
}
}