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