Skip to content

Commit f2d0936

Browse files
committed
feat: add enums for role assignment and removal handling
1 parent d8f68b5 commit f2d0936

2 files changed

Lines changed: 42 additions & 14 deletions

File tree

openedx_authz/rest_api/enums.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,20 @@ class SearchField(BaseEnum):
3333
USERNAME = "username"
3434
FULL_NAME = "full_name"
3535
EMAIL = "email"
36+
37+
38+
class RoleOperationStatus(BaseEnum):
39+
"""Enum for the status of role assignment and removal operations."""
40+
41+
ROLE_ADDED = "role_added"
42+
ROLE_REMOVED = "role_removed"
43+
44+
45+
class RoleOperationError(BaseEnum):
46+
"""Enum for errors that can occur during role assignment and removal operations."""
47+
48+
USER_NOT_FOUND = "user_not_found"
49+
USER_ALREADY_HAS_ROLE = "user_already_has_role"
50+
USER_DOES_NOT_HAVE_ROLE = "user_does_not_have_role"
51+
ROLE_ASSIGNMENT_ERROR = "role_assignment_error"
52+
ROLE_REMOVAL_ERROR = "role_removal_error"

openedx_authz/rest_api/v1/views.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from rest_framework.views import APIView
1616

1717
from openedx_authz import api
18+
from openedx_authz.rest_api.enums import RoleOperationError, RoleOperationStatus
1819
from openedx_authz.rest_api.utils import (
1920
filter_users,
2021
get_user_by_username_or_email,
@@ -159,8 +160,8 @@ class RoleUserAPIView(APIView):
159160
**Response Format (PUT/DELETE)**
160161
Returns HTTP 207 Multi-Status with:
161162
{
162-
"completed": [{"user_identifier": "...", "status": "role_added|role_removed"}],
163-
"errors": [{"user_identifier": "...", "error": "error_type"}]
163+
"completed": [{"user_identifier": "john_doe", "status": "role_added|role_removed"}],
164+
"errors": [{"user_identifier": "jane_doe", "error": "error_type"}]
164165
}
165166
166167
**Authentication and Permissions**
@@ -230,18 +231,23 @@ def put(self, request: HttpRequest) -> Response:
230231

231232
completed, errors = [], []
232233
for user_identifier in serializer.validated_data["users"]:
234+
response_dict = {"user_identifier": user_identifier}
233235
try:
234236
user = get_user_by_username_or_email(user_identifier)
235237
result = api.assign_role_to_user_in_scope(user.username, role_name, scope)
236-
if not result:
237-
errors.append({"user_identifier": user_identifier, "error": "user_already_has_role"})
238-
continue
239-
completed.append({"user_identifier": user_identifier, "status": "role_added"})
238+
if result:
239+
response_dict["status"] = RoleOperationStatus.ROLE_ADDED
240+
completed.append(response_dict)
241+
else:
242+
response_dict["error"] = RoleOperationError.USER_ALREADY_HAS_ROLE
243+
errors.append(response_dict)
240244
except User.DoesNotExist:
241-
errors.append({"user_identifier": user_identifier, "error": "user_not_found"})
245+
response_dict["error"] = RoleOperationError.USER_NOT_FOUND
246+
errors.append(response_dict)
242247
except Exception as e: # pylint: disable=broad-exception-caught
243248
logger.error(f"Error assigning role to user {user_identifier}: {e}")
244-
errors.append({"user_identifier": user_identifier, "error": "role_assignment_failed"})
249+
response_dict["error"] = RoleOperationError.ROLE_ASSIGNMENT_ERROR
250+
errors.append(response_dict)
245251

246252
response_data = {"completed": completed, "errors": errors}
247253
return Response(response_data, status=status.HTTP_207_MULTI_STATUS)
@@ -271,18 +277,23 @@ def delete(self, request: HttpRequest) -> Response:
271277

272278
completed, errors = [], []
273279
for user_identifier in user_identifiers:
280+
response_dict = {"user_identifier": user_identifier}
274281
try:
275282
user = get_user_by_username_or_email(user_identifier)
276283
result = api.unassign_role_from_user(user.username, role_name, scope)
277-
if not result:
278-
errors.append({"user_identifier": user_identifier, "error": "user_does_not_have_role"})
279-
continue
280-
completed.append({"user_identifier": user_identifier, "status": "role_removed"})
284+
if result:
285+
response_dict["status"] = RoleOperationStatus.ROLE_REMOVED
286+
completed.append(response_dict)
287+
else:
288+
response_dict["error"] = RoleOperationError.USER_DOES_NOT_HAVE_ROLE
289+
errors.append(response_dict)
281290
except User.DoesNotExist:
282-
errors.append({"user_identifier": user_identifier, "error": "user_not_found"})
291+
response_dict["error"] = RoleOperationError.USER_NOT_FOUND
292+
errors.append(response_dict)
283293
except Exception as e: # pylint: disable=broad-exception-caught
284294
logger.error(f"Error removing role from user {user_identifier}: {e}")
285-
errors.append({"user_identifier": user_identifier, "error": "removal_failed"})
295+
response_dict["error"] = RoleOperationError.ROLE_REMOVAL_ERROR
296+
errors.append(response_dict)
286297

287298
response_data = {"completed": completed, "errors": errors}
288299
return Response(response_data, status=status.HTTP_207_MULTI_STATUS)

0 commit comments

Comments
 (0)