|
1 #!/usr/bin/python2.5 |
|
2 # |
|
3 # Copyright 2009 the Melange authors. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); |
|
6 # you may not use this file except in compliance with the License. |
|
7 # You may obtain a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, |
|
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 # See the License for the specific language governing permissions and |
|
15 # limitations under the License. |
|
16 |
|
17 """Access control helper. |
|
18 |
|
19 See soc.views.helper.access module. |
|
20 """ |
|
21 |
|
22 __authors__ = [ |
|
23 '"Madhusudan.C.S" <madhusudancs@gmail.com>' |
|
24 ] |
|
25 |
|
26 |
|
27 from django.utils.translation import ugettext |
|
28 |
|
29 from soc.logic.helper import timeline as timeline_helper |
|
30 from soc.logic.models import host as host_logic |
|
31 from soc.logic.models import user as user_logic |
|
32 from soc.views import out_of_band |
|
33 from soc.views.helper import access |
|
34 |
|
35 from soc.modules.ghop.logic.models import mentor as ghop_mentor_logic |
|
36 from soc.modules.ghop.logic.models import org_admin as ghop_org_admin_logic |
|
37 from soc.modules.ghop.logic.models import task as ghop_task_logic |
|
38 |
|
39 |
|
40 DEF_CANT_EDIT_MSG = ugettext( |
|
41 'This task cannot be edited since it has been claimed at least ' |
|
42 'once before.') |
|
43 |
|
44 DEF_MAX_TASKS_REACHED_MSG = ugettext( |
|
45 'You have reached the maximum number of Tasks allowed ' |
|
46 'for your organization for this program.') |
|
47 |
|
48 DEF_NEED_ROLE_MSG = ugettext( |
|
49 'You do not have the required role.') |
|
50 |
|
51 DEF_NO_ACTIVE_ENTITY_MSG = ugettext( |
|
52 'There is no such active entity.') |
|
53 |
|
54 DEF_NO_PUB_TASK_MSG = ugettext( |
|
55 'There is no such published task.') |
|
56 |
|
57 DEF_PAGE_INACTIVE_MSG = ugettext( |
|
58 'This page is inactive at this time.') |
|
59 |
|
60 DEF_SIGN_UP_AS_OA_MENTOR_MSG = ugettext( |
|
61 'You first need to sign up as an Org Admin or a Mentor.') |
|
62 |
|
63 |
|
64 class GHOPChecker(access.Checker): |
|
65 """See soc.views.helper.access.Checker. |
|
66 """ |
|
67 |
|
68 @access.allowDeveloper |
|
69 @access.denySidebar |
|
70 def checkCanOrgAdminOrMentorEdit(self, django_args, |
|
71 key_location, check_limit): |
|
72 """Checks if the mentors can create task for this program, |
|
73 and obeys the task quota limit assigned for their org when check_limit is |
|
74 True. |
|
75 |
|
76 Args: |
|
77 django_args: a dictionary with django's arguments |
|
78 key_location: the key for django_args in which the key_name |
|
79 from the mentor is stored |
|
80 check_limit: iff true checks if the organization reached the |
|
81 task quota limit for the given program. |
|
82 """ |
|
83 |
|
84 self.checkIsUser(django_args) |
|
85 |
|
86 user_account = user_logic.logic.getForCurrentAccount() |
|
87 |
|
88 filter = { |
|
89 'user': user_account, |
|
90 'scope_path': django_args[key_location], |
|
91 'status': 'active' |
|
92 } |
|
93 |
|
94 role_entity = ghop_org_admin_logic.logic.getForFields( |
|
95 filter, unique=True) |
|
96 if not role_entity: |
|
97 role_entity = ghop_mentor_logic.logic.getForFields( |
|
98 filter, unique=True) |
|
99 |
|
100 if not role_entity: |
|
101 raise out_of_band.AccessViolation( |
|
102 message_fmt=DEF_SIGN_UP_AS_OA_MENTOR_MSG) |
|
103 |
|
104 program_entity = role_entity.program |
|
105 |
|
106 if not timeline_helper.isActivePeriod(program_entity.timeline, |
|
107 'program'): |
|
108 raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG) |
|
109 |
|
110 org_entity = role_entity.scope |
|
111 |
|
112 if check_limit: |
|
113 # count all tasks from this organization |
|
114 fields = {'scope': org_entity} |
|
115 task_query = ghop_task_logic.logic.getQueryForFields(fields) |
|
116 |
|
117 if task_query.count() >= org_entity.task_quota_limit: |
|
118 # too many tasks access denied |
|
119 raise out_of_band.AccessViolation(message_fmt=DEF_MAX_TASKS_REACHED) |
|
120 |
|
121 if 'link_id' in django_args: |
|
122 task_filter = { |
|
123 'link_id': django_args['link_id'], |
|
124 'scope_path': django_args['scope_path'], |
|
125 } |
|
126 task_entity = ghop_task_logic.logic.getFromKeyFields(task_filter) |
|
127 |
|
128 if task_entity.status not in ['Unapproved', 'Unpublished', 'Open']: |
|
129 # task is claimed at least once |
|
130 raise out_of_band.AccessViolation(message_fmt=DEF_CANT_EDIT_MSG) |
|
131 |
|
132 return |
|
133 |
|
134 @access.allowDeveloper |
|
135 @access.denySidebar |
|
136 def checkRoleAndStatusForTask(self, django_args, allowed_roles, |
|
137 role_status, task_status): |
|
138 """Checks if the current user has access to the given task. |
|
139 |
|
140 Args: |
|
141 django_args: a dictionary with django's arguments |
|
142 allowed_roles: list with names for the roles allowed to pass access check |
|
143 role_status: list with states allowed for the role |
|
144 task_status: a list with states allowed for the task |
|
145 |
|
146 Raises: |
|
147 AccessViolationResponse: |
|
148 - If there is no task found |
|
149 - If the task is not in one of the required states. |
|
150 - If the user does not have any of the required roles |
|
151 """ |
|
152 |
|
153 self.checkIsUser(django_args) |
|
154 |
|
155 if 'link_id' in django_args: |
|
156 # bail out with 404 if no task is found |
|
157 task_entity = ghop_task_logic.logic.getFromKeyFieldsOr404(django_args) |
|
158 |
|
159 if not task_entity.status in task_status: |
|
160 # this task can not be accessed at the moment |
|
161 raise out_of_band.AccessViolation( |
|
162 message_fmt=DEF_NO_ACTIVE_ENTITY_MSG) |
|
163 |
|
164 user_entity = self.user |
|
165 |
|
166 filter = { |
|
167 'user': user_entity, |
|
168 'status': role_status} |
|
169 |
|
170 if 'host' in allowed_roles: |
|
171 # check if the current user is a host for this proposal's program |
|
172 filter['scope'] = task_entity.program |
|
173 |
|
174 if host_logic.logic.getForFields(filter, unique=True): |
|
175 return |
|
176 |
|
177 if 'ghop/org_admin' in allowed_roles: |
|
178 # check if the current user is an admin for this task's org |
|
179 filter['scope_path'] = django_args['scope_path'] |
|
180 |
|
181 if ghop_org_admin_logic.logic.getForFields(filter, unique=True): |
|
182 return |
|
183 |
|
184 if 'ghop/mentor' in allowed_roles: |
|
185 # check if the current user is a mentor for this task's org |
|
186 filter['scope_path'] = django_args['scope_path'] |
|
187 |
|
188 if ghop_mentor_logic.logic.getForFields(filter, unique=True): |
|
189 return |
|
190 |
|
191 if 'public' in allowed_roles: |
|
192 return |
|
193 |
|
194 # no roles found, access denied |
|
195 raise out_of_band.AccessViolation( |
|
196 message_fmt=DEF_NEED_ROLE_MSG) |
|
197 |
|
198 def checkStatusForTask(self, django_args): |
|
199 """Checks if the current user has access to the given task. |
|
200 |
|
201 Args: |
|
202 django_args: a dictionary with django's arguments |
|
203 |
|
204 Raises: |
|
205 AccessViolationResponse: |
|
206 - If there is no task found |
|
207 - If the task is not in one of the required states. |
|
208 """ |
|
209 |
|
210 try: |
|
211 self.checkIsUser(django_args) |
|
212 user_entity = self.user |
|
213 |
|
214 filter = { |
|
215 'user': user_entity, |
|
216 'status': 'active', |
|
217 'scope_path': django_args['scope_path'], |
|
218 } |
|
219 |
|
220 if ghop_org_admin_logic.logic.getForFields(filter, unique=True): |
|
221 return |
|
222 |
|
223 if ghop_mentor_logic.logic.getForFields(filter, unique=True): |
|
224 return |
|
225 |
|
226 except out_of_band.Error: |
|
227 pass |
|
228 |
|
229 # bail out with 404 if no task is found |
|
230 task_entity = ghop_task_logic.logic.getFromKeyFieldsOr404(django_args) |
|
231 |
|
232 if task_entity.status in ['Unapproved', 'Unpublished', 'Invalid']: |
|
233 # this proposal can not be task at the moment |
|
234 raise out_of_band.AccessViolation( |
|
235 message_fmt=DEF_NO_PUB_TASK_MSG) |