def subscriber_data(self):
        """Return subscriber_ids in a form suitable for JavaScript use."""
        bug = IBug(self.context)
        data = self.direct_subscriber_data(bug)

        others = list(bug.getIndirectSubscribers())
        # If we have made it to here then the logged in user can see the
        # bug, hence they can see any indirect subscribers.
        include_private = self.user is not None
        if include_private:
            precache_permission_for_objects(
                self.request, 'launchpad.LimitedView', others)
        for person in others:
            if person == self.user:
                # Skip the current user viewing the page,
                continue
            if not include_private and person.private:
                # Do not include private teams if there's no logged in user.
                continue
            subscriber = {
                'name': person.name,
                'display_name': person.displayname,
                'web_link': canonical_url(person, rootsite='mainsite'),
                'self_link': absoluteURL(person, self.api_request),
                'is_team': person.is_team,
                'can_edit': False,
                }
            record = {
                'subscriber': subscriber,
                'subscription_level': 'Maybe',
                }
            data.append(record)
        return data
    def subscriber_data(self):
        """Return subscriber_ids in a form suitable for JavaScript use."""
        bug = IBug(self.context)
        data = self.direct_subscriber_data(bug)

        others = list(bug.getIndirectSubscribers())
        # If we have made it to here then the logged in user can see the
        # bug, hence they can see any indirect subscribers.
        include_private = self.user is not None
        if include_private:
            precache_permission_for_objects(
                self.request, 'launchpad.LimitedView', others)
        for person in others:
            if person == self.user:
                # Skip the current user viewing the page,
                continue
            if not include_private and person.private:
                # Do not include private teams if there's no logged in user.
                continue
            subscriber = {
                'name': person.name,
                'display_name': person.displayname,
                'web_link': canonical_url(person, rootsite='mainsite'),
                'self_link': absoluteURL(person, self.api_request),
                'is_team': person.is_team,
                'can_edit': False,
                }
            record = {
                'subscriber': subscriber,
                'subscription_level': 'Maybe',
                }
            data.append(record)
        return data
    def sorted_subscriptions(self):
        """Get the list of subscriptions to the specification.

        The list is sorted such that subscriptions you can unsubscribe appear
        before all other subscriptions.
        """
        can_unsubscribe = []
        cannot_unsubscribe = []
        subscribers = []
        for subscription in self.context.subscriptions:
            subscribers.append(subscription.person)
            if subscription.person == self.user:
                can_unsubscribe = [subscription] + can_unsubscribe
            elif subscription.canBeUnsubscribedByUser(self.user):
                can_unsubscribe.append(subscription)
            else:
                cannot_unsubscribe.append(subscription)
        # Cache permission so private subscribers can be viewed.
        # The security adaptor will do the job also but we don't want or need
        # the expense of running several complex SQL queries.
        precache_permission_for_objects(self.request, 'launchpad.LimitedView',
                                        subscribers)

        sorted_subscriptions = can_unsubscribe + cannot_unsubscribe
        return sorted_subscriptions
Example #4
0
    def subscriptions(self):
        """Return a decorated list of branch subscriptions."""

        # Cache permissions so private subscribers can be rendered.
        # The security adaptor will do the job also but we don't want or need
        # the expense of running several complex SQL queries.
        subscriptions = list(self.context.subscriptions)
        person_ids = [sub.personID for sub in subscriptions]
        list(
            getUtility(IPersonSet).getPrecachedPersonsFromIDs(
                person_ids, need_validity=True))
        if self.user is not None:
            subscribers = [
                subscription.person for subscription in subscriptions
            ]
            precache_permission_for_objects(self.request,
                                            "launchpad.LimitedView",
                                            subscribers)

        visible_subscriptions = [
            subscription for subscription in subscriptions
            if check_permission('launchpad.LimitedView', subscription.person)
        ]
        return sorted(visible_subscriptions,
                      key=lambda subscription: subscription.person.displayname)
    def sorted_subscriptions(self):
        """Get the list of subscriptions to the specification.

        The list is sorted such that subscriptions you can unsubscribe appear
        before all other subscriptions.
        """
        can_unsubscribe = []
        cannot_unsubscribe = []
        subscribers = []
        for subscription in self.context.subscriptions:
            subscribers.append(subscription.person)
            if subscription.person == self.user:
                can_unsubscribe = [subscription] + can_unsubscribe
            elif subscription.canBeUnsubscribedByUser(self.user):
                can_unsubscribe.append(subscription)
            else:
                cannot_unsubscribe.append(subscription)
        # Cache permission so private subscribers can be viewed.
        # The security adaptor will do the job also but we don't want or need
        # the expense of running several complex SQL queries.
        precache_permission_for_objects(
                    self.request, 'launchpad.LimitedView', subscribers)

        sorted_subscriptions = can_unsubscribe + cannot_unsubscribe
        return sorted_subscriptions
Example #6
0
 def _precacheViewPermissions(self, branches):
     """Precache the launchpad.View permissions on the branches."""
     # XXX: TimPenhey 2009-06-08 bug=324546
     # Until there is an API to do this nicely, shove the launchpad.view
     # permission into the request cache directly.
     precache_permission_for_objects(
         self.request, 'launchpad.View', branches)
     return branches
Example #7
0
 def _precacheViewPermissions(self, branches):
     """Precache the launchpad.View permissions on the branches."""
     # XXX: TimPenhey 2009-06-08 bug=324546
     # Until there is an API to do this nicely, shove the launchpad.view
     # permission into the request cache directly.
     precache_permission_for_objects(self.request, 'launchpad.View',
                                     branches)
     return branches
 def eager_load(rows):
     subscriptions = map(itemgetter(0), rows)
     precache_permission_for_objects(None, 'launchpad.View',
                                     subscriptions)
     archives = load_related(Archive, subscriptions, ['archive_id'])
     list(
         getUtility(IPersonSet).getPrecachedPersonsFromIDs(
             [archive.ownerID for archive in archives],
             need_validity=True))
 def test_authorized_kw_arg(self):
     # Method invocation with context being a kw argument.
     bar = Object()
     request = LaunchpadTestRequest()
     login(ANONYMOUS, request)
     precache_permission_for_objects(request, 'launchpad.Edit', [bar])
     obj_to_invoke = AvailableWithPermissionObject()
     foo = Object()
     obj_to_invoke.test_function_bar(foo=foo, bar=bar)
 def test_default_request(self):
     # If no request is provided, the current interaction is used.
     class Boring(object):
         """A boring, but weakref-able object."""
     obj = Boring()
     request = LaunchpadTestRequest()
     login(ANONYMOUS, request)
     precache_permission_for_objects(None, 'launchpad.View', [obj])
     self.assertTrue(check_permission('launchpad.View', obj))
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
Example #12
0
 def _make_formatter(self, cache_permission=False):
     # Helper to create the formatter and optionally cache the permission.
     formatter = getAdapter(self.team, IPathAdapter, 'fmt')
     clear_cache()
     request = LaunchpadTestRequest()
     any_person = self.factory.makePerson()
     if cache_permission:
         login_person(any_person, request)
         precache_permission_for_objects(
             request, 'launchpad.LimitedView', [self.team])
     return formatter, request, any_person
Example #13
0
 def initialize(self):
     # If we have made it to here then the logged in user can see the
     # bug, hence they can see any assignees and subscribers.
     # The security adaptor will do the job also but we don't want or need
     # the expense of running several complex SQL queries.
     authorised_people = []
     for task in self.bugtasks:
         if task.assignee is not None:
             authorised_people.append(task.assignee)
     authorised_people.extend(self.subscribers)
     precache_permission_for_objects(
         self.request, 'launchpad.LimitedView', authorised_people)
 def test_precaching_permissions(self):
     # The precache_permission_for_objects function updates the security
     # policy cache for the permission specified.
     class Boring(object):
         """A boring, but weakref-able object."""
     objects = [Boring(), Boring()]
     request = LaunchpadTestRequest()
     login(ANONYMOUS, request)
     precache_permission_for_objects(request, 'launchpad.View', objects)
     # Confirm that the objects have the permission set.
     self.assertTrue(check_permission('launchpad.View', objects[0]))
     self.assertTrue(check_permission('launchpad.View', objects[1]))
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 administers_and_in:
                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.title,
                    'url': canonical_url(team),
                })
    objects['administratedTeams'] = info
Example #16
0
 def initialize(self):
     super(BranchView, self).initialize()
     self.branch = self.context
     self.notices = []
     # Cache permission so private team owner can be rendered.
     # The security adaptor will do the job also but we don't want or need
     # the expense of running several complex SQL queries.
     authorised_people = [self.branch.owner]
     if self.user is not None:
         precache_permission_for_objects(
             self.request, "launchpad.LimitedView", authorised_people)
     # Replace our context with a decorated branch, if it is not already
     # decorated.
     if not isinstance(self.context, DecoratedBranch):
         self.context = DecoratedBranch(self.context)
 def test_limitedView_visible_attributes(self):
     """Users with LimitedView can know identifying information like name,
     displayname, and unique_name, but cannot know other information like
     team members.
     """
     some_person = self.factory.makePerson()
     request = LaunchpadTestRequest()
     # First login as a person who has limitedView permission.
     precache_permission_for_objects(
         request, 'launchpad.LimitedView', [self.priv_team])
     login_person(some_person, participation=request)
     self.assertEqual('priv-team', self.priv_team.name)
     self.assertEqual('Priv Team', self.priv_team.displayname)
     self.assertEqual(
         'Priv Team (priv-team)', self.priv_team.unique_displayname)
     self.assertIsNone(self.priv_team.icon)
     self.assertRaises(Unauthorized, getattr, self.priv_team, 'allmembers')
Example #18
0
 def test_limitedView_visible_attributes(self):
     """Users with LimitedView can know identifying information like name,
     displayname, and unique_name, but cannot know other information like
     team members.
     """
     some_person = self.factory.makePerson()
     request = LaunchpadTestRequest()
     # First login as a person who has limitedView permission.
     precache_permission_for_objects(request, 'launchpad.LimitedView',
                                     [self.priv_team])
     login_person(some_person, participation=request)
     self.assertEqual('priv-team', self.priv_team.name)
     self.assertEqual('Priv Team', self.priv_team.displayname)
     self.assertEqual('Priv Team (priv-team)',
                      self.priv_team.unique_displayname)
     self.assertIsNone(self.priv_team.icon)
     self.assertRaises(Unauthorized, getattr, self.priv_team, 'allmembers')
Example #19
0
 def _bugtasks(self):
     """The list of non-conjoined bugtasks targeted to this milestone."""
     # Put the results in a list so that iterating over it multiple
     # times in this method does not make multiple queries.
     non_conjoined_slaves = self.context.bugtasks(self.user)
     # Checking bug permissions is expensive. We know from the query that
     # the user has at least launchpad.View on the bugtasks and their bugs.
     # NB: this is in principle unneeded due to injection of permission in
     # the model layer now.
     precache_permission_for_objects(
         self.request, 'launchpad.View', non_conjoined_slaves)
     precache_permission_for_objects(
         self.request, 'launchpad.View',
         [task.bug for task in non_conjoined_slaves])
     # We want the assignees loaded as we show them in the milestone home
     # page.
     list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
         [bug.assigneeID for bug in non_conjoined_slaves],
         need_validity=True))
     return non_conjoined_slaves
Example #20
0
 def _bugtasks(self):
     """The list of non-conjoined bugtasks targeted to this milestone."""
     # Put the results in a list so that iterating over it multiple
     # times in this method does not make multiple queries.
     non_conjoined_slaves = self.context.bugtasks(self.user)
     # Checking bug permissions is expensive. We know from the query that
     # the user has at least launchpad.View on the bugtasks and their bugs.
     # NB: this is in principle unneeded due to injection of permission in
     # the model layer now.
     precache_permission_for_objects(self.request, 'launchpad.View',
                                     non_conjoined_slaves)
     precache_permission_for_objects(
         self.request, 'launchpad.View',
         [task.bug for task in non_conjoined_slaves])
     # We want the assignees loaded as we show them in the milestone home
     # page.
     list(
         getUtility(IPersonSet).getPrecachedPersonsFromIDs(
             [bug.assigneeID for bug in non_conjoined_slaves],
             need_validity=True))
     return non_conjoined_slaves
Example #21
0
    def direct_subscriber_data(self, bug):
        """Get the direct subscriber data.

        This method is isolated from the subscriber_data_js so that query
        count testing can be done accurately and robustly.
        """
        data = []
        details = list(bug.getDirectSubscribersWithDetails())
        for person, subscribed_by, subscription in details:
            can_edit = subscription.canBeUnsubscribedByUser(self.user)
            if person == self.user:
                # Skip the current user viewing the page.
                continue
            if self.user is None and person.private:
                # Do not include private teams if there's no logged in user.
                continue

            # If we have made it to here then the logged in user can see the
            # bug, hence they can see any subscribers.
            # The security adaptor will do the job also but we don't want or
            # need the expense of running several complex SQL queries.
            precache_permission_for_objects(self.request,
                                            'launchpad.LimitedView', [person])
            subscriber = {
                'name': person.name,
                'display_name': person.displayname,
                'web_link': canonical_url(person, rootsite='mainsite'),
                'self_link': absoluteURL(person, self.api_request),
                'is_team': person.is_team,
                'can_edit': can_edit,
                'display_subscribed_by': subscription.display_subscribed_by,
            }
            record = {
                'subscriber':
                subscriber,
                'subscription_level':
                str(removeSecurityProxy(subscription.bug_notification_level)),
            }
            data.append(record)
        return data
Example #22
0
    def subscriptions_with_tokens(self):
        """Return all the persons archive subscriptions with the token
        for each.

        The result is formatted as a list of dicts to make the TALS code
        cleaner.
        """
        subscriber_set = getUtility(IArchiveSubscriberSet)
        subs_with_tokens = subscriber_set.getBySubscriberWithActiveToken(
            self.context)

        subscriptions = map(itemgetter(0), subs_with_tokens)
        precache_permission_for_objects(None, 'launchpad.View', subscriptions)
        archives = load_related(Archive, subscriptions, ['archive_id'])
        list(
            getUtility(IPersonSet).getPrecachedPersonsFromIDs(
                [archive.ownerID for archive in archives], need_validity=True))
        for archive in archives:
            get_property_cache(archive)._known_subscribers = [self.user]

        # Turn the result set into a list of dicts so it can be easily
        # accessed in TAL. Note that we need to ensure that only one
        # PersonalArchiveSubscription is included for each archive,
        # as the person might have participation in multiple
        # subscriptions (via different teams).
        unique_archives = set()
        personal_subscription_tokens = []
        for subscription, token in subs_with_tokens:
            if subscription.archive in unique_archives:
                continue
            unique_archives.add(subscription.archive)

            personal_subscription = PersonalArchiveSubscription(
                self.context, subscription.archive)
            personal_subscription_tokens.append({
                'subscription': personal_subscription,
                'token': token
            })

        return personal_subscription_tokens
    def subscriptions(self):
        """Return a decorated list of branch subscriptions."""

        # Cache permissions so private subscribers can be rendered.
        # The security adaptor will do the job also but we don't want or need
        # the expense of running several complex SQL queries.
        person_ids = [sub.personID for sub in self.context.subscriptions]
        list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
            person_ids, need_validity=True))
        if self.user is not None:
            subscribers = [
                subscription.person
                for subscription in self.context.subscriptions]
            precache_permission_for_objects(
                self.request, "launchpad.LimitedView", subscribers)

        visible_subscriptions = [
            subscription for subscription in self.context.subscriptions
            if check_permission('launchpad.LimitedView', subscription.person)]
        return sorted(
            visible_subscriptions,
            key=lambda subscription: subscription.person.displayname)
    def direct_subscriber_data(self, bug):
        """Get the direct subscriber data.

        This method is isolated from the subscriber_data_js so that query
        count testing can be done accurately and robustly.
        """
        data = []
        details = list(bug.getDirectSubscribersWithDetails())
        for person, subscribed_by, subscription in details:
            can_edit = subscription.canBeUnsubscribedByUser(self.user)
            if person == self.user:
                # Skip the current user viewing the page.
                continue
            if self.user is None and person.private:
                # Do not include private teams if there's no logged in user.
                continue

            # If we have made it to here then the logged in user can see the
            # bug, hence they can see any subscribers.
            # The security adaptor will do the job also but we don't want or
            # need the expense of running several complex SQL queries.
            precache_permission_for_objects(
                        self.request, 'launchpad.LimitedView', [person])
            subscriber = {
                'name': person.name,
                'display_name': person.displayname,
                'web_link': canonical_url(person, rootsite='mainsite'),
                'self_link': absoluteURL(person, self.api_request),
                'is_team': person.is_team,
                'can_edit': can_edit,
                'display_subscribed_by': subscription.display_subscribed_by,
                }
            record = {
                'subscriber': subscriber,
                'subscription_level': str(
                    removeSecurityProxy(subscription.bug_notification_level)),
                }
            data.append(record)
        return data
    def subscriptions_with_tokens(self):
        """Return all the persons archive subscriptions with the token
        for each.

        The result is formatted as a list of dicts to make the TALS code
        cleaner.
        """
        subscriber_set = getUtility(IArchiveSubscriberSet)
        subs_with_tokens = subscriber_set.getBySubscriberWithActiveToken(self.context)

        subscriptions = map(itemgetter(0), subs_with_tokens)
        precache_permission_for_objects(None, "launchpad.View", subscriptions)
        archives = load_related(Archive, subscriptions, ["archive_id"])
        list(
            getUtility(IPersonSet).getPrecachedPersonsFromIDs(
                [archive.ownerID for archive in archives], need_validity=True
            )
        )
        for archive in archives:
            get_property_cache(archive)._known_subscribers = [self.user]

        # Turn the result set into a list of dicts so it can be easily
        # accessed in TAL. Note that we need to ensure that only one
        # PersonalArchiveSubscription is included for each archive,
        # as the person might have participation in multiple
        # subscriptions (via different teams).
        unique_archives = set()
        personal_subscription_tokens = []
        for subscription, token in subs_with_tokens:
            if subscription.archive in unique_archives:
                continue
            unique_archives.add(subscription.archive)

            personal_subscription = PersonalArchiveSubscription(self.context, subscription.archive)
            personal_subscription_tokens.append({"subscription": personal_subscription, "token": token})

        return personal_subscription_tokens