♻️(backend) simplify further select options on link reach/role
We reduce the number of options even more by treating link reach and link role independently: link reach must be higher than its ancestors' equivalent link reach and link role must be higher than its ancestors' link role. This reduces the number of possibilities but we decided to start with the most restrictive and simple offer and extend it if we realize it faces too many criticism instead of risking to offer too many options that are too complex and must be reduced afterwards.
This commit is contained in:
committed by
Anthony LC
parent
d0eb2275e5
commit
d232654c55
@@ -65,49 +65,22 @@ class LinkReachChoices(PriorityTextChoices):
|
||||
def get_select_options(cls, link_reach, link_role):
|
||||
"""
|
||||
Determines the valid select options for link reach and link role depending on the
|
||||
list of ancestors' link reach/role definitions.
|
||||
ancestors' link reach/role given as arguments.
|
||||
Returns:
|
||||
Dictionary mapping possible reach levels to their corresponding possible roles.
|
||||
"""
|
||||
# If no ancestors, return all options
|
||||
if not link_reach:
|
||||
return {
|
||||
reach: LinkRoleChoices.values if reach != cls.RESTRICTED else None
|
||||
for reach in cls.values
|
||||
}
|
||||
|
||||
# Initialize the result for all reaches with possible roles
|
||||
result = {
|
||||
reach: set(LinkRoleChoices.values) if reach != cls.RESTRICTED else None
|
||||
for reach in cls.values
|
||||
}
|
||||
|
||||
# Handle special rules directly with early returns for efficiency
|
||||
|
||||
if link_role == LinkRoleChoices.EDITOR:
|
||||
# Rule 1: public/editor → override everything
|
||||
if link_reach == cls.PUBLIC:
|
||||
return {cls.PUBLIC: [LinkRoleChoices.EDITOR]}
|
||||
|
||||
# Rule 2: authenticated/editor
|
||||
if link_reach == cls.AUTHENTICATED:
|
||||
result[cls.AUTHENTICATED].discard(LinkRoleChoices.READER)
|
||||
result.pop(cls.RESTRICTED, None)
|
||||
|
||||
if link_role == LinkRoleChoices.READER:
|
||||
# Rule 3: public/reader
|
||||
if link_reach == cls.PUBLIC:
|
||||
result.pop(cls.AUTHENTICATED, None)
|
||||
result.pop(cls.RESTRICTED, None)
|
||||
|
||||
# Rule 4: authenticated/reader
|
||||
if link_reach == cls.AUTHENTICATED:
|
||||
result.pop(cls.RESTRICTED, None)
|
||||
|
||||
# Convert sets to ordered lists where applicable
|
||||
return {
|
||||
reach: sorted(roles, key=LinkRoleChoices.get_priority) if roles else roles
|
||||
for reach, roles in result.items()
|
||||
reach: [
|
||||
role
|
||||
for role in LinkRoleChoices.values
|
||||
if LinkRoleChoices.get_priority(role)
|
||||
>= LinkRoleChoices.get_priority(link_role)
|
||||
]
|
||||
if reach != cls.RESTRICTED
|
||||
else None
|
||||
for reach in cls.values
|
||||
if LinkReachChoices.get_priority(reach)
|
||||
>= LinkReachChoices.get_priority(link_reach)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1186,7 +1186,6 @@ def test_models_documents_restore_complex_bis(django_assert_num_queries):
|
||||
@pytest.mark.parametrize(
|
||||
"reach, role, select_options",
|
||||
[
|
||||
# One ancestor
|
||||
(
|
||||
"public",
|
||||
"reader",
|
||||
@@ -1206,7 +1205,7 @@ def test_models_documents_restore_complex_bis(django_assert_num_queries):
|
||||
(
|
||||
"authenticated",
|
||||
"editor",
|
||||
{"authenticated": ["editor"], "public": ["reader", "editor"]},
|
||||
{"authenticated": ["editor"], "public": ["editor"]},
|
||||
),
|
||||
(
|
||||
"restricted",
|
||||
@@ -1222,18 +1221,16 @@ def test_models_documents_restore_complex_bis(django_assert_num_queries):
|
||||
"editor",
|
||||
{
|
||||
"restricted": None,
|
||||
"authenticated": ["reader", "editor"],
|
||||
"public": ["reader", "editor"],
|
||||
"authenticated": ["editor"],
|
||||
"public": ["editor"],
|
||||
},
|
||||
),
|
||||
# No ancestors (edge case)
|
||||
# Edge cases
|
||||
(
|
||||
"public",
|
||||
None,
|
||||
{
|
||||
"public": ["reader", "editor"],
|
||||
"authenticated": ["reader", "editor"],
|
||||
"restricted": None,
|
||||
},
|
||||
),
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user