예제 #1
0
    def toggleFeatured(self, data, value):
        """Makes the project featured.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(message="Invalid post data.")
        if value == 'checked' and not data.url_project.is_featured:
            raise exception.BadRequest(message="Invalid post data.")
        if value == 'unchecked' and data.url_project.is_featured:
            raise exception.BadRequest(message="Invalid post data.")

        project_key = data.url_project.key()

        def make_featured_txn():
            # transactionally get latest version of the project
            project = db.get(project_key)
            if value == 'unchecked':
                project.is_featured = True
            elif value == 'checked':
                project.is_featured = False

            db.put(project)

        db.run_in_transaction(make_featured_txn)
예제 #2
0
    def post(self):
        """Processes the form post data by checking what buttons were pressed."""
        idx = lists.getListIndex(self.data.request)
        if idx != self.IDX:
            return None

        data = self.data.POST.get('data')

        if not data:
            raise exception.BadRequest(message='Missing data')

        parsed = json.loads(data)

        button_id = self.data.POST.get('button_id')

        if not button_id:
            raise exception.BadRequest(message='Missing button_id')

        if button_id == self.PUBLISH_BUTTON_ID:
            return self.postPublish(parsed, True)

        if button_id == self.UNPUBLISH_BUTTON_ID:
            return self.postPublish(parsed, False)

        raise exception.BadRequest(message="Unknown button_id")
예제 #3
0
    def toggleStatus(self, data, value):
        """Toggles the the application state between accept and pending.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(message="Invalid post data.")

        if value == 'checked' and not data.url_proposal.accept_as_project:
            raise exception.BadRequest(message="Invalid post data.")
        if value == 'unchecked' and data.url_proposal.accept_as_project:
            raise exception.BadRequest(message="Invalid post data.")

        proposal_key = data.url_proposal.key()

        def update_status_txn():
            # transactionally get latest version of the proposal
            proposal = db.get(proposal_key)
            if value == 'unchecked':
                proposal.accept_as_project = True
            elif value == 'checked':
                proposal.accept_as_project = False

            db.put(proposal)

        db.run_in_transaction(update_status_txn)
예제 #4
0
    def togglePublicVisibilty(self, data, value):
        """Toggles the the public visibility of the application.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(message="Invalid post data.")

        if value == 'checked' and not data.url_proposal.is_publicly_visible:
            raise exception.BadRequest(message="Invalid post data.")
        if value == 'unchecked' and data.url_proposal.is_publicly_visible:
            raise exception.BadRequest(message="Invalid post data.")

        def update_publicly_visibility_txn():
            # transactionally get latest version of the proposal
            proposal = db.get(data.url_proposal.key())
            if value == 'unchecked':
                proposal.is_publicly_visible = True
            elif value == 'checked':
                proposal.is_publicly_visible = False

            db.put(proposal)

        db.run_in_transaction(update_publicly_visibility_txn)
예제 #5
0
    def toggleModificationPermission(self, data, value):
        """Toggles the permission to modify the proposal after proposal deadline.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(message="Invalid post data.")

        if value == 'checked' and not data.url_proposal.is_editable_post_deadline:
            raise exception.BadRequest(message="Invalid post data.")
        if value == 'unchecked' and data.url_proposal.is_editable_post_deadline:
            raise exception.BadRequest(message="Invalid post data.")

        proposal_key = data.url_proposal.key()

        def update_modification_perm_txn():
            # transactionally get latest version of the proposal
            proposal = db.get(proposal_key)
            if value == 'unchecked':
                proposal.is_editable_post_deadline = True
            elif value == 'checked':
                proposal.is_editable_post_deadline = False

            db.put(proposal)

        db.run_in_transaction(update_modification_perm_txn)
예제 #6
0
  def document(self):
    """Returns document property."""
    if not self._isSet(self._document):
      fields = []
      kwargs = self.kwargs.copy()

      prefix = kwargs.pop('prefix', None)
      fields.append(prefix)

      if prefix in ['gsoc_program', 'gsoc_org', 'gci_program', 'gci_org']:
        fields.append(kwargs.pop('sponsor', None))
        fields.append(kwargs.pop('program', None))

      if prefix in ['gsoc_org', 'gci_org']:
        fields.append(kwargs.pop('organization', None))

      fields.append(kwargs.pop('document', None))

      if any(kwargs.values()):
        raise exception.BadRequest(message="Unexpected value for document url")

      if not all(fields):
        raise exception.BadRequest(message="Missing value for document url")

      # TODO(daniel): remove key_name from it.
      self.key_name = '/'.join(fields)
      self._document = document_model.Document.get_by_key_name(self.key_name)
    return self._document
예제 #7
0
  def post(self, data, check, mutator):
    """See base.RequestHandler.post for specification."""
    form = _formToCreateOrgProfile(request_data=data, data=data.POST)

    if not form.is_valid():
      # TODO(nathaniel): problematic self-use.
      return self.get(data, check, mutator)
    else:
      contact_properties = form.getContactProperties()
      result = contact_logic.createContact(**contact_properties)

      if not result:
        raise exception.BadRequest(message=result.extra)
      else:
        org_properties = form.getOrgProperties()
        org_properties['contact'] = result.extra

        # org_id is a special property
        org_id = org_properties['org_id']
        del org_properties['org_id']

        result = createOrganizationTxn(
            data, org_id, data.program.key(), org_properties,
            [data.ndb_profile.key, form.cleaned_data['backup_admin'].key],
            data.models)

        if not result:
          raise exception.BadRequest(message=result.extra)
        else:
          url = links.LINKER.organization(
              result.extra.key, urls.UrlNames.ORG_APPLICATION_SUBMIT)
          return http.HttpResponseRedirect(url)
예제 #8
0
    def toggleIgnoreProposal(self, data, value):
        """Toggles the ignore status of the proposal.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(message="Invalid post data.")

        if value == 'checked' and data.url_proposal.status != 'ignored':
            raise exception.BadRequest(message="Invalid post data.")
        if value == 'unchecked' and data.url_proposal.status not in [
                'pending', 'withdrawn'
        ]:
            raise exception.BadRequest(message="Invalid post data.")

        proposal_key = data.url_proposal.key()

        def update_status_txn():
            # transactionally get latest version of the proposal
            proposal = db.get(proposal_key)
            if value == 'unchecked':
                proposal.status = 'ignored'
            elif value == 'checked':
                proposal.status = 'pending'

            db.put(proposal)

        db.run_in_transaction(update_status_txn)
예제 #9
0
 def post(self, data, check, mutator):
   """See base.GSoCRequestHandler.post for specification."""
   button_id = data.POST.get('button_id')
   if button_id is not None:
     if button_id == _SET_STATUS_BUTTON_ID:
       handler = SetOrganizationStatusHandler(self)
       return handler.handle(data, check, mutator)
     elif button_id == _APPLY_ORG_ADMISSION_DECISION_ID:
       handler = ApplyOrgAdmissionDecisionHandler(self)
       return handler.handle(data, check, mutator)
     else:
       raise exception.BadRequest(
           message='Button id %s not supported.' % button_id)
   else:
     raise exception.BadRequest(message='Invalid POST data.')
예제 #10
0
    def post(self, data, check, mutator):
        """See base.post for specification."""
        profile_key = ndb.Key.from_old_key(data.url_project.parent_key())

        # get type of survey based on submitted form name
        survey_type = _getSurveyType(data.POST)
        survey_key = project_survey_logic.constructEvaluationKey(
            data.program.key(), survey_type)

        # check if the survey exists
        if not db.get(survey_key):
            raise exception.BadRequest(message='Survey of type %s not found.' %
                                       survey_type)

        # try setting a personal extension
        form = PersonalExtensionForm(data=data.POST)
        result = _setPersonalExtension(profile_key, survey_key, form)

        if result:
            # redirect to somewhere
            url = links.LINKER.userId(data.url_ndb_profile.key,
                                      data.url_project.key().id(),
                                      urls.UrlNames.PROJECT_MANAGE_ADMIN)
            # TODO(daniel): append GET parameter in a better way
            url = url + '?validated'
            return http.HttpResponseRedirect(url)
        else:
            # TODO(nathaniel): problematic self-use.
            return self.get(data, check, mutator)
예제 #11
0
  def url_ndb_org(self):
    """Returns url_org property.

    This property represents organization entity whose identifier is a part
    of the URL of the processed request.

    Returns:
      Retrieved organization entity.

    Raises:
      exception.BadRequest: if the current request does not contain any
        organization data.
      exception.NotFound: if the organization is not found.
    """
    if not self._isSet(self._url_ndb_org):
      try:
        fields = ['sponsor', 'program', 'organization']
        entity_id = '/'.join(self.kwargs[i] for i in fields)
      except KeyError:
        raise exception.BadRequest(
            message='The request does not contain full organization data.')

      self._url_ndb_org = self.models.ndb_org_model.get_by_id(entity_id)

      if not self._url_ndb_org:
        raise exception.NotFound(
            message='Requested organization does not exist.')
    return self._url_ndb_org
예제 #12
0
    def url_proposal(self):
        """Returns the url_proposal field.

    This property represents a proposal entity corresponding to a profile whose
    identifier is a part of the URL of the processed request. Numerical
    identifier of the proposal is also a part of the URL.

    Returns:
      Retrieved proposal entity.

    Raises:
      exception.BadRequest: if some data is missing in the current request.
      exception.NotFound: if no entity is found.
    """
        if not self._isSet(self._url_proposal):
            if 'id' not in self.kwargs:
                raise exception.BadRequest(
                    message='The request does not contain proposal id.')
            else:
                self._url_proposal = proposal_model.GSoCProposal.get_by_id(
                    int(self.kwargs['id']),
                    self.url_ndb_profile.key.to_old_key())

                if not self._url_proposal:
                    raise exception.NotFound(
                        message='Requested proposal does not exist.')

        return self._url_proposal
예제 #13
0
  def url_connection(self):
    """Returns url_connection property.

    This property represents connection entity corresponding to profile whose
    identifier is a part of the URL of the processed request. Numerical
    identifier of the connection is also a part of the URL.

    Returns:
      Retrieved connection entity.

    Raises:
      exception.BadRequest: if some data is missing in the current request.
      exception.NotFound: if no entity is found.
    """
    if not self._isSet(self._url_connection):
      try:
        connection_key = ndb.Key(
            connection_model.Connection._get_kind(), int(self.kwargs['id']),
            parent=self._getUrlNdbProfileKey())
      except KeyError:
        raise exception.BadRequest(
            message='The request does not contain connection id.')

      self._url_connection = connection_key.get()
      if not self._url_connection:
        raise exception.NotFound(
            message='Requested connection does not exist.')
    return self._url_connection
예제 #14
0
 def jsonContext(self, data, check, mutator):
     list_content = SlotsList(data).getListData()
     if list_content:
         return list_content.content()
     else:
         raise exception.BadRequest(
             message='Missing idx parameter for component.')
예제 #15
0
  def url_ndb_user(self):
    """Returns url_user property.

    This property represents user entity for a person whose identifier
    is a part of the URL of the processed request.

    Returns:
      Retrieved user entity.

    Raises:
      exception.BadRequest: if the current request does not contain
        any user data.
      exception.NotFound: if the user is not found.
    """
    if not self._isSet(self._url_ndb_user):
      key_id = self.kwargs.get('user')
      if not key_id:
        raise exception.BadRequest(
            message='The request does not contain user data.')

      self._url_ndb_user = self.models.user_model.get_by_id(key_id)

      if not self._url_ndb_user:
        raise exception.NotFound(message='Requested user does not exist.')
    return self._url_ndb_user
예제 #16
0
 def jsonContext(self, data, check, mutator):
   """See base.GSoCRequestHandler.jsonContext for specification."""
   idx = lists.getListIndex(data.request)
   if idx == 0:
     list_data = OrgApplicationList(data, data.org_app).getListData()
     return list_data.content()
   else:
     raise exception.BadRequest(message='Invalid ID has been specified.')
예제 #17
0
    def post(self, data, check, mutator):
        """Edits records from commands received by the list code."""
        post_dict = data.request.POST

        data.redirect.program()

        if (post_dict.get('process',
                          '') == org_app.PROCESS_ORG_APPS_FORM_BUTTON_VALUE):
            mapreduce_control.start_map(
                'ProcessOrgApp', {
                    'program_type': 'gsoc',
                    'program_key': data.program.key().name()
                })
            return data.redirect.to('gsoc_list_org_app_records',
                                    validated=True)

        if post_dict.get('button_id', None) != 'save':
            raise exception.BadRequest(message='No valid POST data found')

        post_data = post_dict.get('data')

        if not post_data:
            raise exception.BadRequest(message='Missing data')

        parsed = json.loads(post_data)

        url = 'TODO(daniel): remove this part as it is not used anymore'

        for oaid, properties in parsed.iteritems():
            record = OrgAppRecord.get_by_id(long(oaid))

            if not record:
                logging.warning('%s is an invalid OrgAppRecord ID', oaid)
                continue

            if record.survey.key() != data.org_app.key():
                logging.warning(
                    '%s is not a record for the Org App in the URL',
                    record.key())
                continue

            new_status = properties['status']
            org_app_logic.setStatus(data, record, new_status, url)

        return http.HttpResponse()
예제 #18
0
    def createOrUpdateScore(self, data, value):
        """Creates a new score or updates a score if there is already one
    posted by the current user.

    If the value passed in is 0 then the Score of the user will be removed and
    None will be returned.

    Args:
      data: A RequestData describing the current request.
      value: The value of the score the user gave as an integer.

    Returns:
      The score entity that was created/updated or None if value is 0.
    """
        org_key = proposal_model.GSoCProposal.org.get_value_for_datastore(
            data.url_proposal)
        org = ndb.Key.from_old_key(org_key).get()
        max_score = org.max_score

        if value < 0 or value > max_score:
            raise exception.BadRequest(
                message="Score must not be higher than %d" % max_score)

        query = db.Query(GSoCScore)
        query.filter('author = ', data.ndb_profile.key.to_old_key())
        query.ancestor(data.url_proposal)

        def update_score_trx():
            delta = 0

            # update score entity
            score = query.get()
            if not score:
                if not value:
                    return
                old_value = 0
                score = GSoCScore(parent=data.url_proposal,
                                  author=data.ndb_profile.key.to_old_key(),
                                  value=value)
                score.put()
                delta = 1
            else:
                old_value = score.value
                if not value:
                    delta = -1
                    score.delete()
                else:
                    score.value = value
                    score.put()

            # update total score for the proposal
            proposal = db.get(data.url_proposal.key())
            proposal.score += value - old_value
            proposal.nr_scores += delta
            proposal.put()

        db.run_in_transaction(update_score_trx)
예제 #19
0
    def get(self, data, check, mutator):
        """Get handler for the code sample download file."""
        assert isSet(data.url_project)

        try:
            id_value = int(data.request.GET['id'])
            code_sample = GSoCCodeSample.get_by_id(id_value, data.url_project)
            if not code_sample or not code_sample.upload_of_work:
                raise exception.BadRequest(
                    message='Requested project or code sample not found')
            else:
                return bs_helper.sendBlob(code_sample.upload_of_work)
        except KeyError:
            raise exception.BadRequest(
                message='id argument missing in GET data')
        except ValueError:
            raise exception.BadRequest(
                message='id argument in GET data is not a number')
예제 #20
0
    def post(self):
        idx = lists.getListIndex(self.data.request)
        if idx != 0:
            return None

        list_data = self.data.POST.get('data')

        if not list_data:
            raise exception.BadRequest(message="Missing data")

        button_id = self.data.POST.get('button_id')

        if button_id == 'accept':
            return self.postHandler(json.loads(list_data))
        elif button_id:
            raise exception.BadRequest(message='Unknown button_id')
        else:
            raise exception.BadRequest(message="Missing button_id")
예제 #21
0
    def toggleNotificationsEnabled(self, data, value):
        """Makes email notifications enabled or disabled.

    Args:
      data: A RequestData describing the current request.
      value: can be either "checked" or "unchecked".
    """
        assert access_checker.isSet(data.conversation)
        assert access_checker.isSet(data.user)

        query = gciconversation_logic.queryConversationUserForConversationAndUser(
            data.conversation.key, ndb.Key.from_old_key(data.user.key()))
        conv_user_results = query.fetch(1)
        assert conv_user_results
        conv_user = conv_user_results[0]

        if value != 'checked' and value != 'unchecked':
            raise exception.BadRequest(
                message='Invalid post data. Value must be checked or unchecked.'
            )
        if value == 'checked' and not conv_user.enable_notifications:
            raise exception.BadRequest(
                message='Notifications were already disabled.')
        if value == 'unchecked' and conv_user.enable_notifications:
            raise exception.BadRequest(
                message='Notifications were already enabled.')

        conv_user_key = conv_user.key

        # TODO(nathaniel): Remove the suppression on the following line when
        # https://bitbucket.org/logilab/pylint.org/issue/6/false-positive-no
        # is fixed.
        @ndb.transactional(xg=True)  # pylint: disable=no-value-for-parameter
        def set_notifications_enabled_txn():
            # transactionally get latest GCIConversationUser
            conv_user = conv_user_key.get()
            if value == 'unchecked':
                conv_user.enable_notifications = True
            elif value == 'checked':
                conv_user.enable_notifications = False

            conv_user.put()

        set_notifications_enabled_txn()
예제 #22
0
    def checkAccess(self, data, check):
        """See AccessChecker.checkAccess for specification."""
        key_id = data.kwargs.get('user')
        if not key_id:
            raise exception.BadRequest(
                'The request does not contain user data.')

        ensureLoggedIn(data)

        if not data.ndb_user or data.ndb_user.key.id() != key_id:
            raise exception.Forbidden(message=_MESSAGE_NOT_USER_IN_URL)
예제 #23
0
  def handle(self, data, check, mutator):
    """See form_handler.FormHandler.handle for specification."""
    post_data = data.POST.get('data')

    if not post_data:
      raise exception.BadRequest(message='Missing data.')

    parsed_data = json.loads(post_data)
    for org_key_id, properties in parsed_data.iteritems():
      org_key = ndb.Key(
          data.models.ndb_org_model._get_kind(), org_key_id)
      new_status = _STATUS_ID_TO_ENUM_MAP.get(properties.get('status'))
      if not new_status:
        raise exception.BadRequest(
            message='Missing or invalid new status in POST data.')
      else:
        organization = org_key.get()
        org_logic.setStatus(organization, data.program, data.site,
                            data.program.getProgramMessages(), new_status)
        return http.HttpResponse()
예제 #24
0
def forUserId(user_id):
    """Retrieves the user entity for the specified user id.

  If there is no user logged in, or they have no valid associated User
  entity, None is returned.
  """
    if not user_id:
        raise exception.BadRequest(message="Missing argument 'user_id'")

    q = user_model.User.all()
    q.filter('user_id', user_id)
    q.filter('status', 'valid')
    return q.get()
예제 #25
0
    def post(self):
        idx = lists.getListIndex(self.data.request)
        if idx != 0:
            return None

        data = self.data.POST.get('data')

        if not data:
            raise exception.BadRequest(message="Missing data")

        parsed = json.loads(data)

        button_id = self.data.POST.get('button_id')

        if not button_id:
            raise exception.BadRequest(message="Missing button_id")
        elif button_id == 'withdraw':
            return self.postHandler(parsed)
        elif button_id == 'accept':
            return self.postHandler(parsed, withdraw=False)
        else:
            raise exception.BadRequest(message="Unknown button_id")
예제 #26
0
    def get(self, data, check, mutator):
        """Allows hosts to download the student forms."""
        if url_names.CONSENT_FORM_GET_PARAM in data.GET:
            download = data.url_ndb_profile.student_data.consent_form
        elif url_names.ENROLLMENT_FORM_GET_PARAM in data.GET:
            download = data.url_ndb_profile.student_data.enrollment_form
        else:
            raise exception.BadRequest(message='No file requested')

        # download has been requested
        if download:
            return bs_helper.sendBlob(blobstore.BlobInfo(download))
        else:
            raise exception.NotFound(message='File not found')
예제 #27
0
    def get(self, data, check, mutator):
        """Attempts to download the blob in the worksubmission that is specified
    in the GET argument.
    """
        id_string = data.request.GET.get('id', '')
        submission_id = int(id_string) if id_string.isdigit() else -1

        work = work_submission_model.GCIWorkSubmission.get_by_id(
            submission_id, data.task)

        if work and work.upload_of_work:
            return bs_helper.sendBlob(work.upload_of_work)
        else:
            raise exception.BadRequest(message=DEF_NO_WORK_FOUND % id_string)
예제 #28
0
    def post(self, data, check, mutator):
        """Get handler for the code sample delete file."""
        assert isSet(data.url_project)

        try:
            id_value = int(data.request.POST['id'])
            code_sample = GSoCCodeSample.get_by_id(id_value, data.url_project)

            if not code_sample:
                raise exception.BadRequest(
                    message='Requested code sample not found')

            upload_of_work = code_sample.upload_of_work

            def txn():
                code_sample.delete()
                if upload_of_work:
                    # this is executed outside of transaction
                    upload_of_work.delete()

                if data.url_project.countCodeSamples() <= 1:
                    project = GSoCProject.get(data.url_project.key())
                    project.code_samples_submitted = False
                    project.put()

            db.run_in_transaction(txn)

            url = links.LINKER.userId(data.url_profile.key(),
                                      data.url_project.key().id(),
                                      url_names.GSOC_PROJECT_UPDATE)
            return http.HttpResponseRedirect(url)
        except KeyError:
            raise exception.BadRequest(
                message='id argument missing in POST data')
        except ValueError:
            raise exception.BadRequest(
                message='id argument in POST data is not a number')
예제 #29
0
def forAccount(account):
    """Retrieves the user entity for the specified account.

  If there is no user logged in, or they have no valid associated User
  entity, None is returned.
  """
    if not account:
        raise exception.BadRequest(message="Missing argument 'account'")

    account = accounts.normalizeAccount(account)

    q = user_model.User.all()
    q.filter('account', account)
    q.filter('status', 'valid')
    return q.get()
예제 #30
0
 def post(self, data, check, mutator):
     """Handles all POST calls for the TaskViewPage."""
     # TODO(nathaniel): What? Why is data.GET being read in this POST handler?
     if data.is_visible and 'reply' in data.GET:
         return self._postComment(data, check, mutator)
     elif 'button' in data.GET:
         return self._postButton(data)
     elif 'send_for_review' in data.GET:
         return self._postSendForReview(data)
     elif 'delete_submission' in data.GET:
         return self._postDeleteSubmission(data)
     elif 'work_file_submit' in data.POST or 'submit_work' in data.GET:
         return self._postSubmitWork(data, check, mutator)
     else:
         raise exception.BadRequest()