1 | |
---|
2 | from trac.core import TracError |
---|
3 | from trac.perm import DefaultPermissionStore |
---|
4 | |
---|
5 | try: |
---|
6 | import threading |
---|
7 | except ImportError: |
---|
8 | import dummy_threading as threading |
---|
9 | |
---|
10 | class UsersWithPermCachingPermissionStore(DefaultPermissionStore): |
---|
11 | """ |
---|
12 | Extension to the Default implementation that caches the get_users_with_permissions() function |
---|
13 | """ |
---|
14 | |
---|
15 | _cached_users = {} |
---|
16 | _cache_lock = threading.Lock() |
---|
17 | |
---|
18 | def get_users_with_permissions(self, permissions): |
---|
19 | |
---|
20 | cache_key = "".join(sorted(permissions)) |
---|
21 | |
---|
22 | #We check once before locking and once after to prevent locking when we don't need to |
---|
23 | if (not self._cached_users.has_key(cache_key)): |
---|
24 | self._cache_lock.acquire() |
---|
25 | try: |
---|
26 | if (not self._cached_users.has_key(cache_key)): |
---|
27 | self.log.info("Generating Permissions Cache for '%s'" % (cache_key)) |
---|
28 | self._cached_users[cache_key] = DefaultPermissionStore.get_users_with_permissions(self, permissions) |
---|
29 | finally: |
---|
30 | self._cache_lock.release() |
---|
31 | |
---|
32 | return self._cached_users[cache_key] |
---|
33 | |
---|
34 | def grant_permission(self, username, action): |
---|
35 | self._cache_lock.acquire() |
---|
36 | try: |
---|
37 | self.log.info("Clearing Permissions Cache") |
---|
38 | self._cached_users.clear() |
---|
39 | DefaultPermissionStore.grant_permission(self, username, action) |
---|
40 | finally: |
---|
41 | self._cache_lock.release() |
---|
42 | |
---|
43 | def revoke_permission(self, username, action): |
---|
44 | self._cache_lock.acquire() |
---|
45 | try: |
---|
46 | self.log.info("Clearing Permissions Cache") |
---|
47 | self._cached_users.clear() |
---|
48 | DefaultPermissionStore.revoke_permission(self, username, action) |
---|
49 | finally: |
---|
50 | self._cache_lock.release() |
---|
51 | |
---|