koprogo_api/application/community_permissions.rs
1//! Vérification de permission partagée entre les use-cases Community (SEL,
2//! Poll, Notice, SharedObject) — Story 5.3 (#587), INV-4.
3//!
4//! Le droit de PARTICIPER (créer une offre, voter, emprunter) vient d'avoir
5//! une fiche de copropriétaire, pas du rôle actif : un syndic qui a aussi un
6//! lot participe ès qualités de copropriétaire (même raisonnement que
7//! l'ADR-0052 pour le comptable). Ce module ne couvre PAS cette moitié-là —
8//! elle se vérifie via `OwnerRepository` dans chaque use-case, comme avant.
9//!
10//! Le droit de MODÉRER (éditer/annuler/supprimer le contenu d'autrui, motif à
11//! l'appui) vient en revanche du rôle actif. C'est ce que ce module expose,
12//! en un seul endroit, pour que les quatre use-cases Community ne dupliquent
13//! pas le parsing `&str` → `UserRole`.
14
15use crate::domain::entities::UserRole;
16use std::str::FromStr;
17
18/// Le rôle actif (porté par le JWT, donc une `&str` côté handler) autorise-t-il
19/// la modération communautaire (SEL/Poll/Notice/SharedObject) ?
20///
21/// Un rôle illisible (jamais censé arriver depuis un JWT signé par ce
22/// backend, mais un appelant direct — test, BDD — peut passer n'importe
23/// quoi) est traité comme "ne modère pas", jamais comme une erreur : côté
24/// permissions, l'inconnu doit refuser, pas planter.
25pub fn peut_moderer(actor_role: &str) -> bool {
26 UserRole::from_str(actor_role)
27 .map(|role| role.can_moderate_community())
28 .unwrap_or(false)
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn happy_syndic_peut_moderer() {
37 assert!(peut_moderer("syndic"));
38 }
39
40 #[test]
41 fn happy_community_moderator_peut_moderer() {
42 assert!(peut_moderer("community.moderator"));
43 }
44
45 #[test]
46 fn edge_superadmin_peut_moderer() {
47 assert!(peut_moderer("superadmin"));
48 }
49
50 #[test]
51 fn security_owner_ne_peut_pas_moderer() {
52 assert!(!peut_moderer("owner"));
53 }
54
55 #[test]
56 fn negative_un_role_illisible_ne_declenche_pas_de_panique() {
57 assert!(!peut_moderer("<script>alert(1)</script>"));
58 assert!(!peut_moderer(""));
59 }
60}