Added several access checks for student proposals.
Patch by: Lennard de Rijk
Reviewed by: to-be-reviewed
--- a/app/soc/views/helper/access.py Sun Feb 22 20:36:22 2009 +0000
+++ b/app/soc/views/helper/access.py Sun Feb 22 20:42:05 2009 +0000
@@ -55,6 +55,7 @@
from soc.logic.models.site import logic as site_logic
from soc.logic.models.sponsor import logic as sponsor_logic
from soc.logic.models.student import logic as student_logic
+from soc.logic.models.student_proposal import logic as student_proposal_logic
from soc.logic.models.timeline import logic as timeline_logic
from soc.logic.models.user import logic as user_logic
from soc.views.helper import redirects
@@ -124,6 +125,9 @@
DEF_SCOPE_INACTIVE_MSG = ugettext(
'The scope for this request is not active.')
+DEF_SIGN_UP_AS_STUDENT_MSG = ugettext(
+ 'You need to sign up as a Student first.')
+
DEF_NO_LIST_ACCESS_MSG = ugettext(
'You do not have the required rights to list documents for this scope and prefix.')
@@ -992,6 +996,133 @@
return
+ @allowDeveloper
+ def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles,
+ role_status, proposal_status):
+ """Checks if the current user has access to the given proposal.
+
+ 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
+ proposal_status: a list with states allowed for the proposal
+
+ Raises:
+ AccessViolationResponse:
+ - If there is no proposal found
+ - If the proposal is not in one of the required states.
+ - If the user does not have any ofe the required roles
+ """
+
+ self.checkIsUser(django_args)
+
+ # bail out with 404 if no proposal is found
+ proposal_entity = student_proposal_logic.getFromKeyFieldsOr404(django_args)
+
+ if not proposal_entity.status in proposal_status:
+ # this proposal can not be accessed at the moment
+ raise out_of_band.AccessViolation(
+ message_fmt=DEF_NO_ACTIVE_ENTITY_MSG)
+
+ user_entity = self.user
+
+ if 'proposer' in allowed_roles:
+ # check if this proposal belongs to the current user
+ student_entity = proposal_entity.scope
+ if (user_entity.key() == student_entity.user.key()) and (
+ student_entity.status in role_status):
+ return
+
+ 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'] = proposal_entity.program
+
+ if host_logic.getForFields(filter, unique=True):
+ return
+
+ if 'org_admin' in allowed_roles:
+ # check if the current user is an admin for this proposal's org
+ filter['scope'] = proposal_entity.org
+
+ if org_admin_logic.getForFields(filter, unique=True):
+ return
+
+ if 'mentor' in allowed_roles:
+ # check if the current user is a mentor for this proposal's org
+ filter['scope'] = proposal_entity.org
+
+ if mentor_logic.getForFields(filter, unique=True):
+ return
+
+ # no roles found, access denied
+ raise out_of_band.AccessViolation(
+ message_fmt=DEF_NEED_ROLE_MSG)
+
+ @allowDeveloper
+ def checkCanStudentPropose(self, django_args, key_location):
+ """Checks if the program for this student accepts proposals.
+
+ Args:
+ django_args: a dictionary with django's arguments
+ key_location: the key for django_args in which the key_name
+ from the student is stored
+ """
+
+ self.checkIsUser(django_args)
+
+ if 'seed' in django_args:
+ key_name = django_args['seed'][key_location]
+ else:
+ key_name = django_args[key_location]
+
+ student_entity = student_logic.getFromKeyName(key_name)
+
+ if not student_entity or student_entity.status == 'invalid':
+ raise out_of_band.AccessViolation(
+ message_fmt=DEF_SIGN_UP_AS_STUDENT_MSG)
+
+ program_entity = student_entity.scope
+
+ if not timeline_helper.isActivePeriod(program_entity.timeline,
+ 'student_signup'):
+ raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
+
+ return
+
+ @allowDeveloper
+ def checkIsStudent(self, django_args, key_location, status):
+ """Checks if the current user is the given student.
+
+ Args:
+ django_args: a dictionary with django's arguments
+ key_location: the key for django_args in which the key_name
+ from the student is stored
+ status: the allowed status for the student
+ """
+
+ self.checkIsUser(django_args)
+
+ if 'seed' in django_args:
+ key_name = django_args['seed'][key_location]
+ else:
+ key_name = django_args[key_location]
+
+ student_entity = student_logic.getFromKeyName(key_name)
+
+ if not student_entity or student_entity.status not in status:
+ raise out_of_band.AccessViolation(
+ message_fmt=DEF_SIGN_UP_AS_STUDENT_MSG)
+
+ if student_entity.user.key() != self.user.key():
+ # this is not the page for the current user
+ self.deny(django_args)
+
+ return
+
+ @allowDeveloper
def checkIsMyEntity(self, django_args, logic,
field_name='user', user=False):
"""Checks whether the entity belongs to the user.