def execute(self, context):
     """Update the status of the merge proposal."""
     # Only accepts approved, and rejected for now.
     self._ensureNumberOfArguments()
     new_status = self.string_args[0].lower()
     # Grab the latest rev_id from the source branch.
     # This is what the browser code does right now.
     rev_id = context.merge_proposal.source_branch.last_scanned_id
     try:
         if new_status in ('approved', 'approve'):
             if context.vote is None:
                 context.vote = CodeReviewVote.APPROVE
             context.merge_proposal.approveBranch(context.user, rev_id)
         elif new_status in ('rejected', 'reject'):
             if context.vote is None:
                 context.vote = CodeReviewVote.DISAPPROVE
             context.merge_proposal.rejectBranch(context.user, rev_id)
         else:
             raise EmailProcessingError(
                 get_error_message(
                     'dbschema-command-wrong-argument.txt',
                     command_name=self.name,
                     arguments='approved, rejected',
                     example_argument='approved'))
     except (UserNotBranchReviewer, Unauthorized):
         raise EmailProcessingError(
             get_error_message(
                 'user-not-reviewer.txt',
                 error_templates=error_templates,
                 command_name=self.name,
                 target=context.merge_proposal.target_branch.bzr_identity))
    def execute(self, context):
        """Extract the vote and tags from the args."""
        if len(self.string_args) == 0:
            raise EmailProcessingError(
                get_error_message(
                    'num-arguments-mismatch.txt',
                    command_name='review',
                    num_arguments_expected='one or more',
                    num_arguments_got='0'))

        vote_string = self.string_args[0]
        vote_tag_list = self.string_args[1:]
        try:
            context.vote = CodeReviewVote.items[vote_string.upper()]
        except KeyError:
            # If the word doesn't match, check aliases that we allow.
            context.vote = self._vote_alias.get(vote_string)
            if context.vote is None:
                # Replace the _ with - in the names of the items.
                # Slightly easier to type and read.
                valid_votes = ', '.join(sorted(
                    v.name.lower().replace('_', '-')
                    for v in CodeReviewVote.items.items))
                raise EmailProcessingError(
                    get_error_message(
                        'dbschema-command-wrong-argument.txt',
                        command_name='review',
                        arguments=valid_votes,
                        example_argument='needs-fixing'))

        if len(vote_tag_list) > 0:
            context.vote_tags = ' '.join(vote_tag_list)
Beispiel #3
0
    def execute(self, bug, current_event):
        """See IEmailCommand."""
        if isinstance(bug, CreateBugParams):
            # Return the input because there is not yet a bug to
            # unsubscribe too.
            return bug, current_event

        string_args = list(self.string_args)
        if len(string_args) == 1:
            person = get_person_or_team(string_args.pop())
        elif len(string_args) == 0:
            # Subscribe the sender of the email.
            person = getUtility(ILaunchBag).user
        else:
            raise EmailProcessingError(
                get_error_message('unsubscribe-too-many-arguments.txt',
                                  error_templates=error_templates))

        if bug.isSubscribed(person):
            try:
                bug.unsubscribe(person, getUtility(ILaunchBag).user)
            except UserCannotUnsubscribePerson:
                raise EmailProcessingError(
                    get_error_message('user-cannot-unsubscribe.txt',
                                      error_templates=error_templates,
                                      person=person.displayname))
        if bug.isSubscribedToDupes(person):
            bug.unsubscribeFromDupes(person, person)

        return bug, current_event
    def execute(self, context):
        """Extract the vote and tags from the args."""
        if len(self.string_args) == 0:
            raise EmailProcessingError(
                get_error_message('num-arguments-mismatch.txt',
                                  command_name='review',
                                  num_arguments_expected='one or more',
                                  num_arguments_got='0'))

        vote_string = self.string_args[0]
        vote_tag_list = self.string_args[1:]
        try:
            context.vote = CodeReviewVote.items[vote_string.upper()]
        except KeyError:
            # If the word doesn't match, check aliases that we allow.
            context.vote = self._vote_alias.get(vote_string)
            if context.vote is None:
                # Replace the _ with - in the names of the items.
                # Slightly easier to type and read.
                valid_votes = ', '.join(
                    sorted(v.name.lower().replace('_', '-')
                           for v in CodeReviewVote.items.items))
                raise EmailProcessingError(
                    get_error_message('dbschema-command-wrong-argument.txt',
                                      command_name='review',
                                      arguments=valid_votes,
                                      example_argument='needs-fixing'))

        if len(vote_tag_list) > 0:
            context.vote_tags = ' '.join(vote_tag_list)
Beispiel #5
0
    def execute(self, bug, current_event):
        """See IEmailCommand."""
        if isinstance(bug, CreateBugParams):
            # Return the input because there is not yet a bug to
            # unsubscribe too.
            return bug, current_event

        string_args = list(self.string_args)
        if len(string_args) == 1:
            person = get_person_or_team(string_args.pop())
        elif len(string_args) == 0:
            # Subscribe the sender of the email.
            person = getUtility(ILaunchBag).user
        else:
            raise EmailProcessingError(
                get_error_message(
                    'unsubscribe-too-many-arguments.txt',
                    error_templates=error_templates))

        if bug.isSubscribed(person):
            try:
                bug.unsubscribe(person, getUtility(ILaunchBag).user)
            except UserCannotUnsubscribePerson:
                raise EmailProcessingError(
                    get_error_message(
                        'user-cannot-unsubscribe.txt',
                        error_templates=error_templates,
                        person=person.displayname))
        if bug.isSubscribedToDupes(person):
            bug.unsubscribeFromDupes(person, person)

        return bug, current_event
Beispiel #6
0
    def execute(self, bug, current_event):
        """See `IEmailCommand`."""
        # Tags are always lowercase.
        string_args = [arg.lower() for arg in self.string_args]
        if bug.tags is None:
            tags = []
        else:
            tags = list(bug.tags)
        for arg in string_args:
            # Are we adding or removing a tag?
            if arg.startswith('-'):
                remove = True
                tag = arg[1:]
            else:
                remove = False
                tag = arg
            # Tag must be a valid name.
            if not valid_name(tag):
                raise EmailProcessingError(
                    get_error_message('invalid-tag.txt',
                                      error_templates=error_templates,
                                      tag=tag))
            if remove:
                try:
                    tags.remove(tag)
                except ValueError:
                    raise EmailProcessingError(
                        get_error_message('unassigned-tag.txt',
                                          error_templates=error_templates,
                                          tag=tag))
            else:
                tags.append(arg)
        bug.tags = tags

        return bug, current_event
 def execute(self, context):
     """Update the status of the merge proposal."""
     # Only accepts approved, and rejected for now.
     self._ensureNumberOfArguments()
     new_status = self.string_args[0].lower()
     # Grab the latest rev_id from the source branch.
     # This is what the browser code does right now.
     rev_id = context.merge_proposal.source_branch.last_scanned_id
     try:
         if new_status in ('approved', 'approve'):
             if context.vote is None:
                 context.vote = CodeReviewVote.APPROVE
             context.merge_proposal.approveBranch(context.user, rev_id)
         elif new_status in ('rejected', 'reject'):
             if context.vote is None:
                 context.vote = CodeReviewVote.DISAPPROVE
             context.merge_proposal.rejectBranch(context.user, rev_id)
         else:
             raise EmailProcessingError(
                 get_error_message('dbschema-command-wrong-argument.txt',
                                   command_name=self.name,
                                   arguments='approved, rejected',
                                   example_argument='approved'))
     except (UserNotBranchReviewer, Unauthorized):
         raise EmailProcessingError(
             get_error_message(
                 'user-not-reviewer.txt',
                 error_templates=error_templates,
                 command_name=self.name,
                 target=context.merge_proposal.target_branch.bzr_identity))
Beispiel #8
0
    def execute(self, parsed_msg, filealias):
        """See IBugEmailCommand."""
        self._ensureNumberOfArguments()
        bugid = self.string_args[0]

        if bugid == 'new':
            message = getUtility(IMessageSet).fromEmail(
                parsed_msg.as_string(),
                owner=getUtility(ILaunchBag).user,
                filealias=filealias,
                parsed_message=parsed_msg)
            description = message.text_contents
            if description.strip() == '':
                # The report for a new bug must contain an affects command,
                # since the bug must have at least one task
                raise EmailProcessingError(get_error_message(
                    'no-affects-target-on-submit.txt',
                    error_templates=error_templates),
                                           stop_processing=True)

            # Check the message validator.
            validator = IBugAddForm['comment'].validate
            try:
                validator(description)
            except TooLong:
                raise EmailProcessingError(
                    'The description is too long. If you have lots of '
                    'text to add, use an attachment instead.',
                    stop_processing=True)
            except ValidationError as e:
                # More a just in case than any real expectation of getting
                # something.
                raise EmailProcessingError(str(e), stop_processing=True)

            params = CreateBugParams(msg=message,
                                     title=message.title,
                                     owner=getUtility(ILaunchBag).user)
            return params, None
        else:
            try:
                bugid = int(bugid)
            except ValueError:
                raise EmailProcessingError(
                    get_error_message('bug-argument-mismatch.txt',
                                      error_templates=error_templates))

            try:
                bug = getUtility(IBugSet).get(bugid)
            except NotFoundError:
                bug = None
            if bug is None or not check_permission('launchpad.View', bug):
                raise EmailProcessingError(
                    get_error_message('no-such-bug.txt',
                                      error_templates=error_templates,
                                      bug_id=bugid))
            return bug, None
Beispiel #9
0
    def execute(self, context, current_event):
        """See IEmailCommand."""
        if isinstance(context, CreateBugParams):
            # No one intentially reports a duplicate bug. Bug email commands
            # support CreateBugParams, so in this case, just return.
            return context, current_event
        self._ensureNumberOfArguments()
        [bug_id] = self.string_args

        if bug_id != 'no':
            try:
                bug = getUtility(IBugSet).getByNameOrID(bug_id)
            except NotFoundError:
                raise EmailProcessingError(
                    get_error_message(
                        'no-such-bug.txt',
                        error_templates=error_templates,
                        bug_id=bug_id))
        else:
            # 'no' is a special value for unmarking a bug as a duplicate.
            bug = None

        duplicate_field = IBug['duplicateof'].bind(context)
        try:
            duplicate_field.validate(bug)
        except ValidationError as error:
            raise EmailProcessingError(error.doc())

        context_snapshot = Snapshot(
            context, providing=providedBy(context))
        context.markAsDuplicate(bug)
        current_event = ObjectModifiedEvent(
            context, context_snapshot, 'duplicateof')
        notify(current_event)
        return bug, current_event
Beispiel #10
0
    def execute(self, context, current_event):
        """See IEmailCommand."""
        if isinstance(context, CreateBugParams):
            # No one intentially reports a duplicate bug. Bug email commands
            # support CreateBugParams, so in this case, just return.
            return context, current_event
        self._ensureNumberOfArguments()
        [bug_id] = self.string_args

        if bug_id != 'no':
            try:
                bug = getUtility(IBugSet).getByNameOrID(bug_id)
            except NotFoundError:
                raise EmailProcessingError(
                    get_error_message('no-such-bug.txt',
                                      error_templates=error_templates,
                                      bug_id=bug_id))
        else:
            # 'no' is a special value for unmarking a bug as a duplicate.
            bug = None

        duplicate_field = IBug['duplicateof'].bind(context)
        try:
            duplicate_field.validate(bug)
        except ValidationError as error:
            raise EmailProcessingError(error.doc())

        context_snapshot = Snapshot(context, providing=providedBy(context))
        context.markAsDuplicate(bug)
        current_event = ObjectModifiedEvent(context, context_snapshot,
                                            'duplicateof')
        notify(current_event)
        return bug, current_event
    def process(self, mail, email_addr, file_alias):
        """Process an email for the code domain.

        Emails may be converted to CodeReviewComments, and / or
        deferred to jobs to create BranchMergeProposals.
        """
        if email_addr.startswith('merge@'):
            body = get_error_message('mergedirectivenotsupported.txt')
            simple_sendmail(config.canonical.noreply_from_address,
                            [mail.get('from')],
                            'Merge directive not supported.', body)
        else:
            try:
                return self.processComment(mail, email_addr, file_alias)
            except AssertionError:
                body = get_error_message('messagemissingsubject.txt')
                simple_sendmail('*****@*****.**', [mail.get('from')],
                                'Error Creating Merge Proposal', body)
                return True
Beispiel #12
0
    def execute(self, bug, current_event):
        """See IEmailCommand."""
        if bug is None:
            raise EmailProcessingError(get_error_message(
                'command-with-no-bug.txt', error_templates=error_templates),
                                       stop_processing=True)

        # Do a manual control of the number of arguments, in order to
        # provide a better error message than the default one.
        if len(self.string_args) > 1:
            raise EmailProcessingError(
                get_error_message('summary-too-many-arguments.txt',
                                  error_templates=error_templates))

        if isinstance(bug, CreateBugParams):
            bug.title = self.string_args[0]
            return bug, current_event

        return EditEmailCommand.execute(self, bug, current_event)
    def process(self, mail, email_addr, file_alias):
        """Process an email for the code domain.

        Emails may be converted to CodeReviewComments, and / or
        deferred to jobs to create BranchMergeProposals.
        """
        if email_addr.startswith('merge@'):
            body = get_error_message('mergedirectivenotsupported.txt')
            simple_sendmail(
                config.canonical.noreply_from_address, [mail.get('from')],
                'Merge directive not supported.', body)
        else:
            try:
                return self.processComment(mail, email_addr, file_alias)
            except AssertionError:
                body = get_error_message('messagemissingsubject.txt')
                simple_sendmail('*****@*****.**',
                    [mail.get('from')],
                    'Error Creating Merge Proposal', body)
                return True
Beispiel #14
0
def authenticateEmail(mail, signature_timestamp_checker=None):
    """Authenticates an email by verifying the PGP signature.

    The mail is expected to be an ISignedMessage.

    If this completes, it will set the current security principal to be the
    message sender.

    :param signature_timestamp_checker: This callable is
        passed the message signature timestamp, and it can raise an exception
        if it dislikes it (for example as a replay attack.)  This parameter is
        intended for use in tests.  If None, ensure_sane_signature_timestamp
        is used.
    """

    log = logging.getLogger('process-mail')
    authutil = getUtility(IPlacelessAuthUtility)

    principal, dkim_trusted_address = _getPrincipalByDkim(mail)
    if dkim_trusted_address is None:
        from_addr = parseaddr(mail['From'])[1]
        try:
            principal = authutil.getPrincipalByLogin(from_addr)
        except TypeError:
            # The email isn't valid, so don't authenticate
            principal = None

    if principal is None:
        setupInteraction(authutil.unauthenticatedPrincipal())
        return None

    person = IPerson(principal, None)
    if person.account_status != AccountStatus.ACTIVE:
        raise InactiveAccount("Mail from a user with an inactive account.")

    if dkim_trusted_address:
        log.debug('accepting dkim strongly authenticated mail')
        setupInteraction(principal, dkim_trusted_address)
    else:
        log.debug("attempt gpg authentication for %r" % person)
        principal = _gpgAuthenticateEmail(mail, principal, person,
                                          signature_timestamp_checker)

    if (IWeaklyAuthenticatedPrincipal.providedBy(principal)
            and person.require_strong_email_authentication):
        import_url = canonical_url(getUtility(ILaunchBag).user,
                                   view_name='+editpgpkeys')
        error_message = get_error_message('person-requires-signature.txt',
                                          import_url=import_url)
        raise IncomingEmailError(error_message)

    return principal
Beispiel #15
0
    def execute(self, context, current_event):
        """See `IEmailCommand`.

        Much of this method was lifted from
        `EditEmailCommand.execute`.
        """
        # Parse args.
        self._ensureNumberOfArguments()
        [security_flag] = self.string_args
        if security_flag == 'yes':
            security_related = True
        elif security_flag == 'no':
            security_related = False
        else:
            raise EmailProcessingError(
                get_error_message(
                    'security-parameter-mismatch.txt',
                    error_templates=error_templates),
                stop_processing=True)

        if isinstance(context, CreateBugParams):
            if security_related:
                context.information_type = InformationType.PRIVATESECURITY
            return context, current_event

        # Take a snapshot.
        edited = False
        edited_fields = set()
        if IObjectModifiedEvent.providedBy(current_event):
            context_snapshot = current_event.object_before_modification
            edited_fields.update(current_event.edited_fields)
        else:
            context_snapshot = Snapshot(
                context, providing=providedBy(context))

        # Apply requested changes.
        user = getUtility(ILaunchBag).user
        if security_related:
            if context.setPrivate(True, user):
                edited = True
                edited_fields.add('private')
        if context.security_related != security_related:
            context.setSecurityRelated(security_related, user)
            edited = True
            edited_fields.add('security_related')

        # Update the current event.
        if edited and not IObjectCreatedEvent.providedBy(current_event):
            current_event = ObjectModifiedEvent(
                context, context_snapshot, list(edited_fields))

        return context, current_event
Beispiel #16
0
    def execute(self, bug, current_event):
        """See IEmailCommand."""
        if bug is None:
            raise EmailProcessingError(
                get_error_message(
                    'command-with-no-bug.txt',
                    error_templates=error_templates),
                stop_processing=True)

        # Do a manual control of the number of arguments, in order to
        # provide a better error message than the default one.
        if len(self.string_args) > 1:
            raise EmailProcessingError(
                get_error_message(
                    'summary-too-many-arguments.txt',
                    error_templates=error_templates))

        if isinstance(bug, CreateBugParams):
            bug.title = self.string_args[0]
            return bug, current_event

        return EditEmailCommand.execute(self, bug, current_event)
Beispiel #17
0
    def execute(self, context, current_event):
        """See `IEmailCommand`.

        Much of this method was lifted from
        `EditEmailCommand.execute`.
        """
        # Parse args.
        self._ensureNumberOfArguments()
        [security_flag] = self.string_args
        if security_flag == 'yes':
            security_related = True
        elif security_flag == 'no':
            security_related = False
        else:
            raise EmailProcessingError(get_error_message(
                'security-parameter-mismatch.txt',
                error_templates=error_templates),
                                       stop_processing=True)

        if isinstance(context, CreateBugParams):
            if security_related:
                context.information_type = InformationType.PRIVATESECURITY
            return context, current_event

        # Take a snapshot.
        edited = False
        edited_fields = set()
        if IObjectModifiedEvent.providedBy(current_event):
            context_snapshot = current_event.object_before_modification
            edited_fields.update(current_event.edited_fields)
        else:
            context_snapshot = Snapshot(context, providing=providedBy(context))

        # Apply requested changes.
        user = getUtility(ILaunchBag).user
        if security_related:
            if context.setPrivate(True, user):
                edited = True
                edited_fields.add('private')
        if context.security_related != security_related:
            context.setSecurityRelated(security_related, user)
            edited = True
            edited_fields.add('security_related')

        # Update the current event.
        if edited and not IObjectCreatedEvent.providedBy(current_event):
            current_event = ObjectModifiedEvent(context, context_snapshot,
                                                list(edited_fields))

        return context, current_event
Beispiel #18
0
    def _ensureNumberOfArguments(self):
        """Check that the number of arguments is correct.

        Raise an EmailProcessingError
        """
        if self._numberOfArguments is not None:
            num_arguments_got = len(self.string_args)
            if self._numberOfArguments != num_arguments_got:
                raise EmailProcessingError(
                    get_error_message(
                        'num-arguments-mismatch.txt',
                        command_name=self.name,
                        num_arguments_expected=self._numberOfArguments,
                        num_arguments_got=num_arguments_got))
Beispiel #19
0
    def execute(self, bug, current_event):
        """See `IEmailCommand`."""
        # Tags are always lowercase.
        string_args = [arg.lower() for arg in self.string_args]
        if bug.tags is None:
            tags = []
        else:
            tags = list(bug.tags)
        for arg in string_args:
            # Are we adding or removing a tag?
            if arg.startswith('-'):
                remove = True
                tag = arg[1:]
            else:
                remove = False
                tag = arg
            # Tag must be a valid name.
            if not valid_name(tag):
                raise EmailProcessingError(
                    get_error_message(
                        'invalid-tag.txt',
                        error_templates=error_templates,
                        tag=tag))
            if remove:
                try:
                    tags.remove(tag)
                except ValueError:
                    raise EmailProcessingError(
                        get_error_message(
                            'unassigned-tag.txt',
                            error_templates=error_templates,
                            tag=tag))
            else:
                tags.append(arg)
        bug.tags = tags

        return bug, current_event
Beispiel #20
0
    def execute(self, context, current_event):
        """See `IEmailCommand`. Much of this method has been lifted from
        `EditEmailCommand.execute`.
        """
        # Parse args.
        self._ensureNumberOfArguments()
        private_arg = self.string_args[0]
        if private_arg == 'yes':
            private = True
        elif private_arg == 'no':
            private = False
        else:
            raise EmailProcessingError(
                get_error_message(
                    'private-parameter-mismatch.txt',
                    error_templates=error_templates),
                stop_processing=True)

        if isinstance(context, CreateBugParams):
            if private:
                # "private yes" forces it to Private if it isn't already.
                if (context.information_type is None
                    or context.information_type in PUBLIC_INFORMATION_TYPES):
                    context.information_type = InformationType.USERDATA
            elif context.information_type != InformationType.PRIVATESECURITY:
                # "private no" forces it to Public, except we always
                # force new security bugs to be private.
                context.information_type = InformationType.PUBLIC
            return context, current_event

        # Snapshot.
        edited_fields = set()
        if IObjectModifiedEvent.providedBy(current_event):
            context_snapshot = current_event.object_before_modification
            edited_fields.update(current_event.edited_fields)
        else:
            context_snapshot = Snapshot(
                context, providing=providedBy(context))

        # Apply requested changes.
        edited = context.setPrivate(private, getUtility(ILaunchBag).user)

        # Update the current event.
        if edited and not IObjectCreatedEvent.providedBy(current_event):
            edited_fields.add('private')
            current_event = ObjectModifiedEvent(
                context, context_snapshot, list(edited_fields))

        return context, current_event
Beispiel #21
0
def _send_email_oops(trans, log, mail, error_msg, file_alias_url):
    """Handle an error that generates an oops.

    It does the following:
        * records an OOPS with error_msg and file_alias_url
        * commits the current transaction to ensure that the
            message gets sent
    """
    log.info('error processing mail: %s' % (error_msg, ))
    oops_id = report_oops(file_alias_url=file_alias_url, error_msg=error_msg)
    log.info('oops %s' % (oops_id, ))
    send_process_error_notification(
        mail['From'], 'Submit Request Failure',
        get_error_message('oops.txt', oops_id=oops_id), mail)
    trans.commit()
    def parseReviewRequest(klass, op_name, string_args):
        if len(string_args) == 0:
            raise EmailProcessingError(
                get_error_message('num-arguments-mismatch.txt',
                                  command_name=op_name,
                                  num_arguments_expected='one or more',
                                  num_arguments_got='0'))

        # Pop the first arg as the reviewer.
        reviewer = get_person_or_team(string_args.pop(0))
        if len(string_args) > 0:
            review_tags = ' '.join(string_args)
        else:
            review_tags = None
        return (reviewer, review_tags)
    def parseReviewRequest(klass, op_name, string_args):
        if len(string_args) == 0:
            raise EmailProcessingError(
                get_error_message(
                    'num-arguments-mismatch.txt',
                    command_name=op_name,
                    num_arguments_expected='one or more',
                    num_arguments_got='0'))

        # Pop the first arg as the reviewer.
        reviewer = get_person_or_team(string_args.pop(0))
        if len(string_args) > 0:
            review_tags = ' '.join(string_args)
        else:
            review_tags = None
        return (reviewer, review_tags)
Beispiel #24
0
    def _ensureNumberOfArguments(self):
        """Check that the number of arguments is correct.

        Raise an EmailProcessingError
        """
        if self._numberOfArguments is not None:
            num_arguments_got = len(self.string_args)
            if self._numberOfArguments != num_arguments_got:
                raise EmailProcessingError(
                    get_error_message(
                        "num-arguments-mismatch.txt",
                        command_name=self.name,
                        num_arguments_expected=self._numberOfArguments,
                        num_arguments_got=num_arguments_got,
                    )
                )
Beispiel #25
0
    def execute(self, context, current_event):
        """See `IEmailCommand`. Much of this method has been lifted from
        `EditEmailCommand.execute`.
        """
        # Parse args.
        self._ensureNumberOfArguments()
        private_arg = self.string_args[0]
        if private_arg == 'yes':
            private = True
        elif private_arg == 'no':
            private = False
        else:
            raise EmailProcessingError(get_error_message(
                'private-parameter-mismatch.txt',
                error_templates=error_templates),
                                       stop_processing=True)

        if isinstance(context, CreateBugParams):
            if private:
                # "private yes" forces it to Private if it isn't already.
                if (context.information_type is None or
                        context.information_type in PUBLIC_INFORMATION_TYPES):
                    context.information_type = InformationType.USERDATA
            elif context.information_type != InformationType.PRIVATESECURITY:
                # "private no" forces it to Public, except we always
                # force new security bugs to be private.
                context.information_type = InformationType.PUBLIC
            return context, current_event

        # Snapshot.
        edited_fields = set()
        if IObjectModifiedEvent.providedBy(current_event):
            context_snapshot = current_event.object_before_modification
            edited_fields.update(current_event.edited_fields)
        else:
            context_snapshot = Snapshot(context, providing=providedBy(context))

        # Apply requested changes.
        edited = context.setPrivate(private, getUtility(ILaunchBag).user)

        # Update the current event.
        if edited and not IObjectCreatedEvent.providedBy(current_event):
            edited_fields.add('private')
            current_event = ObjectModifiedEvent(context, context_snapshot,
                                                list(edited_fields))

        return context, current_event
Beispiel #26
0
def _send_email_oops(trans, log, mail, error_msg, file_alias_url):
    """Handle an error that generates an oops.

    It does the following:
        * records an OOPS with error_msg and file_alias_url
        * commits the current transaction to ensure that the
            message gets sent
    """
    log.info('error processing mail: %s' % (error_msg,))
    oops_id = report_oops(
        file_alias_url=file_alias_url,
        error_msg=error_msg)
    log.info('oops %s' % (oops_id,))
    send_process_error_notification(
        mail['From'],
        'Submit Request Failure',
        get_error_message('oops.txt', oops_id=oops_id),
        mail)
    trans.commit()
Beispiel #27
0
    def execute(self, bug, current_event):
        """See IEmailCommand."""
        string_args = list(self.string_args)
        # preserve compatibility with the original command that let you
        # specify a subscription type
        if len(string_args) == 2:
            # Remove the subscription_name
            string_args.pop()

        user = getUtility(ILaunchBag).user

        if len(string_args) == 1:
            person = get_person_or_team(string_args.pop())
        elif len(string_args) == 0:
            # Subscribe the sender of the email.
            person = user
        else:
            raise EmailProcessingError(
                get_error_message(
                    'subscribe-too-many-arguments.txt',
                    error_templates=error_templates))

        if isinstance(bug, CreateBugParams):
            if len(bug.subscribers) == 0:
                bug.subscribers = [person]
            else:
                bug.subscribers.append(person)
            return bug, current_event

        if bug.isSubscribed(person):
            # but we still need to find the subscription
            for bugsubscription in bug.subscriptions:
                if bugsubscription.person == person:
                    break

        else:
            bugsubscription = bug.subscribe(person, user)
            notify(ObjectCreatedEvent(bugsubscription))

        return bug, current_event
Beispiel #28
0
    def convertArguments(self, context):
        """See EmailCommand."""
        item_name = self.string_args[0]
        dbschema = self.dbschema
        try:
            dbitem = dbschema.items[item_name.upper()]
        except KeyError:
            dbitem = None

        if dbitem is None or dbitem.name == 'UNKNOWN':
            possible_items = [
                item.name.lower() for item in dbschema.items
                if item.name != 'UNKNOWN'
            ]
            possible_values = ', '.join(possible_items)
            raise EmailProcessingError(
                get_error_message('dbschema-command-wrong-argument.txt',
                                  command_name=self.name,
                                  arguments=possible_values,
                                  example_argument=possible_items[0]))

        return {self.name: dbitem}
Beispiel #29
0
    def execute(self, bug, current_event):
        """See IEmailCommand."""
        string_args = list(self.string_args)
        # preserve compatibility with the original command that let you
        # specify a subscription type
        if len(string_args) == 2:
            # Remove the subscription_name
            string_args.pop()

        user = getUtility(ILaunchBag).user

        if len(string_args) == 1:
            person = get_person_or_team(string_args.pop())
        elif len(string_args) == 0:
            # Subscribe the sender of the email.
            person = user
        else:
            raise EmailProcessingError(
                get_error_message('subscribe-too-many-arguments.txt',
                                  error_templates=error_templates))

        if isinstance(bug, CreateBugParams):
            if len(bug.subscribers) == 0:
                bug.subscribers = [person]
            else:
                bug.subscribers.append(person)
            return bug, current_event

        if bug.isSubscribed(person):
            # but we still need to find the subscription
            for bugsubscription in bug.subscriptions:
                if bugsubscription.person == person:
                    break

        else:
            bugsubscription = bug.subscribe(person, user)
            notify(ObjectCreatedEvent(bugsubscription))

        return bug, current_event
Beispiel #30
0
    def convertArguments(self, context):
        """See EmailCommand."""
        item_name = self.string_args[0]
        dbschema = self.dbschema
        try:
            dbitem = dbschema.items[item_name.upper()]
        except KeyError:
            dbitem = None

        if dbitem is None or dbitem.name == 'UNKNOWN':
            possible_items = [
                item.name.lower() for item in dbschema.items
                if item.name != 'UNKNOWN']
            possible_values = ', '.join(possible_items)
            raise EmailProcessingError(
                    get_error_message(
                        'dbschema-command-wrong-argument.txt',
                         command_name=self.name,
                         arguments=possible_values,
                         example_argument=possible_items[0]))

        return {self.name: dbitem}
Beispiel #31
0
 def execute(self, context, current_event):
     raise EmailProcessingError(
             get_error_message(
                 'bug-importance.txt',
                 error_templates=error_templates,
                 argument=self.name))
Beispiel #32
0
 def execute(self, context, current_event):
     raise EmailProcessingError(
         get_error_message('bug-importance.txt',
                           error_templates=error_templates,
                           argument=self.name))
Beispiel #33
0
 def handleNoDefaultAffectsTarget(self, bug):
     raise IncomingEmailError(
         get_error_message('no-default-affects.txt',
                           error_templates=error_templates,
                           bug_id=bug.id,
                           nr_of_bugtasks=len(bug.bugtasks)))
Beispiel #34
0
 def handleNoAffectsTarget(self):
     transaction.abort()
     raise IncomingEmailError(
         get_error_message('no-affects-target-on-submit.txt',
                           error_templates=error_templates))
Beispiel #35
0
    def execute(self, parsed_msg, filealias):
        """See IBugEmailCommand."""
        self._ensureNumberOfArguments()
        bugid = self.string_args[0]

        if bugid == 'new':
            message = getUtility(IMessageSet).fromEmail(
                parsed_msg.as_string(),
                owner=getUtility(ILaunchBag).user,
                filealias=filealias,
                parsed_message=parsed_msg)
            description = message.text_contents
            if description.strip() == '':
                # The report for a new bug must contain an affects command,
                # since the bug must have at least one task
                raise EmailProcessingError(
                    get_error_message(
                        'no-affects-target-on-submit.txt',
                        error_templates=error_templates),
                    stop_processing=True)

            # Check the message validator.
            validator = IBugAddForm['comment'].validate
            try:
                validator(description)
            except TooLong:
                raise EmailProcessingError(
                    'The description is too long. If you have lots of '
                    'text to add, use an attachment instead.',
                    stop_processing=True)
            except ValidationError as e:
                # More a just in case than any real expectation of getting
                # something.
                raise EmailProcessingError(
                    str(e),
                    stop_processing=True)

            params = CreateBugParams(
                msg=message, title=message.title,
                owner=getUtility(ILaunchBag).user)
            return params, None
        else:
            try:
                bugid = int(bugid)
            except ValueError:
                raise EmailProcessingError(
                    get_error_message(
                        'bug-argument-mismatch.txt',
                        error_templates=error_templates))

            try:
                bug = getUtility(IBugSet).get(bugid)
            except NotFoundError:
                bug = None
            if bug is None or not check_permission('launchpad.View', bug):
                raise EmailProcessingError(
                    get_error_message(
                        'no-such-bug.txt',
                        error_templates=error_templates,
                        bug_id=bugid))
            return bug, None
Beispiel #36
0
 def handleNoAffectsTarget(self):
     transaction.abort()
     raise IncomingEmailError(
         get_error_message(
             'no-affects-target-on-submit.txt',
             error_templates=error_templates))
Beispiel #37
0
    def execute(self, bug, bug_event):
        """See IEmailCommand."""
        if bug is None:
            raise EmailProcessingError(
                get_error_message(
                    'command-with-no-bug.txt',
                    error_templates=error_templates),
                stop_processing=True)

        string_args = list(self.string_args)
        try:
            path = string_args.pop(0)
        except IndexError:
            raise EmailProcessingError(
                get_error_message(
                    'affects-no-arguments.txt',
                    error_templates=error_templates),
                stop_processing=True)
        try:
            bug_target = self.getBugTarget(path)
        except BugTargetNotFound as error:
            raise EmailProcessingError(unicode(error), stop_processing=True)
        event = None

        if isinstance(bug, CreateBugParams):
            # Enough information has been gathered to create a new bug.
            # If a series task is requested, create the non-series
            # equivalent here. The series will be nominated/targeted in
            # the remainder of the method.
            if ISeriesBugTarget.providedBy(bug_target):
                bug.target = bug_target.bugtarget_parent
            else:
                bug.target = bug_target
            bug, bug_event = getUtility(IBugSet).createBug(
                bug, notify_event=False)
            event = ObjectCreatedEvent(bug.bugtasks[0])
            # Continue because the bug_target may be a subordinate bugtask.

        bugtask = bug.getBugTask(bug_target)
        if (bugtask is None and
            IDistributionSourcePackage.providedBy(bug_target)):
            # If there's a distribution task with no source package, use
            # that one.
            bugtask = bug.getBugTask(bug_target.distribution)
            if bugtask is not None:
                bugtask_before_edit = Snapshot(
                    bugtask, providing=IBugTask)
                bugtask.transitionToTarget(
                    bug_target, getUtility(ILaunchBag).user)
                event = ObjectModifiedEvent(
                    bugtask, bugtask_before_edit, ['sourcepackagename'])

        if bugtask is None:
            try:
                bugtask = self._create_bug_task(bug, bug_target)
            except IllegalTarget as e:
                raise EmailProcessingError(
                    get_error_message(
                        'cannot-add-task.txt',
                        error_templates=error_templates,
                        bug_id=bug.id,
                        target_name=bug_target.name, reason=e[0]),
                    stop_processing=True)
            event = ObjectCreatedEvent(bugtask)

        return bugtask, event, bug_event
Beispiel #38
0
    def execute(self, bug, bug_event):
        """See IEmailCommand."""
        if bug is None:
            raise EmailProcessingError(get_error_message(
                'command-with-no-bug.txt', error_templates=error_templates),
                                       stop_processing=True)

        string_args = list(self.string_args)
        try:
            path = string_args.pop(0)
        except IndexError:
            raise EmailProcessingError(get_error_message(
                'affects-no-arguments.txt', error_templates=error_templates),
                                       stop_processing=True)
        try:
            bug_target = self.getBugTarget(path)
        except BugTargetNotFound as error:
            raise EmailProcessingError(unicode(error), stop_processing=True)
        event = None

        if isinstance(bug, CreateBugParams):
            # Enough information has been gathered to create a new bug.
            # If a series task is requested, create the non-series
            # equivalent here. The series will be nominated/targeted in
            # the remainder of the method.
            if ISeriesBugTarget.providedBy(bug_target):
                bug.target = bug_target.bugtarget_parent
            else:
                bug.target = bug_target
            bug, bug_event = getUtility(IBugSet).createBug(bug,
                                                           notify_event=False)
            event = ObjectCreatedEvent(bug.bugtasks[0])
            # Continue because the bug_target may be a subordinate bugtask.

        bugtask = bug.getBugTask(bug_target)
        if (bugtask is None
                and IDistributionSourcePackage.providedBy(bug_target)):
            # If there's a distribution task with no source package, use
            # that one.
            bugtask = bug.getBugTask(bug_target.distribution)
            if bugtask is not None:
                bugtask_before_edit = Snapshot(bugtask, providing=IBugTask)
                bugtask.transitionToTarget(bug_target,
                                           getUtility(ILaunchBag).user)
                event = ObjectModifiedEvent(bugtask, bugtask_before_edit,
                                            ['sourcepackagename'])

        if bugtask is None:
            try:
                bugtask = self._create_bug_task(bug, bug_target)
            except IllegalTarget as e:
                raise EmailProcessingError(get_error_message(
                    'cannot-add-task.txt',
                    error_templates=error_templates,
                    bug_id=bug.id,
                    target_name=bug_target.name,
                    reason=e[0]),
                                           stop_processing=True)
            event = ObjectCreatedEvent(bugtask)

        return bugtask, event, bug_event
Beispiel #39
0
 def handleNoDefaultAffectsTarget(self, bug):
     raise IncomingEmailError(get_error_message(
         'no-default-affects.txt',
         error_templates=error_templates,
         bug_id=bug.id,
         nr_of_bugtasks=len(bug.bugtasks)))