launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #29740
[Merge] ~lgp171188/launchpad:hide-make-announcement-link-illegitimate-pillar-owners into launchpad:master
Guruprasad has proposed merging ~lgp171188/launchpad:hide-make-announcement-link-illegitimate-pillar-owners into launchpad:master.
Commit message:
Hide the 'Make announcement' link for illegitimate pillar owners
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~lgp171188/launchpad/+git/launchpad/+merge/438674
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~lgp171188/launchpad:hide-make-announcement-link-illegitimate-pillar-owners into launchpad:master.
diff --git a/lib/lp/registry/browser/announcement.py b/lib/lp/registry/browser/announcement.py
index 7ef6105..931acd4 100644
--- a/lib/lp/registry/browser/announcement.py
+++ b/lib/lp/registry/browser/announcement.py
@@ -1,18 +1,19 @@
-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2023 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Announcement views."""
__all__ = [
"AnnouncementAddView",
- "AnnouncementRetargetView",
- "AnnouncementPublishView",
- "AnnouncementRetractView",
"AnnouncementDeleteView",
"AnnouncementEditView",
+ "AnnouncementPublishView",
+ "AnnouncementRetargetView",
+ "AnnouncementRetractView",
"AnnouncementSetView",
- "HasAnnouncementsView",
"AnnouncementView",
+ "current_user_can_announce",
+ "HasAnnouncementsView",
]
from zope.interface import Interface, implementer
@@ -41,6 +42,13 @@ from lp.services.webapp.menu import (
from lp.services.webapp.publisher import LaunchpadView, canonical_url
+def current_user_can_announce(pillar):
+ """Can the current user can make announcements for the pillar?"""
+ return check_permission("launchpad.Edit", pillar) and check_permission(
+ "launchpad.AnyLegitimatePerson", pillar
+ )
+
+
class AnnouncementMenuMixin:
"""A mixin of links common to many menus."""
diff --git a/lib/lp/registry/browser/distribution.py b/lib/lp/registry/browser/distribution.py
index 1a6257d..3fb8a36 100644
--- a/lib/lp/registry/browser/distribution.py
+++ b/lib/lp/registry/browser/distribution.py
@@ -86,7 +86,10 @@ from lp.bugs.browser.structuralsubscription import (
from lp.buildmaster.interfaces.processor import IProcessorSet
from lp.code.browser.vcslisting import TargetDefaultVCSNavigationMixin
from lp.registry.browser import RegistryEditFormView, add_subscribe_link
-from lp.registry.browser.announcement import HasAnnouncementsView
+from lp.registry.browser.announcement import (
+ HasAnnouncementsView,
+ current_user_can_announce,
+)
from lp.registry.browser.menu import (
IRegistryCollectionNavigationMenu,
RegistryCollectionActionMenuBase,
@@ -571,11 +574,13 @@ class DistributionOverviewMenu(ApplicationMenu, DistributionLinksMixin):
text = "All milestones"
return Link("+milestones", text, icon="info")
- @enabled_with_permission("launchpad.Edit")
def announce(self):
text = "Make announcement"
summary = "Publish an item of news for this project"
- return Link("+announce", text, summary, icon="add")
+ link = Link("+announce", text, summary, icon="add")
+ if not current_user_can_announce(self.context):
+ link.enabled = False
+ return link
def announcements(self):
text = "Read all announcements"
diff --git a/lib/lp/registry/browser/product.py b/lib/lp/registry/browser/product.py
index 5f90da9..56c03a3 100644
--- a/lib/lp/registry/browser/product.py
+++ b/lib/lp/registry/browser/product.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2021 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2023 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Browser views for products."""
@@ -127,7 +127,10 @@ from lp.code.interfaces.branchjob import IRosettaUploadJobSource
from lp.code.interfaces.codeimport import ICodeImport, ICodeImportSet
from lp.code.interfaces.gitrepository import IGitRepository, IGitRepositorySet
from lp.registry.browser import BaseRdfView, add_subscribe_link
-from lp.registry.browser.announcement import HasAnnouncementsView
+from lp.registry.browser.announcement import (
+ HasAnnouncementsView,
+ current_user_can_announce,
+)
from lp.registry.browser.branding import BrandingChangeView
from lp.registry.browser.menu import (
IRegistryCollectionNavigationMenu,
@@ -602,11 +605,13 @@ class ProductOverviewMenu(
text = "View milestones"
return Link("+milestones", text, icon="info")
- @enabled_with_permission("launchpad.Edit")
def announce(self):
text = "Make announcement"
summary = "Publish an item of news for this project"
- return Link("+announce", text, summary, icon="add")
+ link = Link("+announce", text, summary, icon="add")
+ if not current_user_can_announce(self.context):
+ link.enabled = False
+ return link
def announcements(self):
text = "Read all announcements"
diff --git a/lib/lp/registry/browser/project.py b/lib/lp/registry/browser/project.py
index 54eda82..a08d20d 100644
--- a/lib/lp/registry/browser/project.py
+++ b/lib/lp/registry/browser/project.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2023 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Project-related View Classes"""
@@ -59,7 +59,10 @@ from lp.bugs.browser.structuralsubscription import (
expose_structural_subscription_data_to_js,
)
from lp.registry.browser import BaseRdfView, add_subscribe_link
-from lp.registry.browser.announcement import HasAnnouncementsView
+from lp.registry.browser.announcement import (
+ HasAnnouncementsView,
+ current_user_can_announce,
+)
from lp.registry.browser.branding import BrandingChangeView
from lp.registry.browser.menu import (
IRegistryCollectionNavigationMenu,
@@ -232,11 +235,13 @@ class ProjectOverviewMenu(ProjectEditMenuMixin, ApplicationMenu):
text = "More contributors"
return Link("+topcontributors", text, icon="info")
- @enabled_with_permission("launchpad.Edit")
def announce(self):
text = "Make announcement"
summary = "Publish an item of news for this project"
- return Link("+announce", text, summary, icon="add")
+ link = Link("+announce", text, summary, icon="add")
+ if not current_user_can_announce(self.context):
+ link.enabled = False
+ return link
def announcements(self):
text = "Read all announcements"
diff --git a/lib/lp/registry/stories/announcements/xx-announcements.rst b/lib/lp/registry/stories/announcements/xx-announcements.rst
index 6c36e4e..bddb6fd 100644
--- a/lib/lp/registry/stories/announcements/xx-announcements.rst
+++ b/lib/lp/registry/stories/announcements/xx-announcements.rst
@@ -72,7 +72,8 @@ page.
Logged in users can only see it if they have launchpad.Edit on the
-pillar.
+pillar and have an old-enough (config.min_legitimate_account_age), legitimate
+account with sufficient karma (config.min_legitimate_karma).
>>> nopriv_browser = setupBrowser(auth="Basic no-priv@xxxxxxxxxxxxx:test")
>>> nopriv_browser.open("http://launchpad.test/firefox")
@@ -87,6 +88,49 @@ pillar.
...
zope.testbrowser.browser.LinkNotFoundError
+ >>> from lp.testing.sampledata import ADMIN_EMAIL
+ >>> login(ADMIN_EMAIL)
+ >>> new_user = factory.makePerson(
+ ... name="new", displayname="new", email="new@xxxxxxxxxxx"
+ ... )
+ >>> new_product = factory.makeProduct(
+ ... name="new-product", owner=new_user, driver=new_user
+ ... )
+ >>> new_distribution = factory.makeDistribution(
+ ... name="new-distribution", owner=new_user
+ ... )
+ >>> new_project = factory.makeProject(name="new-project", owner=new_user)
+ >>> logout()
+
+ >>> from lp.services.config import config
+ >>> legitimate_person_config = """
+ ... [launchpad]
+ ... min_legitimate_karma: 10
+ ... min_legitimate_account_age: 7
+ ... """
+ >>> config.push("legitimate person", legitimate_person_config)
+
+ >>> new_user_browser = setupBrowser(auth="Basic new@xxxxxxxxxxx:test")
+ >>> new_user_browser.open("http://launchpad.test/new-product")
+ >>> new_user_browser.getLink("Make announcement")
+ Traceback (most recent call last):
+ ...
+ zope.testbrowser.browser.LinkNotFoundError
+
+ >>> new_user_browser.open("http://launchpad.test/new-distribution")
+ >>> new_user_browser.getLink("Make announcement")
+ Traceback (most recent call last):
+ ...
+ zope.testbrowser.browser.LinkNotFoundError
+
+ >>> new_user_browser.open("http://launchpad.test/new-project")
+ >>> new_user_browser.getLink("Make announcement")
+ Traceback (most recent call last):
+ ...
+ zope.testbrowser.browser.LinkNotFoundError
+ >>> config.pop("legitimate person")
+ (...)
+
>>> priv_browser = setupBrowser(auth="Basic mark@xxxxxxxxxxx:test")
>>> priv_browser.open("http://launchpad.test/ubuntu")
>>> link = priv_browser.getLink("Make announcement")
Follow ups