1use std::collections::BTreeSet;
4
5use soaprs_core::SoapResult;
6
7use crate::{AuthorizationName, PrincipalId};
8
9pub trait Principal: Send + Sync {
11 fn principal_id(&self) -> &PrincipalId;
13
14 fn has_role(&self, role: &AuthorizationName) -> bool;
16
17 fn has_permission(&self, permission: &AuthorizationName) -> bool;
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct StandardPrincipal {
24 id: PrincipalId,
25 roles: BTreeSet<AuthorizationName>,
26 permissions: BTreeSet<AuthorizationName>,
27}
28
29impl StandardPrincipal {
30 pub fn new(id: impl Into<String>) -> SoapResult<Self> {
32 Ok(Self {
33 id: PrincipalId::new(id)?,
34 roles: BTreeSet::new(),
35 permissions: BTreeSet::new(),
36 })
37 }
38
39 pub fn role(mut self, role: impl Into<String>) -> SoapResult<Self> {
41 self.roles.insert(AuthorizationName::new(role)?);
42 Ok(self)
43 }
44
45 pub fn permission(mut self, permission: impl Into<String>) -> SoapResult<Self> {
47 self.permissions.insert(AuthorizationName::new(permission)?);
48 Ok(self)
49 }
50
51 pub fn roles(&self) -> &BTreeSet<AuthorizationName> {
53 &self.roles
54 }
55
56 pub fn permissions(&self) -> &BTreeSet<AuthorizationName> {
58 &self.permissions
59 }
60}
61
62impl Principal for StandardPrincipal {
63 fn principal_id(&self) -> &PrincipalId {
64 &self.id
65 }
66
67 fn has_role(&self, role: &AuthorizationName) -> bool {
68 self.roles.contains(role)
69 }
70
71 fn has_permission(&self, permission: &AuthorizationName) -> bool {
72 self.permissions.contains(permission)
73 }
74}