feat: partage dirigé entre utilisateurs #196
- create_share/shared_with + validation des destinataires
- gate auth sur /s/{token} (+pdf, raw) : 404 opaque hors créateur/admin/destinataires
- GET /api/shares scopé (non-admin = créés + reçus), révocation créateur/admin
- UI : dialogue dirigé/public + destinataires, dashboard « partagé par X »
- i18n FR/EN, tests test_directed_shares.py (9), fiche feature
This commit is contained in:
+17
-3
@@ -44,8 +44,14 @@ def create_share(
|
||||
path: str,
|
||||
created_by: str,
|
||||
expires_in_hours: int | None = None,
|
||||
shared_with: list[str] | None = None,
|
||||
) -> dict:
|
||||
"""Create a new share token for a document."""
|
||||
"""Create a new share token for a document.
|
||||
|
||||
``shared_with`` non vide (#196) : partage **dirigé** — la page ``/s/…``
|
||||
exige alors une session et n'accepte que les destinataires listés (plus
|
||||
le créateur et les admins). Vide/absent : comportement public inchangé.
|
||||
"""
|
||||
with _lock:
|
||||
data = _read()
|
||||
token = secrets.token_hex(32) # 64-char hex token
|
||||
@@ -64,6 +70,7 @@ def create_share(
|
||||
"expires_at": expires_at,
|
||||
"access_count": 0,
|
||||
"last_accessed": None,
|
||||
"shared_with": list(shared_with) if shared_with else [],
|
||||
}
|
||||
data["shares"][token] = share
|
||||
_write(data)
|
||||
@@ -107,10 +114,17 @@ def revoke_share(share_id: str) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def list_shares(vault_filter: str | None = None) -> list:
|
||||
"""List all shares, optionally filtered by vault."""
|
||||
def list_shares(vault_filter: str | None = None, user: str | None = None) -> list:
|
||||
"""List shares, optionally filtered by vault and/or requesting user.
|
||||
|
||||
#196 : un non-admin ne voit que les partages qu'il a créés **ou** qui lui
|
||||
sont dirigés. Un admin voit tout. ``user=None`` (anciens appels, tests
|
||||
unitaires) conserve l'ancien comportement : tout lister.
|
||||
"""
|
||||
data = _read()
|
||||
shares = list(data["shares"].values())
|
||||
if user is not None:
|
||||
shares = [s for s in shares if user in (s.get("created_by"), *(s.get("shared_with") or []))]
|
||||
if vault_filter:
|
||||
shares = [s for s in shares if s["vault"] == vault_filter]
|
||||
# Most recent first
|
||||
|
||||
Reference in New Issue
Block a user