Mercurial > public > sg101
comparison gpp/forums/permissions.py @ 459:9d3bd7304050
Fixing #221. Also combined all permissions checks into a new module, permissions.py. This allows us to cache user, category, and forum groups information since it rarely changes.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 02 Jul 2011 23:35:45 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
458:9a4bffdf37c3 | 459:9d3bd7304050 |
---|---|
1 """ | |
2 This module does permissions checking for the forums application. | |
3 | |
4 """ | |
5 from django.core.cache import cache | |
6 | |
7 # How long (in secs) to cache group information for various entities: | |
8 CATEGORY_TIMEOUT = 4 * 60 * 60 | |
9 FORUM_TIMEOUT = 4 * 60 * 60 | |
10 USER_TIMEOUT = 15 * 60 | |
11 | |
12 | |
13 def can_access(category, user): | |
14 """ | |
15 This function returns True if the given user can access the forum category | |
16 and False otherwise. | |
17 | |
18 """ | |
19 if user.is_superuser: | |
20 return True | |
21 | |
22 # If this category has no groups assigned to it, return True. Else, return | |
23 # True if the user belongs to a group that has been assigned to this | |
24 # category, and False otherwise. | |
25 | |
26 # Get the groups assigned to this category. | |
27 cat_groups = get_category_groups(category) | |
28 | |
29 if len(cat_groups) == 0: | |
30 return True # No groups => public category | |
31 | |
32 user_groups = get_user_groups(user) | |
33 return bool(user_groups & cat_groups) | |
34 | |
35 | |
36 def can_moderate(forum, user): | |
37 """ | |
38 Returns True if the user can moderate the forum. | |
39 | |
40 """ | |
41 # Get the simple cases out of the way first: | |
42 if not user.is_authenticated(): | |
43 return False | |
44 elif user.is_superuser: | |
45 return True | |
46 | |
47 # If we get here, we have to see if there is an intersection between the | |
48 # user's groups and the forum's moderator groups. | |
49 | |
50 forum_groups = get_forum_groups(forum) | |
51 user_groups = get_user_groups(user) | |
52 | |
53 return bool(user_groups & forum_groups) | |
54 | |
55 | |
56 def can_post(topic, user): | |
57 """ | |
58 Returns True if the user can post in the topic and False otherwise. | |
59 | |
60 """ | |
61 if not user.is_authenticated(): | |
62 return False | |
63 if user.is_superuser or can_moderate(topic.forum, user): | |
64 return True | |
65 | |
66 return not topic.locked and can_access(topic.forum.category, user) | |
67 | |
68 | |
69 def get_user_groups(user): | |
70 """ | |
71 Returns a set of group ID's that the user belongs to. | |
72 | |
73 """ | |
74 user_groups_key = '%s_groups' % user.username | |
75 return _get_groups(user_groups_key, user.groups.all(), USER_TIMEOUT) | |
76 | |
77 | |
78 def get_forum_groups(forum): | |
79 """ | |
80 Returns a set of group ID's of the forum's moderator groups. | |
81 | |
82 """ | |
83 forum_groups_key = 'forum_%d_mods' % forum.id | |
84 return _get_groups(forum_groups_key, forum.moderators.all(), FORUM_TIMEOUT) | |
85 | |
86 | |
87 def get_category_groups(category): | |
88 """ | |
89 Returns a set of group ID's of the groups that can access this forum | |
90 category. | |
91 | |
92 """ | |
93 cat_groups_key = 'cat_%d_groups' % category.id | |
94 return _get_groups(cat_groups_key, category.groups.all(), CATEGORY_TIMEOUT) | |
95 | |
96 | |
97 def _get_groups(key, qs, timeout): | |
98 """ | |
99 This internal function contains the code common to the get_xxx_groups() | |
100 functions. Returns a set of group ID's from the cache. If the set is not | |
101 found in the cache, the set is generated from the queryset qs and cached | |
102 with the given timeout. | |
103 | |
104 key - the cache key for the set of group ID's | |
105 qs - the query set of groups to query if the set is not in the cache | |
106 timeout - the cache timeout to use | |
107 | |
108 """ | |
109 groups = cache.get(key) | |
110 if groups is None: | |
111 groups = set([g.id for g in qs]) | |
112 cache.set(key, groups, timeout) | |
113 | |
114 return groups |