Skip to content

policy

Class to define group and permission policies.

Policy

Source code in mlte/store/user/policy/policy.py
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
class Policy:
    # -----------------------------------------------------------------------------
    # Group naming.
    # -----------------------------------------------------------------------------

    CREATE_GROUP_PREFIX = "create"
    EDIT_GROUP_PREFIX = "edit"
    READ_GROUP_PREFIX = "read"

    SEPARATOR = "-"
    SEPARATOR_REPLACEMENT = "___"
    """Used when building group name."""

    @staticmethod
    def _build_group_name(
        prefix: str, resource_type: ResourceType, resource_id: Optional[str]
    ):
        """Builds group ids for the given prefix and resource id."""
        name = f"{prefix}{Policy.SEPARATOR}{resource_type}"
        if resource_id is not None:
            name = f"{name}{Policy.SEPARATOR}{resource_id.replace(Policy.SEPARATOR, Policy.SEPARATOR_REPLACEMENT)}"
        return name

    # -----------------------------------------------------------------------------
    # Policy handling.
    # -----------------------------------------------------------------------------

    def __init__(
        self,
        resource_type: ResourceType,
        resource_id: Optional[str] = None,
        read_group: bool = True,
        edit_group: bool = True,
        create_group: bool = True,
    ):
        """Initializes a policy from a list of groups."""

        self.resource_type = resource_type
        """The resource type for this policy."""

        self.resource_id = resource_id
        """The id of the specific resource this policy is for, if any."""

        self.read_group = read_group
        self.edit_group = edit_group
        self.create_group = create_group
        """Define which types of groups are enabled."""

        self.groups = self._build_groups()
        """A list of groups and their permissions, defining a policy."""

    def _build_groups(self) -> list[Group]:
        """Generates in memory representations of read and write groups for the given resource."""
        groups: list[Group] = []

        # Group with read permissions.
        if self.read_group:
            read_group = Group(
                name=Policy._build_group_name(
                    Policy.READ_GROUP_PREFIX,
                    self.resource_type,
                    self.resource_id,
                ),
                permissions=[
                    Permission(
                        resource_type=self.resource_type,
                        resource_id=self.resource_id,
                        method=MethodType.GET,
                    )
                ],
            )
            groups.append(read_group)

        # Group with create permissions.
        if self.create_group:
            # Create group is only created for non-resource-id related groups, create is always general, never associated to an id.
            if self.resource_id is None:
                create_group = Group(
                    name=Policy._build_group_name(
                        Policy.CREATE_GROUP_PREFIX, self.resource_type, None
                    ),
                    permissions=[
                        Permission(
                            resource_type=self.resource_type,
                            resource_id=self.resource_id,
                            method=MethodType.POST,
                        ),
                    ],
                )
                groups.append(create_group)

        # Group with edit/delete permissions.
        if self.edit_group:
            write_group = Group(
                name=Policy._build_group_name(
                    Policy.EDIT_GROUP_PREFIX,
                    self.resource_type,
                    self.resource_id,
                ),
                permissions=[
                    Permission(
                        resource_type=self.resource_type,
                        resource_id=self.resource_id,
                        method=MethodType.PUT,
                    ),
                    Permission(
                        resource_type=self.resource_type,
                        resource_id=self.resource_id,
                        method=MethodType.DELETE,
                    ),
                ],
            )

            # Creating/editing items inside the major resources will happen with a POST and an id of the major resource.
            if self.resource_id is not None:
                write_group.permissions.append(
                    Permission(
                        resource_type=self.resource_type,
                        resource_id=self.resource_id,
                        method=MethodType.POST,
                    ),
                )

            groups.append(write_group)

        return groups

    def assign_to_user(
        self, user: Union[UserWithPassword, BasicUser]
    ) -> Union[UserWithPassword, BasicUser]:
        """
        Add to this user object the groups from this policy he is not a member of.
        """
        # Groups are not assigned to admin role, which has access to everything.
        if user.role == RoleType.ADMIN:
            return user

        # Only add groups the user does not already belong to.
        for group in self.groups:
            user_already_in_group = False
            for existing_group in user.groups:
                if existing_group.name == group.name:
                    user_already_in_group = True
                    break

            if not user_already_in_group:
                user.groups.append(group)

        return user

    def __str__(self) -> str:
        return f"Resource {self.resource_type}, Id: {self.resource_id}, Read: {self.read_group}, Edit: {self.edit_group}, Create: {self.create_group}, Groups: {self.groups}"

SEPARATOR_REPLACEMENT = '___' class-attribute instance-attribute

Used when building group name.

create_group = create_group instance-attribute

Define which types of groups are enabled.

groups = self._build_groups() instance-attribute

A list of groups and their permissions, defining a policy.

resource_id = resource_id instance-attribute

The id of the specific resource this policy is for, if any.

resource_type = resource_type instance-attribute

The resource type for this policy.

__init__(resource_type, resource_id=None, read_group=True, edit_group=True, create_group=True)

Initializes a policy from a list of groups.

Source code in mlte/store/user/policy/policy.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
def __init__(
    self,
    resource_type: ResourceType,
    resource_id: Optional[str] = None,
    read_group: bool = True,
    edit_group: bool = True,
    create_group: bool = True,
):
    """Initializes a policy from a list of groups."""

    self.resource_type = resource_type
    """The resource type for this policy."""

    self.resource_id = resource_id
    """The id of the specific resource this policy is for, if any."""

    self.read_group = read_group
    self.edit_group = edit_group
    self.create_group = create_group
    """Define which types of groups are enabled."""

    self.groups = self._build_groups()
    """A list of groups and their permissions, defining a policy."""

assign_to_user(user)

Add to this user object the groups from this policy he is not a member of.

Source code in mlte/store/user/policy/policy.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def assign_to_user(
    self, user: Union[UserWithPassword, BasicUser]
) -> Union[UserWithPassword, BasicUser]:
    """
    Add to this user object the groups from this policy he is not a member of.
    """
    # Groups are not assigned to admin role, which has access to everything.
    if user.role == RoleType.ADMIN:
        return user

    # Only add groups the user does not already belong to.
    for group in self.groups:
        user_already_in_group = False
        for existing_group in user.groups:
            if existing_group.name == group.name:
                user_already_in_group = True
                break

        if not user_already_in_group:
            user.groups.append(group)

    return user