示例#1
0
    def checkRoleAndStatusForTask(self, django_args, allowed_roles,
                                  role_status, task_status):
        """Checks if the current user has access to the given task.

    This method checks if the current user is in one of the allowed_roles
    and has specified role_status, If yes, allows him to access the Task page.

    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 = gci_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,
            'scope_path': django_args['scope_path'],
            'status': role_status
        }

        if 'host' in allowed_roles:
            # check if the current user is a host for this proposal's program
            if host_logic.logic.getForFields(filter, unique=True):
                return

        if 'gci/org_admin' in allowed_roles:
            # check if the current user is an admin for this task's org
            if gci_org_admin_logic.logic.getForFields(filter, unique=True):
                return

        if 'gci/mentor' in allowed_roles:
            # check if the current user is a mentor for this task's org
            if gci_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)
示例#2
0
    def checkCanEditStudentProjectAsStudent(self, django_args):
        """Checks whether the project can be edited in a student mode
    by the current user.

    Args:
      django_args: a dictionary with django's arguments

     Raises:
       AccessViolationResponse:
         - If there is no project found
         - If the project does not belong to the current user
    """

        self.checkIsUser()

        project_entity = student_project_logic.getFromKeyFieldsOr404(
            django_args)
        student_entity = project_entity.student

        if student_entity.user.key() != self.user.key():
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NOT_YOUR_ENTITY_MSG)

        if student_entity.status != 'active':
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NO_ACTIVE_ENTITY_MSG)

        return
示例#3
0
    def checkCanDownloadConsentForms(self, django_args, student_logic,
                                     forms_data):
        """Checks if the user is a student who can download the forms i.e.
    the blobs he has requested.

    Args:
      django_args: a dictionary with django's arguments
      student_logic: student logic used to look up student entity
      forms_data: dictionary containing the data related to the forms
          that student should upload and entities that store the form.

    Raises:
      AccessViolationResponse:
        - If there are no forms uploaded for the student.
        - If the logged in user is not the one to whom the form belongs to.
    """

        self.checkIsUser(django_args)

        user_entity = self.user

        try:
            # if the current user is the program host no more access is required
            if self.checkIsHostForProgramInScope(django_args,
                                                 gci_program_logic.logic):
                return
        except out_of_band.AccessViolation:
            # if the user is not the host proceed for other checks
            # NOTE: This is not combined with the following exception because
            # if we catch AccessViolation there the access check for blob key
            # being null which raises the same exception will also be caught
            pass

        filter = {
            'user': user_entity,
            'status': 'active',
            'scope_path': django_args['scope_path'],
            'link_id': django_args['link_id'],
        }

        student_entity = student_logic.getForFields(filter, unique=True)

        try:
            form_type = django_args['GET'].get('type', '')
            blob_key = django_args['GET'].get('key', '')

            if not blob_key:
                raise out_of_band.AccessViolation(
                    message_fmt=DEF_NO_FILE_SPECIFIED_MSG)

            form_entity_name = forms_data.get(form_type, '')
            form_entity = getattr(student_entity, form_entity_name)
            if blob_key == str(form_entity.key()):
                return

        except AttributeError:
            pass

        raise out_of_band.AccessViolation(message_fmt=DEF_NO_FILE_ACCESS_MSG)
示例#4
0
    def checkStatusForTask(self, django_args):
        """Checks if the current user has access to the given task.

    This method checks if the current user is either an GCI Org Admin or a
    Mentor and is active, if yes it allows them to view the task page at any
    task state. If the user is none of the above, it checks the status of the
    task, and if it is in one of the valid published states it allows access
    to view the task page.

    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.
    """

        user_entity = self.user

        # bail out with 404 if no task is found
        task_entity = gci_task_logic.logic.getFromKeyFieldsOr404(django_args)

        if (user_entity and task_entity.user
                and task_entity.user.key() == user_entity.key()):
            return

        filter = {
            'user': user_entity,
            'status': 'active',
        }

        if host_logic.logic.getForFields(filter, unique=True):
            return

        filter['scope_path'] = django_args['scope_path']

        if gci_org_admin_logic.logic.getForFields(filter, unique=True):
            return

        if gci_mentor_logic.logic.getForFields(filter, unique=True):
            return

        org_entity = gci_org_logic.logic.getFromKeyNameOr404(
            django_args['scope_path'])

        if not timeline_helper.isAfterEvent(org_entity.scope.timeline,
                                            'tasks_publicly_visible'):
            raise out_of_band.AccessViolation(
                message_fmt=DEF_PAGE_INACTIVE_MSG)

        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)
示例#5
0
    def checkIsStudentProposalPubliclyVisible(self, django_args):
        """Checks whether the proposal's content can be seen by everyone.
    
    Args:
      django_args: a dictionary with django's arguments

    Raises:
      AccessViolationResponse:
        - If there is no proposal found
        - If the proposal cannot be publicly seen
    """

        proposal_entity = student_proposal_logic.getFromKeyFieldsOr404(
            django_args)

        user = self.user
        proposal_owner = proposal_entity.scope.user.key().id_or_name()

        # student may see his own proposal even if public view is not available
        if user and user.key().id_or_name() == proposal_owner:
            return

        if not proposal_entity.is_publicly_visible:
            raise out_of_band.AccessViolation(
                message_fmt=DEF_PROPOSAL_NOT_PUBLIC)

        return
示例#6
0
    def checkCanApply(self, django_args):
        """Checks if the user has the completed at least one task to register as
    a student.

    Args:
      django_args: a dictionary with django's arguments

     Raises:
       AccessViolationResponse:
         - If student has not completed even a single task
    """

        self.checkIsUser(django_args)

        program_entity = gci_program_logic.logic.getFromKeyNameOr404(
            django_args['scope_path'])

        filter = {
            'user': self.user,
            'program': program_entity,
            'status': 'AwaitingRegistration',
        }

        if gci_task_logic.logic.getForFields(filter, unique=True):
            return

        # no completed tasks found, access denied
        raise out_of_band.AccessViolation(message_fmt=DEF_CANT_REGISTER)
示例#7
0
    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
示例#8
0
    def checkCanOpenTaskList(self, django_args):
        """Checks if the current user is allowed to see a list of his tasks.

    Args:
      django_args: a dictionary with django's arguments

    Raises:
      AccessViolationResponse:
        - if the user is not registered as a student; and
        - if the user has not claimed a single task
    """

        self.checkIsUser(django_args)

        try:
            return self.checkHasRoleForScope(django_args, ghop_student_logic)
        except out_of_band.Error:
            pass

        program = ghop_program_logic.logic.getFromKeyNameOr404(
            django_args['scope_path'])

        filter = {
            'user': self.user,
            'program': program,
        }

        if not ghop_task_logic.logic.getForFields(filter, unique=True):
            raise out_of_band.AccessViolation(
                message_fmt=DEF_NO_TASKS_ASSIGNED)
示例#9
0
    def checkCanStudentPropose(self, django_args, key_location, check_limit):
        """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
      check_limit: iff true checks if the student reached the apps_tasks_limit
                   for the given program.
    """

        from soc.logic.helper import timeline as timeline_helper

        self.checkIsUser(django_args)

        if django_args.get('seed'):
            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=access.DEF_PAGE_INACTIVE_MSG)

        if check_limit:
            # count all studentproposals by the student
            fields = {'scope': student_entity}
            proposal_query = student_proposal_logic.getQueryForFields(fields)

            if proposal_query.count() >= program_entity.apps_tasks_limit:
                # too many proposals access denied
                raise out_of_band.AccessViolation(
                    message_fmt=DEF_MAX_PROPOSALS_REACHED)

        return
示例#10
0
    def checkOrgHasNoOpenTasks(self, django_args):
        """Checks if the organization does not have any tasks which might be 
    claimed by students.
    """

        org_entity = gci_org_logic.logic.getFromKeyFieldsOr404(django_args)

        fields = {'status': ['Open', 'Reopened'], 'scope': org_entity}
        if gci_task_logic.logic.getForFields(fields, unique=True):
            raise out_of_band.AccessViolation(message_fmt=DEF_ORG_HAS_TASKS)
示例#11
0
    def checkIsNotStudentForProgramOfOrg(self, django_args, org_logic,
                                         student_logic):
        """Extends the basic with one that checks whether the current user has
    claimed a task in the program.

    Args:
        See Checker.checkIsNotStudentForProgramOfOrg().
    """
        org_entity = super(GCIChecker, self).checkIsNotStudentForProgramOfOrg(
            django_args, org_logic, student_logic)

        fields = {'user': self.user, 'program': org_entity.scope}
        if gci_task_logic.logic.getForFields(fields, unique=True):
            raise out_of_band.AccessViolation(
                message_fmt=DEF_ALREADY_CLAIMED_A_TASK)

        return org_entity
示例#12
0
    def checkCanOpenTaskList(self, django_args, role_logic, role):
        """Checks if the current user is allowed to see a list of his tasks.

    Args:
      django_args: a dictionary with django's arguments
      role_logic: the specific role whose logic must be used to check
                  for the scope
      role: name of the role for this check is performed

    Raises:
      AccessViolationResponse:
        - if the user is not registered as a student; and
        - if the user has not claimed a single task
    """

        self.checkIsUser(django_args)

        try:
            return self.checkHasRoleForScope(django_args, role_logic)
        except out_of_band.Error:
            pass

        program = gci_program_logic.logic.getFromKeyNameOr404(
            django_args['scope_path'])

        filter = {
            'program': program,
        }

        if role == 'gci/student':
            filter['user'] = self.user
        elif role == 'gci/mentor':
            mentor_filter = {
                'user': self.user,
                'program': program,
                'status': 'active'
            }
            mentor_entity = role_logic.getForFields(mentor_filter, unique=True)
            filter['mentors'] = [mentor_entity]

        if not gci_task_logic.logic.getForFields(filter, unique=True):
            raise out_of_band.AccessViolation(
                message_fmt=DEF_NO_TASKS_AFFILIATED)
示例#13
0
    def checkStudentProjectHasStatus(self, django_args, allowed_status):
        """Checks whether the Project has one of the given statuses.

    Args:
      django_args: a dictionary with django's arguments
      allowed_status: list with the allowed statuses for the entity

     Raises:
       AccessViolationResponse:
         - If there is no project found
         - If the project is not in the requested status
    """

        project_entity = student_project_logic.getFromKeyFieldsOr404(
            django_args)

        if not project_entity.status in allowed_status:
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NO_ACTIVE_ENTITY_MSG)

        return
示例#14
0
    def checkTimelineFromTaskScope(self, django_args, status, period_name):
        """Checks the timeline for the program found in the scope variable of a
    Task.

    Args:
      django_args: a dictionary with django's arguments
      status: one of three strings, during which calls isActivePeriod(),
              before which calls isBeforeEvent() and after which calls
              isAfterEvent().
      period_name: the name of the period to check the timeline for.

    Raises:
      AccessViolationResponse:
        - if the program is not in a valid state
        - if the period specified does not pass the required status check
    """

        org_entity = gci_org_logic.logic.getFromKeyNameOr404(
            django_args['scope_path'])

        program_args = {'scope_path': org_entity.scope_path}

        if status is 'during':
            return self.checkIsActivePeriod(program_args, period_name,
                                            'scope_path',
                                            gci_program_logic.logic)
        elif status is 'before':
            return self.checkIsBeforeEvent(program_args, period_name,
                                           'scope_path',
                                           gci_program_logic.logic)
        elif status is 'after':
            return self.checkIsAfterEvent(program_args, period_name,
                                          'scope_path',
                                          gci_program_logic.logic)
        # no right status set, but we can't give the user access
        raise out_of_band.AccessViolation(message_fmt=DEF_UNEXPECTED_ERROR)
示例#15
0
    def checkIsAllowedToViewProjectSurveyRecordAs(self, django_args,
                                                  survey_logic, role_name,
                                                  record_key_location):
        """Checks whether the current user is allowed to view the record given in
    the GET data by the record_key_location.

    Args:
      django_args: a dictionary with django's arguments
      survey_logic: Survey Logic instance that belongs to the SurveyRecord
        type in question
      role_name: string containing either "student" or "mentor". Determines
        which of the roles the within the project the current user should have
        to view the evaluation results.
      record_key_location: string containing the name of the GET param which
        contains the id for the SurveyRecord to retrieve

    Raises:
      AccessViolation if:
        - No valid numeric Record ID is given in the POST data.
        - No Record could be retrieved for the given Record ID.
        - The current user has not taken the survey, is not the Student/Mentor
          (depending on the role_name) and is not an Org Admin for the project
          to which the SurveyRecord belongs.
    """

        if not role_name in ['mentor', 'student']:
            raise InvalidArgumentError('role_name is not mentor or student')

        self.checkIsUser(django_args)
        user_entity = self.user

        get_dict = django_args['GET']
        record_id = get_dict.get(record_key_location)

        if not record_id or not record_id.isdigit():
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NO_VALID_RECORD_ID)
        else:
            record_id = int(record_id)

        record_logic = survey_logic.getRecordLogic()
        record_entity = record_logic.getFromIDOr404(record_id)

        if record_entity.user.key() == user_entity.key():
            # this record belongs to the current user
            return

        if role_name == 'student':
            role_entity = record_entity.project.student
        elif role_name == 'mentor':
            role_entity = record_entity.project.mentor

        if role_entity.user.key() == user_entity.key() and (
                role_entity.status in ['active', 'inactive']):
            # this user has the role required
            return

        fields = {
            'user': user_entity,
            'scope': record_entity.org,
            'status': ['active', 'inactive']
        }
        admin_entity = org_admin_logic.getForFields(fields, unique=True)

        if admin_entity:
            # this user is org admin for the retrieved record's project
            return

        # The current user is no Org Admin, has not taken the Survey and is not
        # the one responsible for taking this survey.
        raise out_of_band.AccessViolation(
            message_fmt=access.DEF_NOT_YOUR_RECORD)
示例#16
0
    def checkIsAllowedToTakeProjectSurveyAs(self, django_args, survey_logic,
                                            role_name, project_key_location):
        """Checks whether a ProjectSurvey can be taken by the current User.

    role_name argument determines wether the current user is taking the survey
    as a student or mentor specified by the project in GET dict.

    If the survey is taken as a mentor, org admins for the Organization in
    which the project resides will also have access.

    However if the project entry is not present in the dictionary this access
    check passes.

    Args:
      django_args: a dictionary with django's arguments
      survey_logic: instance of ProjectSurveyLogic (or subclass)
      role_name: String containing either "student" or "mentor"
      project_key_location: String containing the key entry in the GET dict
        where the key for the project can be located.
    """

        if not role_name in ['mentor', 'student']:
            raise InvalidArgumentError('role_name is not mentor or student')

        # check if the current user is signed up
        self.checkIsUser(django_args)
        user_entity = self.user

        # get the project keyname from the GET dictionary
        get_dict = django_args['GET']
        key_name = get_dict.get(project_key_location)

        if not key_name:
            # no key name present so no need to deny access
            return

        # retrieve the Student Project for the key
        project_entity = student_project_logic.getFromKeyNameOr404(key_name)

        # check if a survey can be conducted about this project
        if project_entity.status != 'accepted':
            raise out_of_band.AccessViolation(
                message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)

        # get the correct role depending on the role_name
        if role_name == 'student':
            role_entity = project_entity.student
        elif role_name == 'mentor':
            role_entity = project_entity.mentor

        # check if the role matches the current user
        if role_entity.user.key() != user_entity.key() and (role_entity.status
                                                            == 'active'):
            if role_name == 'student':
                raise out_of_band.AccessViolation(
                    message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)
            elif role_name == 'mentor':
                # check if the current user is an Org Admin for this Student Project
                fields = {
                    'user': user_entity,
                    'scope': project_entity.scope,
                    'status': 'active'
                }
                admin_entity = org_admin_logic.getForFields(fields,
                                                            unique=True)
                if not admin_entity:
                    # this user is no Org Admin or Mentor for this project
                    raise out_of_band.AccessViolation(
                        message_fmt=DEF_NOT_ALLOWED_PROJECT_FOR_SURVEY_MSG)
        elif role_entity.status != 'active':
            # this role is not active
            raise out_of_band.AccessViolation(
                message_fmt=access.DEF_NEED_ROLE_MSG)

        return
示例#17
0
    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=access.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.scope

            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=access.DEF_NEED_ROLE_MSG)
示例#18
0
    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
                    of the org is stored.
      check_limit: iff true checks if the organization reached the
                   task quota limit for the given program.
    """

        import settings

        self.checkIsUser(django_args)

        user_account = user_logic.logic.getCurrentUser()

        if key_location not in django_args:
            raise out_of_band.AccessViolation(message_fmt=DEF_NEED_ROLE_MSG)

        filter = {
            'user': user_account,
            'scope_path': django_args[key_location],
            'status': 'active'
        }

        role_entity = gci_org_admin_logic.logic.getForFields(filter,
                                                             unique=True)
        if not role_entity:
            role_entity = gci_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)

        # pylint: disable=E1103
        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)

        # pylint: disable=E1103
        org_entity = role_entity.scope

        if settings.GCI_TASK_QUOTA_LIMIT_ENABLED and check_limit:
            # count all tasks from this organization
            fields = {'scope': org_entity}
            task_query = gci_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_MSG)

        if 'link_id' in django_args:
            task_entity = gci_task_logic.logic.getFromKeyFieldsOr404(
                django_args)

            if task_entity.status not in [
                    'Unapproved', 'Unpublished', 'Open', 'ClaimRequested',
                    'Reopened'
            ]:
                # task is claimed at least once
                raise out_of_band.AccessViolation(
                    message_fmt=DEF_CANT_EDIT_MSG)

        return