Skip to content

Commit d454d05

Browse files
feat: enhance role permission checks for organization member invites
Signed-off-by: rohan <[email protected]>
1 parent 0ee752e commit d454d05

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

backend/api/utils/access/permissions.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ def member_can_access_org(member_id, org_id):
6666
).exists()
6767

6868

69+
def role_has_permission(role, action, resource, is_app_resource=False):
70+
"""Check if a role has the specified permission for a resource."""
71+
if not role:
72+
return False # No role assigned, hence no permissions
73+
74+
# Check if the role is a default role
75+
if role.is_default:
76+
# Get permissions from the default_roles dictionary
77+
role_name = role.name.capitalize()
78+
permissions = default_roles.get(role_name, {})
79+
else:
80+
# Use the permissions stored in the role object
81+
permissions = role.permissions
82+
83+
# Determine the correct key to check
84+
permission_key = "app_permissions" if is_app_resource else "permissions"
85+
86+
# Check if the resource exists and if the action is permitted
87+
resource_permissions = permissions.get(permission_key, {}).get(resource, [])
88+
return action in resource_permissions
89+
90+
6991
def user_has_permission(
7092
account,
7193
action,
@@ -85,25 +107,8 @@ def user_has_permission(
85107
org_member = OrganisationMember.objects.get(
86108
user=account, organisation=organisation, deleted_at=None
87109
)
88-
role = org_member.role
89-
if not role:
90-
return False # No role assigned, hence no permissions
91-
92-
# Check if the role is a default role
93-
if role.is_default:
94-
# Get permissions from the default_roles dictionary
95-
role_name = role.name.capitalize()
96-
permissions = default_roles.get(role_name, {})
97-
else:
98-
# Use the permissions stored in the role object
99-
permissions = role.permissions
100-
101-
# Determine the correct key to check
102-
permission_key = "app_permissions" if is_app_resource else "permissions"
103110

104-
# Check if the resource exists and if the action is permitted
105-
resource_permissions = permissions.get(permission_key, {}).get(resource, [])
106-
return action in resource_permissions
111+
return role_has_permission(org_member.role, action, resource, is_app_resource)
107112

108113
except OrganisationMember.DoesNotExist:
109114
return False # User is not a member of the organization

backend/backend/graphene/mutations/organisation.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from api.emails import send_user_joined_email, send_welcome_email
22
from api.utils.access.permissions import (
33
role_has_global_access,
4+
role_has_permission,
45
user_has_permission,
5-
user_is_admin,
66
user_is_org_member,
77
)
88
from api.utils.access.roles import default_roles
@@ -162,11 +162,20 @@ def mutate(cls, root, info, org_id, invites):
162162
app_scope = App.objects.filter(id__in=apps)
163163

164164
# Restrict roles that can be assigned via invites
165-
allowed_invite_roles = ["developer", "service"]
165+
org_roles = Role.objects.filter(organisation=org)
166+
167+
allowed_invite_roles = [
168+
r
169+
for r in org_roles
170+
if not role_has_global_access(r)
171+
and not role_has_permission(r, "create", "ServiceAccountTokens")
172+
]
173+
166174
role = Role.objects.get(organisation=org, id=role_id)
167-
if role.name.lower() not in allowed_invite_roles:
175+
if role not in allowed_invite_roles:
176+
allowed_role_names = [r.name for r in allowed_invite_roles]
168177
raise GraphQLError(
169-
f"You can only invite members with the following roles: {', '.join(allowed_invite_roles)}"
178+
f"You can only invite members with the following roles: {', '.join(allowed_role_names)}"
170179
)
171180

172181
new_invite = OrganisationMemberInvite.objects.create(

0 commit comments

Comments
 (0)