# HG changeset patch # User Madhusudan.C.S # Date 1251633381 -7200 # Node ID 41f7938a35b0b6c72398ae246978342a6e0d5176 # Parent e031b1a734c33432ab1a7d0cc881462f02b62edb Added access checks for GHOP Module. Reviewed by: Lennard de Rijk diff -r e031b1a734c3 -r 41f7938a35b0 app/soc/modules/ghop/views/helper/access.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/soc/modules/ghop/views/helper/access.py Sun Aug 30 13:56:21 2009 +0200 @@ -0,0 +1,235 @@ +#!/usr/bin/python2.5 +# +# Copyright 2009 the Melange authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Access control helper. + +See soc.views.helper.access module. +""" + +__authors__ = [ + '"Madhusudan.C.S" ' + ] + + +from django.utils.translation import ugettext + +from soc.logic.helper import timeline as timeline_helper +from soc.logic.models import host as host_logic +from soc.logic.models import user as user_logic +from soc.views import out_of_band +from soc.views.helper import access + +from soc.modules.ghop.logic.models import mentor as ghop_mentor_logic +from soc.modules.ghop.logic.models import org_admin as ghop_org_admin_logic +from soc.modules.ghop.logic.models import task as ghop_task_logic + + +DEF_CANT_EDIT_MSG = ugettext( + 'This task cannot be edited since it has been claimed at least ' + 'once before.') + +DEF_MAX_TASKS_REACHED_MSG = ugettext( + 'You have reached the maximum number of Tasks allowed ' + 'for your organization for this program.') + +DEF_NEED_ROLE_MSG = ugettext( + 'You do not have the required role.') + +DEF_NO_ACTIVE_ENTITY_MSG = ugettext( + 'There is no such active entity.') + +DEF_NO_PUB_TASK_MSG = ugettext( + 'There is no such published task.') + +DEF_PAGE_INACTIVE_MSG = ugettext( + 'This page is inactive at this time.') + +DEF_SIGN_UP_AS_OA_MENTOR_MSG = ugettext( + 'You first need to sign up as an Org Admin or a Mentor.') + + +class GHOPChecker(access.Checker): + """See soc.views.helper.access.Checker. + """ + + @access.allowDeveloper + @access.denySidebar + def checkCanOrgAdminOrMentorEdit(self, django_args, + key_location, check_limit): + """Checks if the mentors can create task for this program, + and obeys the task quota limit assigned for their org when check_limit is + True. + + Args: + django_args: a dictionary with django's arguments + key_location: the key for django_args in which the key_name + from the mentor is stored + check_limit: iff true checks if the organization reached the + task quota limit for the given program. + """ + + self.checkIsUser(django_args) + + user_account = user_logic.logic.getForCurrentAccount() + + filter = { + 'user': user_account, + 'scope_path': django_args[key_location], + 'status': 'active' + } + + role_entity = ghop_org_admin_logic.logic.getForFields( + filter, unique=True) + if not role_entity: + role_entity = ghop_mentor_logic.logic.getForFields( + filter, unique=True) + + if not role_entity: + raise out_of_band.AccessViolation( + message_fmt=DEF_SIGN_UP_AS_OA_MENTOR_MSG) + + program_entity = role_entity.program + + if not timeline_helper.isActivePeriod(program_entity.timeline, + 'program'): + raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG) + + org_entity = role_entity.scope + + if check_limit: + # count all tasks from this organization + fields = {'scope': org_entity} + task_query = ghop_task_logic.logic.getQueryForFields(fields) + + if task_query.count() >= org_entity.task_quota_limit: + # too many tasks access denied + raise out_of_band.AccessViolation(message_fmt=DEF_MAX_TASKS_REACHED) + + if 'link_id' in django_args: + task_filter = { + 'link_id': django_args['link_id'], + 'scope_path': django_args['scope_path'], + } + task_entity = ghop_task_logic.logic.getFromKeyFields(task_filter) + + if task_entity.status not in ['Unapproved', 'Unpublished', 'Open']: + # task is claimed at least once + raise out_of_band.AccessViolation(message_fmt=DEF_CANT_EDIT_MSG) + + return + + @access.allowDeveloper + @access.denySidebar + def checkRoleAndStatusForTask(self, django_args, allowed_roles, + role_status, task_status): + """Checks if the current user has access to the given task. + + Args: + django_args: a dictionary with django's arguments + allowed_roles: list with names for the roles allowed to pass access check + role_status: list with states allowed for the role + task_status: a list with states allowed for the task + + Raises: + AccessViolationResponse: + - If there is no task found + - If the task is not in one of the required states. + - If the user does not have any of the required roles + """ + + self.checkIsUser(django_args) + + if 'link_id' in django_args: + # bail out with 404 if no task is found + task_entity = ghop_task_logic.logic.getFromKeyFieldsOr404(django_args) + + if not task_entity.status in task_status: + # this task can not be accessed at the moment + raise out_of_band.AccessViolation( + message_fmt=DEF_NO_ACTIVE_ENTITY_MSG) + + user_entity = self.user + + filter = { + 'user': user_entity, + 'status': role_status} + + if 'host' in allowed_roles: + # check if the current user is a host for this proposal's program + filter['scope'] = task_entity.program + + if host_logic.logic.getForFields(filter, unique=True): + return + + if 'ghop/org_admin' in allowed_roles: + # check if the current user is an admin for this task's org + filter['scope_path'] = django_args['scope_path'] + + if ghop_org_admin_logic.logic.getForFields(filter, unique=True): + return + + if 'ghop/mentor' in allowed_roles: + # check if the current user is a mentor for this task's org + filter['scope_path'] = django_args['scope_path'] + + if ghop_mentor_logic.logic.getForFields(filter, unique=True): + return + + if 'public' in allowed_roles: + return + + # no roles found, access denied + raise out_of_band.AccessViolation( + message_fmt=DEF_NEED_ROLE_MSG) + + def checkStatusForTask(self, django_args): + """Checks if the current user has access to the given task. + + Args: + django_args: a dictionary with django's arguments + + Raises: + AccessViolationResponse: + - If there is no task found + - If the task is not in one of the required states. + """ + + try: + self.checkIsUser(django_args) + user_entity = self.user + + filter = { + 'user': user_entity, + 'status': 'active', + 'scope_path': django_args['scope_path'], + } + + if ghop_org_admin_logic.logic.getForFields(filter, unique=True): + return + + if ghop_mentor_logic.logic.getForFields(filter, unique=True): + return + + except out_of_band.Error: + pass + + # bail out with 404 if no task is found + task_entity = ghop_task_logic.logic.getFromKeyFieldsOr404(django_args) + + if task_entity.status in ['Unapproved', 'Unpublished', 'Invalid']: + # this proposal can not be task at the moment + raise out_of_band.AccessViolation( + message_fmt=DEF_NO_PUB_TASK_MSG)