Exemplo n.º 1
0
def notify_bugtask_edited(modified_bugtask, event):
    """Notify CC'd subscribers of this bug that something has changed
    on this task.

    modified_bugtask must be an IBugTask. event must be an
    IObjectModifiedEvent.
    """
    bugtask_delta = event.object.getDelta(event.object_before_modification)
    bug_delta = BugDelta(bug=event.object.bug,
                         bugurl=canonical_url(event.object.bug),
                         bugtask_deltas=bugtask_delta,
                         user=IPerson(event.user))

    event_creator = IPerson(event.user)
    previous_subscribers = event.object_before_modification.bug_subscribers
    current_subscribers = event.object.bug_subscribers
    prev_subs_set = set(previous_subscribers)
    cur_subs_set = set(current_subscribers)
    new_subs = cur_subs_set.difference(prev_subs_set)

    add_bug_change_notifications(bug_delta,
                                 old_bugtask=event.object_before_modification,
                                 new_subscribers=new_subs)

    send_bug_details_to_new_bug_subscribers(event.object.bug,
                                            previous_subscribers,
                                            current_subscribers,
                                            event_creator=event_creator)
    def checkTransitionEvents(self, message, edited_fields, status_name):
        """Helper method to validate the events triggered from the transition.

        Check that an IObjectCreatedEvent event was sent when the message
        was created and that an IObjectModifiedEvent was also sent.
        The event object and edited_fields attribute are checked.
        """
        def failure_msg(msg):
            return "From status %s: %s" % (status_name, msg)

        self.assertTrue(
            len(self.collected_events) >= 1,
            failure_msg('failed to trigger an IObjectCreatedEvent'))
        created_event = self.collected_events[0]
        created_event_user = IPerson(created_event.user)
        self.assertTrue(
            IObjectCreatedEvent.providedBy(created_event),
            failure_msg("%s doesn't provide IObjectCreatedEvent" %
                        created_event))
        self.assertTrue(
            created_event.object == message,
            failure_msg("IObjectCreatedEvent contains wrong message"))
        self.assertTrue(
            created_event_user == message.owner,
            failure_msg(
                "%s != %s" %
                (created_event_user.displayname, message.owner.displayname)))

        self.assertTrue(
            len(self.collected_events) == 2,
            failure_msg('failed to trigger an IObjectModifiedEvent'))
        modified_event = self.collected_events[1]
        modified_event_user = IPerson(modified_event.user)
        self.assertTrue(
            IObjectModifiedEvent.providedBy(modified_event),
            failure_msg("%s doesn't provide IObjectModifiedEvent" %
                        modified_event))
        self.assertTrue(
            modified_event.object == self.question,
            failure_msg("IObjectModifiedEvent contains wrong question"))
        self.assertTrue(
            modified_event_user == message.owner,
            failure_msg(
                "%s != %s" %
                (modified_event_user.displayname, message.owner.displayname)))
        if edited_fields:
            self.assertTrue(
                set(modified_event.edited_fields) == set(edited_fields),
                failure_msg(
                    "%s != %s" %
                    (set(modified_event.edited_fields), set(edited_fields))))
Exemplo n.º 3
0
def notify_bug_watch_modified(modified_bug_watch, event):
    """Notify CC'd bug subscribers that a bug watch was edited.

    modified_bug_watch must be an IBugWatch. event must be an
    IObjectModifiedEvent.
    """
    old_watch = event.object_before_modification
    new_watch = event.object
    bug = new_watch.bug
    if old_watch.url == new_watch.url:
        # Nothing interesting was modified, don't record any changes.
        return
    bug.addChange(BugWatchRemoved(UTC_NOW, IPerson(event.user), old_watch))
    bug.addChange(BugWatchAdded(UTC_NOW, IPerson(event.user), new_watch))
Exemplo n.º 4
0
def branch_linked(bug, event):
    """Assign karma to the user who linked the bug to the branch."""
    from lp.code.interfaces.branch import IBranch
    if not IBranch.providedBy(event.other_object):
        return
    event.other_object.target.assignKarma(IPerson(event.user),
                                          'bugbranchcreated')
Exemplo n.º 5
0
def branch_merge_modified(proposal, event):
    """Assign karma to the user who approved or rejected the merge."""
    if event.user is None or isinstance(event.user, UnauthenticatedPrincipal):
        # Some modification events have no associated user context.  In
        # these cases there's no karma to assign.
        return

    if proposal.source_git_repository is not None:
        target = proposal.source_git_repository.namespace
    else:
        target = proposal.source_branch.target
    user = IPerson(event.user)
    old_status = event.object_before_modification.queue_status
    new_status = proposal.queue_status

    in_progress_states = (BranchMergeProposalStatus.WORK_IN_PROGRESS,
                          BranchMergeProposalStatus.NEEDS_REVIEW)

    if ((new_status == BranchMergeProposalStatus.CODE_APPROVED)
            and (old_status in (in_progress_states))):
        if user == proposal.registrant:
            target.assignKarma(user, 'branchmergeapprovedown')
        else:
            target.assignKarma(user, 'branchmergeapproved')
    elif ((new_status == BranchMergeProposalStatus.REJECTED)
          and (old_status in (in_progress_states))):
        if user == proposal.registrant:
            target.assignKarma(user, 'branchmergerejectedown')
        else:
            target.assignKarma(user, 'branchmergerejected')
    else:
        # Only care about approved and rejected right now.
        pass
Exemplo n.º 6
0
def merge_proposal_linked(bug, event):
    """Assign karma to the user who linked the bug to the merge proposal."""
    from lp.code.interfaces.branchmergeproposal import IBranchMergeProposal
    if not IBranchMergeProposal.providedBy(event.other_object):
        return
    event.other_object.target.assignKarma(IPerson(event.user),
                                          'bugbranchcreated')
Exemplo n.º 7
0
def bugtask_modified(bugtask, event):
    """Check changes made to <bugtask> and assign karma to user if needed."""
    user = IPerson(event.user)
    task_delta = event.object.getDelta(event.object_before_modification)

    if task_delta is None:
        return

    actionname_status_mapping = {
        BugTaskStatus.FIXRELEASED: 'bugfixed',
        BugTaskStatus.INVALID: 'bugrejected',
        BugTaskStatus.CONFIRMED: 'bugaccepted',
        BugTaskStatus.TRIAGED: 'bugaccepted',
    }

    if task_delta.status:
        new_status = task_delta.status['new']
        actionname = actionname_status_mapping.get(new_status)
        if actionname is not None:
            if actionname == 'bugfixed' and bugtask.assignee is not None:
                _assign_karma_using_bugtask_context(bugtask.assignee, bugtask,
                                                    actionname)
            else:
                _assign_karma_using_bugtask_context(user, bugtask, actionname)

    if task_delta.importance is not None:
        _assign_karma_using_bugtask_context(user, bugtask,
                                            'bugtaskimportancechanged')
Exemplo n.º 8
0
    def createPositiveResponse(self):
        """Create a positive assertion OpenIDResponse.

        This method should be called to create the response to
        successful checkid requests.

        If the trust root for the request is in openid_sreg_trustroots,
        then additional user information is included with the
        response.
        """
        assert self.account is not None, (
            'Must be logged in for positive OpenID response')
        assert self.openid_request is not None, (
            'No OpenID request to respond to.')

        if not self.isIdentityOwner():
            return self.createFailedResponse()

        if self.openid_request.idSelect():
            response = self.openid_request.answer(
                True, identity=self.user_identity_url)
        else:
            response = self.openid_request.answer(True)

        person = IPerson(self.account)
        sreg_fields = dict(nickname=person.name,
                           email=person.preferredemail.email,
                           fullname=self.account.displayname)
        sreg_request = SRegRequest.fromOpenIDRequest(self.openid_request)
        sreg_response = SRegResponse.extractResponse(sreg_request, sreg_fields)
        response.addExtension(sreg_response)

        return response
Exemplo n.º 9
0
    def test_unseen_identity(self):
        # When we get a positive assertion about an identity URL we've never
        # seen, we automatically register an account with that identity
        # because someone who registered on login.lp.net or login.u.c should
        # be able to login here without any further steps.
        identifier = u'4w7kmzU'
        account_set = getUtility(IAccountSet)
        self.assertRaises(
            LookupError, account_set.getByOpenIDIdentifier, identifier)
        openid_response = FakeOpenIDResponse(
            'http://testopenid.dev/+id/%s' % identifier, status=SUCCESS,
            email='*****@*****.**', full_name='Foo User')
        with SRegResponse_fromSuccessResponse_stubbed():
            view, html = self._createAndRenderView(openid_response)
        self.assertTrue(view.login_called)
        account = account_set.getByOpenIDIdentifier(identifier)
        self.assertIsNot(None, account)
        self.assertEquals(AccountStatus.ACTIVE, account.status)
        person = IPerson(account, None)
        self.assertIsNot(None, person)
        self.assertEquals('Foo User', person.displayname)
        self.assertEquals('*****@*****.**',
                          removeSecurityProxy(person.preferredemail).email)

        # We also update the last_write flag in the session, to make sure
        # further requests use the master DB and thus see the newly created
        # stuff.
        self.assertLastWriteIsSet(view.request)
def merge_proposal_modified(merge_proposal, event):
    """Notify branch subscribers when merge proposals are updated."""
    # Check the user.
    if event.user is None:
        return
    if isinstance(event.user, UnauthenticatedPrincipal):
        from_person = None
    else:
        from_person = IPerson(event.user)
    # If the merge proposal was work in progress, then we don't want to send
    # out an email as the needs review email will cover that.
    old_status = event.object_before_modification.queue_status
    if old_status == BranchMergeProposalStatus.WORK_IN_PROGRESS:
        # Unless the new status is merged.  If this occurs we really should
        # send out an email.
        if merge_proposal.queue_status != BranchMergeProposalStatus.MERGED:
            return
    # Create a delta of the changes.  If there are no changes to report, then
    # we're done.
    delta = BranchMergeProposalNoPreviewDiffDelta.construct(
        event.object_before_modification, merge_proposal)
    if delta is None:
        return
    changes = text_delta(delta, delta.delta_values, delta.new_values,
                         delta.interface)
    # Now create the job to send the email.
    getUtility(IMergeProposalUpdatedEmailJobSource).create(
        merge_proposal, changes, from_person)
Exemplo n.º 11
0
def notify_bugtask_deleted(bugtask, event):
    """A bugtask has been deleted (removed from a bug).

    bugtask must be in IBugTask. event must be anIObjectDeletedEvent.
    """
    bugtask.bug.addChange(BugTaskDeleted(UTC_NOW, IPerson(event.user),
                                         bugtask))
Exemplo n.º 12
0
def notify_specification_subscription_modified(specsub, event):
    """Notify a subscriber to a blueprint that their
    subscription has changed.
    """
    user = IPerson(event.user)
    spec = specsub.specification
    person = specsub.person
    # Only send a notification if the
    # subscription changed by someone else.
    if person == user:
        return
    subject = specification_notification_subject(spec)
    if specsub.essential:
        specsub_type = 'Participation essential'
    else:
        specsub_type = 'Participation non-essential'
    mailwrapper = MailWrapper(width=72)
    body = mailwrapper.format(
        'Your subscription to the blueprint '
        '%(blueprint_name)s - %(blueprint_title)s '
        'has changed to [%(specsub_type)s].\n\n'
        '--\n  %(blueprint_url)s' %
        {'blueprint_name': spec.name,
         'blueprint_title': spec.title,
         'specsub_type': specsub_type,
         'blueprint_url': canonical_url(spec)})
    for address in get_contact_email_addresses(person):
        simple_sendmail_from_person(user, address, subject, body)
Exemplo n.º 13
0
def send_branch_modified_notifications(branch, event):
    """Notify the related people that a branch has been modified."""
    user = IPerson(event.user)
    branch_delta = BranchDelta.construct(event.object_before_modification,
                                         branch, user)
    if branch_delta is None:
        return
    getUtility(IBranchModifiedMailJobSource).create(branch, user, branch_delta)
Exemplo n.º 14
0
def record_bug_added(bug, object_created_event):
    activity = getUtility(IBugActivitySet).new(bug=bug.id,
                                               datechanged=UTC_NOW,
                                               person=IPerson(
                                                   object_created_event.user),
                                               whatchanged="bug",
                                               message="added bug")
    bug.addCommentNotification(bug.initial_message, activity=activity)
Exemplo n.º 15
0
def record_cve_linked_to_bug(bug, event):
    """Record when a CVE is linked to a bug."""
    if not ICve.providedBy(event.other_object):
        return
    bug.addChange(
        CveLinkedToBug(when=None,
                       person=IPerson(event.user),
                       cve=event.other_object))
Exemplo n.º 16
0
def notify_bugtask_added(bugtask, event):
    """Notify CC'd list that this bug has been marked as needing fixing
    somewhere else.

    bugtask must be in IBugTask. event must be an
    IObjectModifiedEvent.
    """
    bugtask.bug.addChange(BugTaskAdded(UTC_NOW, IPerson(event.user), bugtask))
Exemplo n.º 17
0
def record_cve_unlinked_from_bug(bug, event):
    """Record when a CVE is unlinked from a bug."""
    if not ICve.providedBy(event.other_object):
        return
    bug.addChange(
        CveUnlinkedFromBug(when=None,
                           person=IPerson(event.user),
                           cve=event.other_object))
Exemplo n.º 18
0
def notify_bug_modified(bug, event):
    """Handle bug change events."""
    bug_delta = get_bug_delta(old_bug=event.object_before_modification,
                              new_bug=event.object,
                              user=IPerson(event.user))

    if bug_delta is not None:
        add_bug_change_notifications(bug_delta)
Exemplo n.º 19
0
def specification_update_lifecycle_status(spec, event):
    """Mark the specification as started and/or complete if appropriate.

    Does nothing if there is no user associated with the event.
    """
    if event.user is None:
        return
    spec.updateLifecycleStatus(IPerson(event.user))
Exemplo n.º 20
0
def faq_edited(faq, event):
    """Assign karma to user who edited a FAQ."""
    user = IPerson(event.user)
    old_faq = event.object_before_modification

    context = get_karma_context_parameters(faq.target)
    if old_faq.content != faq.content or old_faq.title != faq.title:
        user.assignKarma('faqedited', **context)
Exemplo n.º 21
0
def send_git_repository_modified_notifications(repository, event):
    """Notify the related people that a Git repository has been modified."""
    user = IPerson(event.user)
    repository_delta = GitRepositoryDelta.construct(
        event.object_before_modification, repository, user)
    if repository_delta is None:
        return
    getUtility(IGitRepositoryModifiedMailJobSource).create(
        repository, user, repository_delta)
Exemplo n.º 22
0
def record_merge_proposal_linked_to_bug(bug, event):
    """Record when a merge proposal is linked to a bug."""
    if not IBranchMergeProposal.providedBy(event.other_object):
        return
    bug.addChange(
        MergeProposalLinkedToBug(when=None,
                                 person=IPerson(event.user),
                                 merge_proposal=event.other_object,
                                 bug=event.object))
Exemplo n.º 23
0
def record_merge_proposal_unlinked_from_bug(bug, event):
    """Record when a merge proposal is unlinked from a bug."""
    if not IBranchMergeProposal.providedBy(event.other_object):
        return
    bug.addChange(
        MergeProposalUnlinkedFromBug(when=None,
                                     person=IPerson(event.user),
                                     merge_proposal=event.other_object,
                                     bug=event.object))
Exemplo n.º 24
0
def record_bugsubscription_added(bugsubscription_added, object_created_event):
    subscribed_user = bugsubscription_added.person
    if subscribed_user.visibility == PersonVisibility.PUBLIC:
        getUtility(IBugActivitySet).new(
            bug=bugsubscription_added.bug,
            datechanged=UTC_NOW,
            person=IPerson(object_created_event.user),
            whatchanged='bug',
            message='added subscriber %s' % subscribed_user.displayname)
Exemplo n.º 25
0
 def test_checkAuthenticated_for_full_fledged_account(self):
     # AuthorizationBase.checkAuthenticated should delegate to
     # checkAuthenticated() when the given account can be adapted
     # into an IPerson.
     full_fledged_account = self.factory.makePerson().account
     adapter = FakeSecurityAdapter()
     adapter.checkAuthenticated(IPerson(full_fledged_account))
     self.assertVectorEqual((1, adapter.checkAuthenticated.call_count),
                            (0, adapter.checkUnauthenticated.call_count))
Exemplo n.º 26
0
def send_branch_modified_notifications(branch, event):
    """Notify the related people that a branch has been modifed."""
    user = IPerson(event.user)
    branch_delta = BranchDelta.construct(event.object_before_modification,
                                         branch, user)
    if branch_delta is None:
        return
    mailer = BranchMailer.forBranchModified(branch, user, branch_delta)
    mailer.sendAll()
def expose_user_administered_teams_to_js(request,
                                         user,
                                         context,
                                         absoluteURL=absoluteURL):
    """Make the list of teams the user administers available to JavaScript."""
    # XXX: Robert Collins workaround multiple calls making this cause
    # timeouts: see bug 788510.
    objects = IJSONRequestCache(request).objects
    if 'administratedTeams' in objects:
        return
    info = []
    api_request = IWebServiceClientRequest(request)
    is_distro = IDistribution.providedBy(context)
    if is_distro:
        # If the context is a distro AND a bug supervisor is set then we only
        # allow subscriptions from members of the bug supervisor team.
        bug_supervisor = context.bug_supervisor
    else:
        bug_supervisor = None
    if user is not None:
        administrated_teams = set(user.administrated_teams)
        if administrated_teams:
            # Get this only if we need to.
            membership = set(user.teams_participated_in)
            # Only consider teams the user is both in and administers:
            #  If the user is not a member of the team itself, then
            # skip it, because structural subscriptions and their
            # filters can only be edited by the subscriber.
            # This can happen if the user is an owner but not a member.
            administers_and_in = membership.intersection(administrated_teams)
            list(
                getUtility(IPersonSet).getPrecachedPersonsFromIDs(
                    [team.id for team in administers_and_in],
                    need_preferred_email=True))

            # If the requester is the user, they're at least an admin in
            # all of these teams. Precache launchpad.(Limited)View so we
            # can see the necessary attributes.
            current_user = IPerson(get_current_principal(), None)
            if current_user is not None and user == current_user:
                for perm in ('launchpad.View', 'launchpad.LimitedView'):
                    precache_permission_for_objects(None, perm,
                                                    administers_and_in)

            for team in sorted(administers_and_in, key=attrgetter('name')):
                if (bug_supervisor is not None
                        and not team.inTeam(bug_supervisor)):
                    continue
                info.append({
                    'has_preferredemail': team.preferredemail is not None,
                    'link': absoluteURL(team, api_request),
                    'title': team.unique_displayname,
                    'url': canonical_url(team),
                })
    objects['administratedTeams'] = info
Exemplo n.º 28
0
def git_rule_modified(rule, event):
    """Update date_last_modified when a GitRule is modified.

    This method is registered as a subscriber to `IObjectModifiedEvent`
    events on Git repository rules.
    """
    if event.edited_fields:
        user = IPerson(event.user)
        getUtility(IGitActivitySet).logRuleChanged(
            event.object_before_modification, rule, user)
        removeSecurityProxy(rule).date_last_modified = UTC_NOW
Exemplo n.º 29
0
def question_modified(question, event):
    """Check changes made to <question> and assign karma to user if needed."""
    user = IPerson(event.user)
    old_question = event.object_before_modification

    if old_question.description != question.description:
        assignKarmaUsingQuestionContext(
            user, question, 'questiondescriptionchanged')

    if old_question.title != question.title:
        assignKarmaUsingQuestionContext(
            user, question, 'questiontitlechanged')
Exemplo n.º 30
0
def notify_bug_attachment_removed(bugattachment, event):
    """Notify that an attachment has been removed."""
    bug = bugattachment.bug
    bug_delta = BugDelta(bug=bug,
                         bugurl=canonical_url(bug),
                         user=IPerson(event.user),
                         attachment={
                             'old': bugattachment,
                             'new': None
                         })

    add_bug_change_notifications(bug_delta)