Skip to content

Commit 9e8ef45

Browse files
authored
[NOBUG] fix user group on update user (#686)
1 parent bfc5599 commit 9e8ef45

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-8
lines changed

compliance-api/src/compliance_api/services/authorize_service/auth_service.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ def update_user_group(auth_user_guid: str, payload: dict):
9191
f"Update group in the auth server failed for user : {auth_user_guid}"
9292
)
9393

94+
# Invalidate auth caches for this specific user
95+
AuthService._invalidate_auth_user_cache(auth_user_guid)
96+
97+
# Invalidate the "all users by app" cache since this user's groups changed
98+
AuthService._invalidate_auth_users_by_app_cache()
99+
94100
# Invalidate ALL staff caches since permissions changed
95101
CachedStaffUserService.invalidate_staff_cache(auth_user_guid)
96102

@@ -110,11 +116,51 @@ def delete_user_group(auth_user_guid: str, group: str, del_sub_group_mappings=Tr
110116
if delete_response.status_code != 204:
111117
raise BusinessError("Delete group mapping failed")
112118

119+
# Invalidate auth caches for this specific user
120+
AuthService._invalidate_auth_user_cache(auth_user_guid)
121+
122+
# Invalidate the "all users by app" cache since this user's groups changed
123+
AuthService._invalidate_auth_users_by_app_cache()
124+
113125
# Invalidate ALL staff caches since permissions changed
114126
CachedStaffUserService.invalidate_staff_cache(auth_user_guid)
115127

116128
return delete_response
117129

130+
@staticmethod
131+
def _invalidate_auth_user_cache(auth_user_guid: str):
132+
"""
133+
Invalidate the individual auth user cache.
134+
135+
Since cache keys include token hashes, we can't delete all variations.
136+
Instead, we use a pattern-based approach or accept that cache will expire naturally.
137+
"""
138+
from compliance_api.services.cached_staff_user import CachedStaffUserService
139+
140+
# Get current token hash
141+
token_hash = CachedStaffUserService._get_token_hash()
142+
cache_key = f"auth_user:{auth_user_guid}:{token_hash}"
143+
144+
cache.delete(cache_key)
145+
current_app.logger.info(f"Invalidated auth user cache for {auth_user_guid}")
146+
147+
@staticmethod
148+
def _invalidate_auth_users_by_app_cache():
149+
"""
150+
Invalidate the "all users by app" cache.
151+
152+
Since cache keys include token hashes, we can't delete all variations.
153+
Instead, we delete for the current token.
154+
"""
155+
from compliance_api.services.cached_staff_user import CachedStaffUserService
156+
157+
# Get current token hash
158+
token_hash = CachedStaffUserService._get_token_hash()
159+
cache_key = f"auth_users_app:{AUTH_APP}:{token_hash}"
160+
161+
cache.delete(cache_key)
162+
current_app.logger.info("Invalidated auth users by app cache")
163+
118164

119165
def _request_auth_service(
120166
relative_url, http_method: HttpMethod = HttpMethod.GET, data=None

compliance-api/src/compliance_api/services/cached_staff_user.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class CachedStaffUserService:
1616
STAFF_CACHE_KEY_PREFIX = "staff_user:"
1717
ALL_STAFF_CACHE_KEY = "all_staff_users"
1818
ALL_STAFF_WITH_AUTH_PREFIX = "all_staff_with_auth:"
19+
CACHE_VERSION_KEY = "all_staff_with_auth_version"
1920

2021
@classmethod
2122
def exists_staff_by_auth_guid(cls, auth_guid: str) -> bool:
@@ -62,13 +63,13 @@ def get_all_staff_users_with_auth():
6263
# pylint: disable=import-outside-toplevel
6364
from compliance_api.services.staff_user import _set_permission_level_in_compliance_user_obj
6465

65-
# Create cache key that includes token hash for security
66-
token_hash = CachedStaffUserService._get_token_hash()
67-
68-
version = cache.get("all_staff_with_auth_version")
66+
# Get current version
67+
version = cache.get(CachedStaffUserService.CACHE_VERSION_KEY)
6968
if version is None:
7069
version = 0
7170

71+
# Create cache key that includes token hash AND version
72+
token_hash = CachedStaffUserService._get_token_hash()
7273
cache_key = (
7374
f"{CachedStaffUserService.ALL_STAFF_WITH_AUTH_PREFIX}"
7475
f"{token_hash}:v{version}"
@@ -120,13 +121,22 @@ def invalidate_staff_cache(auth_guid: str = None):
120121

121122
@staticmethod
122123
def _invalidate_all_staff_with_auth_cache():
124+
"""
125+
Invalidate all staff+auth cache by bumping version number.
126+
127+
This invalidates cache for all tokens/users since the version
128+
is part of every cache key.
129+
"""
123130
try:
124-
current_version = cache.get("all_staff_with_auth_version")
131+
current_version = cache.get(CachedStaffUserService.CACHE_VERSION_KEY)
125132
if current_version is None:
126133
current_version = 0
127134

128-
cache.set("all_staff_with_auth_version", current_version + 1)
129-
current_app.logger.info("Bumped staff+auth cache version")
135+
new_version = current_version + 1
136+
cache.set(CachedStaffUserService.CACHE_VERSION_KEY, new_version)
137+
current_app.logger.info(
138+
f"Bumped staff+auth cache version from {current_version} to {new_version}"
139+
)
130140
except (AttributeError, RuntimeError) as e:
131141
current_app.logger.error(f"Error invalidating staff+auth cache: {e}")
132142

compliance-api/src/compliance_api/services/staff_user.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def create_user(user_data):
8888
# Update user group in auth service
8989
AuthService.update_user_group(
9090
auth_user_guid,
91-
{"group": permission, "app_name": AUTH_APP}
91+
{"group_name": permission, "app_name": AUTH_APP}
9292
)
9393
except (AttributeError, RuntimeError) as e:
9494
# Log the error but don't fail the user creation
@@ -127,6 +127,19 @@ def update_user(user_id, user_data):
127127
updated_user = StaffUserModel.update_staff(user_id, user_data)
128128

129129
if updated_user:
130+
# Handle permission (group) assignment
131+
permission = user_data.get("permission")
132+
if permission:
133+
auth_guid_to_update = new_auth_guid if new_auth_guid else existing_user.auth_user_guid
134+
try:
135+
# Update user group
136+
AuthService.update_user_group(
137+
auth_guid_to_update,
138+
{"group_name": permission, "app_name": AUTH_APP}
139+
)
140+
except (AttributeError, RuntimeError) as e:
141+
logging.error("Failed to update user group in auth service: %s", e)
142+
130143
# Invalidate caches for both old and new auth_guid (if changed)
131144
CachedStaffUserService.invalidate_staff_cache(existing_user.auth_user_guid)
132145

0 commit comments

Comments
 (0)