Skip to main content

potree_auth/authorization/domain/
resource.rs

1use std::fmt::Debug;
2
3use crate::common::domain::Group;
4use crate::common::domain::utils::new_type::new_type;
5use crate::user::domain::EmailAddress;
6
7/// Defines a resource type that can be authorized against.
8pub trait Resource: Debug {
9    fn resource_type(&self) -> ResourceType;
10}
11
12/// Defines the functionality required for fine grained access to a particular
13/// resource (instance-level authZ).
14pub trait ResourceInstance: Resource {
15    /// Identifies the specific resource instance.
16    fn resource_identifier(&self) -> ResourceIdentifier;
17
18    /// The groups that the resource belongs to. Some resource types won't be
19    /// associated with groups, in this case this should return None. Currently,
20    /// if a user is part of the same group they are allowed do action the
21    /// resource.
22    fn groups(&self) -> Option<Vec<Group>>;
23
24    ///The email addresses of the users that have access to the resource. Some
25    /// resource types won't be associated with users, in this case this
26    /// should return None.
27    fn user_emails(&self) -> Option<Vec<EmailAddress>>;
28}
29
30new_type![
31    /// The identifier of a resource type (type-level). E.g. a "user", a "group",
32    /// a "file", etc.
33    ResourceType(String)
34];
35
36new_type![
37    /// The identifier of a specific resource instance (instance-level). E.g. a
38    /// user id, a group id, a file id, etc.
39    ResourceIdentifier(String)
40];
41
42/// A super basic struct implementing the [`Resource`] and [`ResourceInstance`]
43/// traits for testing purposes.
44///
45/// I was struggling to get mockall to deal with the supertrait mocking.
46#[cfg(any(test, feature = "mock"))]
47pub mod mocked_resource {
48    use super::EmailAddress;
49    use super::Group;
50    use super::Resource;
51    use super::ResourceIdentifier;
52    use super::ResourceInstance;
53    use super::ResourceType;
54
55    #[derive(Debug, fake::Dummy)]
56    pub struct MockedResource {
57        pub resource_type: ResourceType,
58        pub resource_identifier: ResourceIdentifier,
59        pub groups: Option<Vec<Group>>,
60        pub user_emails: Option<Vec<EmailAddress>>,
61    }
62
63    impl Resource for MockedResource {
64        fn resource_type(&self) -> ResourceType {
65            self.resource_type.clone()
66        }
67    }
68
69    impl ResourceInstance for MockedResource {
70        fn resource_identifier(&self) -> ResourceIdentifier {
71            self.resource_identifier.clone()
72        }
73
74        fn groups(&self) -> Option<Vec<Group>> {
75            self.groups.clone()
76        }
77
78        fn user_emails(&self) -> Option<Vec<EmailAddress>> {
79            self.user_emails.clone()
80        }
81    }
82}