Added several access checks for student proposals.
authorLennard de Rijk <ljvderijk@gmail.com>
Sun, 22 Feb 2009 20:42:05 +0000
changeset 1466 bfcec687b362
parent 1465 f3805525efda
child 1467 c5f99265a680
Added several access checks for student proposals. Patch by: Lennard de Rijk Reviewed by: to-be-reviewed
app/soc/views/helper/access.py
--- 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.