def add(self, persons, reason, header):
        """See `INotificationRecipientSet`."""
        from zope.security.proxy import removeSecurityProxy
        from lp.registry.model.person import get_recipients
        if IPerson.providedBy(persons):
            persons = [persons]

        for person in persons:
            assert IPerson.providedBy(person), (
                'You can only add() an IPerson: %r' % person)
            # If the person already has a rationale, keep the first one.
            if person in self._personToRationale:
                continue
            self._personToRationale[person] = reason, header
            for receiving_person in get_recipients(person):
                # Bypass zope's security because IEmailAddress.email is not
                # public.
                preferred_email = removeSecurityProxy(
                    receiving_person).preferredemail
                email = str(preferred_email.email)
                self._receiving_people.add((email, receiving_person))
                old_person = self._emailToPerson.get(email)
                # Only associate this email to the person, if there was
                # no association or if the previous one was to a team and
                # the newer one is to a person.
                if (old_person is None
                    or (old_person.is_team and not person.is_team)):
                    self._emailToPerson[email] = person
Beispiel #2
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)
def get_string_representation(obj):
    """Returns a string representation of an object.

    It can be used as oldvalue and newvalue.

    Returns None if no representation can be made.
    """
    if IPerson.providedBy(obj):
        return obj.name
    if IBug.providedBy(obj):
        return str(obj.id)
    elif ISourcePackageRelease.providedBy(obj):
        return "%s %s" % (obj.sourcepackagename.name, obj.version)
    elif IProductRelease.providedBy(obj):
        return "%s %s" % (obj.product.name, obj.version)
    elif IMilestone.providedBy(obj):
        return obj.name
    elif isinstance(obj, BaseItem):
        return obj.title
    elif isinstance(obj, basestring):
        return obj
    elif isinstance(obj, bool):
        return str(obj)
    else:
        return None
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))
Beispiel #5
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
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)
Beispiel #7
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.assertEqual(AccountStatus.ACTIVE, account.status)
        person = IPerson(account, None)
        self.assertIsNot(None, person)
        self.assertEqual('Foo User', person.displayname)
        self.assertEqual('*****@*****.**',
                         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 get_string_representation(obj):
    """Returns a string representation of an object.

    It can be used as oldvalue and newvalue.

    Returns None if no representation can be made.
    """
    if IPerson.providedBy(obj):
        return obj.name
    if IBug.providedBy(obj):
        return str(obj.id)
    elif ISourcePackageRelease.providedBy(obj):
        return "%s %s" % (obj.sourcepackagename.name, obj.version)
    elif IProductRelease.providedBy(obj):
        return "%s %s" % (obj.product.name, obj.version)
    elif IMilestone.providedBy(obj):
        return obj.name
    elif isinstance(obj, BaseItem):
        return obj.title
    elif isinstance(obj, basestring):
        return obj
    elif isinstance(obj, bool):
        return str(obj)
    else:
        return None
Beispiel #9
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')
Beispiel #10
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
Beispiel #11
0
 def __init__(self, context=None):
     """Pass a Person as context, or anything else for the current user."""
     super(HostedBranchRestrictedOnOwnerVocabulary, self).__init__(context)
     if IPerson.providedBy(self.context):
         self.user = self.context
     else:
         self.user = getUtility(ILaunchBag).user
    def template(self):
        # Check for the magical "index" added by the browser:page template
        # machinery. If it exists this is actually the
        # zope.browserpage.simpleviewclass.simple class that is magically
        # mixed in by the browser:page zcml directive the template defined in
        # the directive should be used.
        if safe_hasattr(self, 'index'):
            return super(HasSpecificationsView, self).template

        # Sprints and Persons don't have a usage enum for blueprints, so we
        # have to fallback to the default.
        if (ISprint.providedBy(self.context)
                or IPerson.providedBy(self.context)):
            return self.default_template

        # ProjectGroups are a special case, as their products may be a
        # combination of usage settings. To deal with this, check all
        # products via the involvment menu.
        if (IProjectGroup.providedBy(self.context)
                or IProjectGroupSeries.providedBy(self.context)):
            involvement = getMultiAdapter((self.context, self.request),
                                          name='+get-involved')
            if service_uses_launchpad(involvement.blueprints_usage):
                return self.default_template
            else:
                return self.not_launchpad_template

        # Otherwise, determine usage and provide the correct template.
        service_usage = IServiceUsage(self.context)
        if service_uses_launchpad(service_usage.blueprints_usage):
            return self.default_template
        else:
            return self.not_launchpad_template
    def template(self):
        # Check for the magical "index" added by the browser:page template
        # machinery. If it exists this is actually the
        # zope.browserpage.simpleviewclass.simple class that is magically
        # mixed in by the browser:page zcml directive the template defined in
        # the directive should be used.
        if safe_hasattr(self, 'index'):
            return super(HasSpecificationsView, self).template

        # Sprints and Persons don't have a usage enum for blueprints, so we
        # have to fallback to the default.
        if (ISprint.providedBy(self.context)
            or IPerson.providedBy(self.context)):
            return self.default_template

        # ProjectGroups are a special case, as their products may be a
        # combination of usage settings. To deal with this, check all
        # products via the involvment menu.
        if (IProjectGroup.providedBy(self.context)
            or IProjectGroupSeries.providedBy(self.context)):
            involvement = getMultiAdapter(
                (self.context, self.request),
                name='+get-involved')
            if service_uses_launchpad(involvement.blueprints_usage):
                return self.default_template
            else:
                return self.not_launchpad_template

        # Otherwise, determine usage and provide the correct template.
        service_usage = IServiceUsage(self.context)
        if service_uses_launchpad(service_usage.blueprints_usage):
            return self.default_template
        else:
            return self.not_launchpad_template
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))
Beispiel #15
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))
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)
Beispiel #17
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)
Beispiel #18
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))
Beispiel #19
0
def is_public_person_or_closed_team(person):
    """Return True if person is a Person or not an open or delegated team."""
    from lp.registry.interfaces.person import IPerson
    if not IPerson.providedBy(person):
        return False
    if not person.is_team:
        return person.visibility == PersonVisibility.PUBLIC
    return person.membership_policy in EXCLUSIVE_TEAM_POLICY
Beispiel #20
0
 def create(cls, minor_person, major_person, metadata, requester=None):
     """See `IPersonTransferJob`."""
     if not IPerson.providedBy(minor_person):
         raise TypeError("minor_person must be IPerson: %s"
                         % repr(minor_person))
     if not IPerson.providedBy(major_person):
         raise TypeError("major_person must be IPerson: %s"
                         % repr(major_person))
     job = PersonTransferJob(
         minor_person=minor_person,
         major_person=major_person,
         job_type=cls.class_job_type,
         metadata=metadata,
         requester=requester)
     derived = cls(job)
     derived.celeryRunOnCommit()
     return derived
Beispiel #21
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)
Beispiel #22
0
def is_public_person_or_closed_team(person):
    """Return True if person is a Person or not an open or delegated team."""
    from lp.registry.interfaces.person import IPerson
    if not IPerson.providedBy(person):
        return False
    if not person.is_team:
        return person.visibility == PersonVisibility.PUBLIC
    return person.membership_policy in EXCLUSIVE_TEAM_POLICY
Beispiel #23
0
 def __contains__(self, person_or_email):
     """See `INotificationRecipientSet`."""
     if zope_isinstance(person_or_email, (str, unicode)):
         return person_or_email in self._emailToPerson
     elif IPerson.providedBy(person_or_email):
         return person_or_email in self._personToRationale
     else:
         return False
 def __contains__(self, person_or_email):
     """See `INotificationRecipientSet`."""
     if zope_isinstance(person_or_email, (str, unicode)):
         return person_or_email in self._emailToPerson
     elif IPerson.providedBy(person_or_email):
         return person_or_email in self._personToRationale
     else:
         return False
Beispiel #25
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))
 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))
Beispiel #27
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))
Beispiel #28
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)
Beispiel #29
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()
Beispiel #30
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))
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)
 def remove(self, persons):
     """See `INotificationRecipientSet`."""
     from zope.security.proxy import removeSecurityProxy
     from lp.registry.model.person import get_recipients
     if IPerson.providedBy(persons):
         persons = [persons]
     for person in persons:
         assert IPerson.providedBy(person), (
             'You can only remove() an IPerson: %r' % person)
         if person in self._personToRationale:
             del self._personToRationale[person]
         for removed_person in get_recipients(person):
             # Bypass zope's security because IEmailAddress.email is
             # not public.
             preferred_email = removeSecurityProxy(
                 removed_person.preferredemail)
             email = str(preferred_email.email)
             self._receiving_people.discard((email, removed_person))
             del self._emailToPerson[email]
Beispiel #33
0
 def remove(self, persons):
     """See `INotificationRecipientSet`."""
     from zope.security.proxy import removeSecurityProxy
     from lp.registry.model.person import get_recipients
     if IPerson.providedBy(persons):
         persons = [persons]
     for person in persons:
         assert IPerson.providedBy(person), (
             'You can only remove() an IPerson: %r' % person)
         if person in self._personToRationale:
             del self._personToRationale[person]
         for removed_person in get_recipients(person):
             # Bypass zope's security because IEmailAddress.email is
             # not public.
             preferred_email = removeSecurityProxy(
                 removed_person.preferredemail)
             email = str(preferred_email.email)
             self._receiving_people.discard((email, removed_person))
             del self._emailToPerson[email]
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
    def maybeRestrictToTeam(self, request):
        restrict_to_team = config.launchpad.restrict_to_team
        if not restrict_to_team:
            return

        restrictedlogin = '******'
        restrictedinfo = '+restricted-info'

        # Always allow access to +restrictedlogin and +restrictedinfo.
        traversal_stack = request.getTraversalStack()
        if (traversal_stack == [restrictedlogin] or
            traversal_stack == [restrictedinfo]):
            return

        principal = request.principal
        team = getUtility(IPersonSet).getByName(restrict_to_team)
        if team is None:
            raise AssertionError(
                'restrict_to_team "%s" not found' % restrict_to_team)
        elif not ITeam.providedBy(team):
            raise AssertionError(
                'restrict_to_team "%s" is not a team' % restrict_to_team)

        if IUnauthenticatedPrincipal.providedBy(principal):
            location = '/%s' % restrictedlogin
        else:
            # We have a team we can work with.
            user = IPerson(principal)
            if (user.inTeam(team) or
                user.inTeam(getUtility(ILaunchpadCelebrities).admin)):
                return
            else:
                location = '/%s' % restrictedinfo

        non_restricted_url = self.getNonRestrictedURL(request)
        if non_restricted_url is not None:
            location += '?production=%s' % urllib.quote(non_restricted_url)

        request.response.setResult('')
        request.response.redirect(location, temporary_if_possible=True)
        # Quash further traversal.
        request.setTraversalStack([])
    def maybeRestrictToTeam(self, request):
        restrict_to_team = config.launchpad.restrict_to_team
        if not restrict_to_team:
            return

        restrictedlogin = '******'
        restrictedinfo = '+restricted-info'

        # Always allow access to +restrictedlogin and +restrictedinfo.
        traversal_stack = request.getTraversalStack()
        if (traversal_stack == [restrictedlogin]
                or traversal_stack == [restrictedinfo]):
            return

        principal = request.principal
        team = getUtility(IPersonSet).getByName(restrict_to_team)
        if team is None:
            raise AssertionError('restrict_to_team "%s" not found' %
                                 restrict_to_team)
        elif not ITeam.providedBy(team):
            raise AssertionError('restrict_to_team "%s" is not a team' %
                                 restrict_to_team)

        if IUnauthenticatedPrincipal.providedBy(principal):
            location = '/%s' % restrictedlogin
        else:
            # We have a team we can work with.
            user = IPerson(principal)
            if (user.inTeam(team)
                    or user.inTeam(getUtility(ILaunchpadCelebrities).admin)):
                return
            else:
                location = '/%s' % restrictedinfo

        non_restricted_url = self.getNonRestrictedURL(request)
        if non_restricted_url is not None:
            location += '?production=%s' % urllib.quote(non_restricted_url)

        request.response.setResult('')
        request.response.redirect(location, temporary_if_possible=True)
        # Quash further traversal.
        request.setTraversalStack([])
Beispiel #37
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
Beispiel #38
0
def get_git_namespace(target, owner):
    if IProduct.providedBy(target):
        return getUtility(IGitNamespaceSet).get(owner, project=target)
    elif IDistributionSourcePackage.providedBy(target):
        return getUtility(IGitNamespaceSet).get(
            owner, distribution=target.distribution,
            sourcepackagename=target.sourcepackagename)
    elif target is None or IPerson.providedBy(target):
        return getUtility(IGitNamespaceSet).get(owner)
    else:
        raise AssertionError("No Git namespace defined for %s" % target)
 def test_branch_list_recipes_link(self):
     # The link to the source package recipes is always displayed.
     page = self.get_branch_list_page()
     recipes_matcher = soupmatchers.HTMLContains(
         soupmatchers.Tag(
             'Source package recipes link', 'a',
             text='Source package recipes',
             attrs={'href': self.base_url + '/+recipes'}))
     if IPerson.providedBy(self.default_target):
         self.assertThat(page, recipes_matcher)
     else:
         self.assertThat(page, Not(recipes_matcher))
Beispiel #40
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')
 def getProposalsForContext(context, status=None, visible_by_user=None):
     """See `IBranchMergeProposalGetter`."""
     collection = getUtility(IAllBranches).visibleByUser(visible_by_user)
     if context is None:
         pass
     elif IProduct.providedBy(context):
         collection = collection.inProduct(context)
     elif IPerson.providedBy(context):
         collection = collection.ownedBy(context)
     else:
         raise BadBranchMergeProposalSearchContext(context)
     return collection.getMergeProposals(status)
 def setRenderedValue(self, value):
     """See IWidget."""
     self.setUpSubWidgets()
     if IBranchTarget.providedBy(value):
         if IProduct.providedBy(value.context):
             self.default_option = 'product'
             self.product_widget.setRenderedValue(value.context)
             return
         elif IPerson.providedBy(value.context):
             self.default_option = 'personal'
             return
     else:
         raise AssertionError('Not a valid value: %r' % value)
def spec_modified(spec, event):
    """Check changes made to the spec and assign karma if needed."""
    user = IPerson(event.user)
    spec_delta = event.object.getDelta(event.object_before_modification, user)
    if spec_delta is None:
        return

    # easy 1-1 mappings from attribute changing to karma
    attrs_actionnames = {
        'title': 'spectitlechanged',
        'summary': 'specsummarychanged',
        'specurl': 'specurlchanged',
        'priority': 'specpriority',
        'productseries': 'specseries',
        'distroseries': 'specseries',
        'milestone': 'specmilestone',
        }

    for attr, actionname in attrs_actionnames.items():
        if getattr(spec_delta, attr, None) is not None:
            user.assignKarma(
                actionname, product=spec.product,
                distribution=spec.distribution)
 def getReason(self, person_or_email):
     """See `INotificationRecipientSet`."""
     if zope_isinstance(person_or_email, basestring):
         try:
             person = self._emailToPerson[person_or_email]
         except KeyError:
             raise UnknownRecipientError(person_or_email)
     elif IPerson.providedBy(person_or_email):
         person = person_or_email
     else:
         raise AssertionError(
             'Not an IPerson or email address: %r' % person_or_email)
     try:
         return self._personToRationale[person]
     except KeyError:
         raise UnknownRecipientError(person)
Beispiel #45
0
    def __init__(self, search_text=None, owner=None, sort=None, product=None,
                 distribution=None, project=None):
        """Initialize a new FAQ search.

        See `IFAQCollection`.searchFAQs for the basic parameters description.
        Additional parameters:
        :param product: The product in which to search for FAQs.
        :param distribution: The distribution in which to search for FAQs.
        :param project: The project in which to search for FAQs.
        """
        if search_text is not None:
            assert isinstance(search_text, basestring), (
                'search_text should be a string, not %s' % type(search_text))
            self.search_text = search_text

        if owner is not None:
            assert IPerson.providedBy(owner), (
                'owner should be an IPerson, not %s' % type(owner))
            self.owner = owner

        if sort is not None:
            assert sort in FAQSort.items, (
                'sort should be an item from FAQSort, not %s' % type(sort))
            self.sort = sort

        if product is not None:
            assert IProduct.providedBy(product), (
                'product should be an IProduct, not %s' % type(product))
            assert distribution is None and project is None, (
                'can only use one of product, distribution, or project')
            self.product = product

        if distribution is not None:
            assert IDistribution.providedBy(distribution), (
                'distribution should be an IDistribution, %s' %
                type(distribution))
            assert product is None and project is None, (
                'can only use one of product, distribution, or project')
            self.distribution = distribution

        if project is not None:
            assert IProjectGroup.providedBy(project), (
                'project should be an IProjectGroup, not %s' % type(project))
            assert product is None and distribution is None, (
                'can only use one of product, distribution, or project')
            self.project = project
def get_person_bugtasks_search_params(user, context, **kwargs):
    """Returns a list of `BugTaskSearchParams` which can be used to
    search for all tasks related to a user given by `context`.

    Which tasks are related to a user?
      * the user has to be either assignee or owner of this task
        OR
      * the user has to be subscriber or commenter to the underlying bug
        OR
      * the user is reporter of the underlying bug, but this condition
        is automatically fulfilled by the first one as each new bug
        always get one task owned by the bug reporter
    """
    from lp.registry.interfaces.person import IPerson
    assert IPerson.providedBy(context), "Context argument needs to be IPerson"
    relevant_fields = ('assignee', 'bug_subscriber', 'owner', 'bug_commenter',
                       'structural_subscriber')
    search_params = []
    for key in relevant_fields:
        # all these parameter default to None
        user_param = kwargs.get(key)
        if user_param is None or user_param == context:
            # we are only creating a `BugTaskSearchParams` object if
            # the field is None or equal to the context
            arguments = kwargs.copy()
            arguments[key] = context
            if key == 'owner':
                # Specify both owner and bug_reporter to try to
                # prevent the same bug (but different tasks)
                # being displayed.
                # see `PersonRelatedBugTaskSearchListingView.searchUnbatched`
                arguments['bug_reporter'] = context
            search_params.append(
                BugTaskSearchParams.fromSearchForm(user, **arguments))
    if len(search_params) == 0:
        # unable to search for related tasks to user_context because user
        # modified the query in an invalid way by overwriting all user
        # related parameters
        raise IllegalRelatedBugTasksParams(
            ('Cannot search for related tasks to \'%s\', at least one '
             'of these parameter has to be empty: %s'
                % (context.name, ", ".join(relevant_fields))))
    return search_params
 def create(cls, member, team, reviewer, old_status, new_status,
            last_change_comment=None):
     if not ITeam.providedBy(team):
         raise TypeError('team must be ITeam: %s' % repr(team))
     if not IPerson.providedBy(reviewer):
         raise TypeError('reviewer must be IPerson: %s' % repr(reviewer))
     if old_status not in TeamMembershipStatus:
         raise TypeError("old_status must be TeamMembershipStatus: %s"
                         % repr(old_status))
     if new_status not in TeamMembershipStatus:
         raise TypeError("new_status must be TeamMembershipStatus: %s"
                         % repr(new_status))
     metadata = {
         'reviewer': reviewer.id,
         'old_status': old_status.name,
         'new_status': new_status.name,
         'last_change_comment': last_change_comment,
         }
     return super(MembershipNotificationJob, cls).create(
         minor_person=member, major_person=team, metadata=metadata)
Beispiel #48
0
    def new(owner, title, content, keywords=keywords, date_created=None,
            product=None, distribution=None):
        """Factory method to create a new FAQ.

        Ensure that only one of product or distribution is given.
        """
        if not IPerson.providedBy(owner):
            raise AssertionError(
                'owner parameter should be an IPerson, not %s' % type(owner))
        if product is not None and distribution is not None:
            raise AssertionError(
                "only one of product or distribution should be provided")
        if product is None and distribution is None:
            raise AssertionError("product or distribution must be provided")
        if date_created is None:
            date_created = DEFAULT
        faq = FAQ(
            owner=owner, title=title, content=content, keywords=keywords,
            date_created=date_created, product=product,
            distribution=distribution)
        notify(ObjectCreatedEvent(faq))
        return faq
    def initialize(self):
        if IPerson.providedBy(self.context):
            self.is_person = True
        elif IDistribution.providedBy(self.context):
            self.is_target = True
            self.is_pillar = True
            self.show_series = True
        elif IProduct.providedBy(self.context):
            self.is_target = True
            self.is_pillar = True
            self.has_wiki = True
            self.show_series = True
        elif IProjectGroup.providedBy(self.context):
            self.is_project = True
            self.is_pillar = True
            self.has_wiki = True
            self.show_target = True
            self.show_series = True
        elif IProjectGroupSeries.providedBy(self.context):
            self.show_milestone = True
            self.show_target = True
            self.show_series = True
        elif (IProductSeries.providedBy(self.context) or
              IDistroSeries.providedBy(self.context)):
            self.is_series = True
            self.show_milestone = True
        elif ISprint.providedBy(self.context):
            self.is_sprint = True
            self.show_target = True
        else:
            raise AssertionError('Unknown blueprint listing site.')

        if IHasDrivers.providedBy(self.context):
            self.has_drivers = True

        self.batchnav = BatchNavigator(
            self.specs, self.request,
            size=config.launchpad.default_batch_size)
def get_person_picker_entry_metadata(picker_entry):
    """Return the picker entry meta for a given result value."""
    if picker_entry is not None and IPerson.providedBy(picker_entry):
        return "team" if picker_entry.is_team else "person"
    return None
Beispiel #51
0
def is_public_person(person):
    """Return True if the person is public."""
    from lp.registry.interfaces.person import IPerson
    if not IPerson.providedBy(person):
        return False
    return person.visibility == PersonVisibility.PUBLIC
    def getForDistroSeries(distro_series, difference_type=None,
                           name_filter=None, status=None,
                           child_version_higher=False, parent_series=None,
                           packagesets=None, changed_by=None):
        """See `IDistroSeriesDifferenceSource`."""
        if isinstance(status, DBItem):
            status = (status,)
        if IPerson.providedBy(changed_by):
            changed_by = (changed_by,)

        # Aliases, to improve readability.
        DSD = DistroSeriesDifference
        PSS = PackagesetSources
        SPN = SourcePackageName
        SPPH = SourcePackagePublishingHistory
        SPR = SourcePackageRelease
        TP = TeamParticipation

        conditions = [
            DSD.derived_series == distro_series,
            DSD.source_package_name == SPN.id,  # For ordering.
            ]
        if difference_type is not None:
            conditions.append(DSD.difference_type == difference_type)
        if status is not None:
            conditions.append(DSD.status.is_in(tuple(status)))

        if child_version_higher:
            conditions.append(DSD.source_version > DSD.parent_source_version)

        if parent_series:
            conditions.append(DSD.parent_series == parent_series.id)

        # Take a copy of the conditions specified thus far.
        basic_conditions = list(conditions)

        if name_filter:
            name_matches = [SPN.name == name_filter]
            try:
                packageset = getUtility(IPackagesetSet).getByName(
                    name_filter, distroseries=distro_series)
            except NoSuchPackageSet:
                packageset = None
            if packageset is not None:
                name_matches.append(
                    DSD.source_package_name_id.is_in(
                        Select(PSS.sourcepackagename_id,
                               PSS.packageset == packageset)))
            conditions.append(Or(*name_matches))

        if packagesets is not None:
            set_ids = [packageset.id for packageset in packagesets]
            conditions.append(
                DSD.source_package_name_id.is_in(
                    Select(PSS.sourcepackagename_id,
                           PSS.packageset_id.is_in(set_ids))))

        store = IStore(DSD)
        columns = (DSD, SPN.name)
        differences = store.find(columns, And(*conditions))

        if changed_by is not None:
            # Identify all DSDs referring to SPRs created by changed_by for
            # this distroseries. The set of DSDs for the given distroseries
            # can then be discovered as the intersection between this set and
            # the already established differences.
            differences_changed_by_conditions = And(
                basic_conditions,
                SPPH.archiveID == distro_series.main_archive.id,
                SPPH.distroseriesID == distro_series.id,
                SPPH.sourcepackagereleaseID == SPR.id,
                SPPH.status.is_in(active_publishing_status),
                SPR.creatorID == TP.personID,
                SPR.sourcepackagenameID == DSD.source_package_name_id,
                TP.teamID.is_in(person.id for person in changed_by))
            differences_changed_by = store.find(
                columns, differences_changed_by_conditions)
            differences = differences.intersection(differences_changed_by)

        differences = differences.order_by(SPN.name)

        def pre_iter_hook(rows):
            # Each row is (dsd, spn.name). Modify the results in place.
            rows[:] = (dsd for (dsd, spn_name) in rows)
            # Eager load everything to do with DSDs.
            return eager_load_dsds(rows)

        return DecoratedResultSet(differences, pre_iter_hook=pre_iter_hook)
 def _get_person_celebrities(self, is_team):
     for name in ILaunchpadCelebrities.names():
         attr = getattr(self.celebs, name)
         if IPerson.providedBy(attr) and attr.is_team == is_team:
             yield (name, attr)