fix: rp_caches race condition causing intermittent 403
load_roleperms() was setting self.rp_caches = {} before the async
DB query. During the await, other coroutines saw {} (not None),
skipped the load, and checked permissions against an empty dict,
causing intermittent 403 on random paths.
Fix: build in local dict first, assign atomically when complete.
This commit is contained in:
parent
c776c0b3b5
commit
fbbe011a8d
@ -237,7 +237,9 @@ class UserPermissions:
|
||||
if _cache_enabled('rbac') and self.rp_caches is not None and (now - self.rp_cache_loaded_at) < self.rp_cache_ttl:
|
||||
return
|
||||
|
||||
self.rp_caches = {}
|
||||
# Build in local dict first, assign atomically when complete.
|
||||
# Otherwise other coroutines see {} during the await and get 403.
|
||||
new_caches = {}
|
||||
sql_all = """select c.id, c.orgtypeid, c.name, b.path
|
||||
from rolepermission a, permission b, role c
|
||||
where a.permid = b.id
|
||||
@ -253,9 +255,11 @@ order by c.orgtypeid, c.name"""
|
||||
k = 'logined'
|
||||
else:
|
||||
k = f'{r.orgtypeid}.{r.name}'
|
||||
arr = self.rp_caches.get(k, [])
|
||||
arr = new_caches.get(k, [])
|
||||
arr.append(r.path)
|
||||
self.rp_caches[k] = arr
|
||||
new_caches[k] = arr
|
||||
# Atomic swap: other coroutines see old cache or fully-loaded new cache, never {}
|
||||
self.rp_caches = new_caches
|
||||
self.rp_cache_loaded_at = now
|
||||
|
||||
async def get_userroles(self, sor, userid):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user