Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x backport] Do not break if a syndication feed comes from a protected resource #378

Merged
merged 2 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/374.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Do not break if a syndication feed comes from a protected resource.
[ale-rt]
54 changes: 54 additions & 0 deletions plone/app/layout/links/tests/test_rssviewlet.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
from plone.app.layout.links.viewlets import RSSViewlet
from plone.app.layout.viewlets.tests.base import ViewletsTestCase
from plone.app.testing import login
from plone.app.testing import logout
from plone.app.testing import setRoles
from plone.app.testing import TEST_USER_ID
from plone.app.testing import TEST_USER_NAME
from plone.base.interfaces import ISiteSyndicationSettings
from plone.registry.interfaces import IRegistry
from zope.component import getUtility

import re


class TestRSSViewletView(ViewletsTestCase):
def test_RSSViewlet(self):
Expand All @@ -30,3 +35,52 @@ def test_RSSViewlet(self):
self.assertFalse("<link" not in result)
self.assertFalse("http://nohost/plone/atom.xml" not in result)
self.assertFalse("http://nohost/plone/news/atom.xml" not in result)

def test_RSSViewlet_with_private_objs(self):
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.portal.invokeFactory("Folder", "news")
registry = getUtility(IRegistry)
settings = registry.forInterface(ISiteSyndicationSettings)
self.assertTrue(settings.allowed)

# Stream a private folder
self.portal.news.invokeFactory("Collection", "aggregator")
settings.site_rss_items = (self.portal.news.aggregator.UID(),)
request = self.layer["request"]

link_href_pattern = re.compile(r'<link href="(.*?)"')

# Verify that anonymous users can't see the RSS feed
# from the aggregator collection
logout()
viewlet = RSSViewlet(self.portal, request.clone(), None, None)
viewlet.update()
result = viewlet.render()

self.assertSetEqual(
{
"http://nohost/plone/atom.xml",
"http://nohost/plone/rss.xml",
"http://nohost/plone/RSS",
},
{match.group(1) for match in link_href_pattern.finditer(result)},
)

login(self.portal, TEST_USER_NAME)
viewlet = RSSViewlet(self.portal, request.clone(), None, None)
viewlet.update()
result = viewlet.render()

# Verify that an authenticated user can see the RSS feed
# from the aggregator collection
self.assertSetEqual(
{
"http://nohost/plone/atom.xml",
"http://nohost/plone/rss.xml",
"http://nohost/plone/RSS",
"http://nohost/plone/news/aggregator/atom.xml",
"http://nohost/plone/news/aggregator/rss.xml",
"http://nohost/plone/news/aggregator/RSS",
},
{match.group(1) for match in link_href_pattern.finditer(result)},
)
8 changes: 7 additions & 1 deletion plone/app/layout/links/viewlets.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from AccessControl import Unauthorized
from Acquisition import aq_inner
from plone.app.layout.viewlets import ViewletBase
from plone.app.uuid.utils import uuidToObject
Expand Down Expand Up @@ -156,7 +157,12 @@ def update(self):
for uid in settings.site_rss_items:
if not uid:
continue
obj = uuidToObject(uid)
try:
obj = uuidToObject(uid)
except Unauthorized:
# Do not break if we do not have enough permission
# to access the object
obj = None
if obj is None and uid[0] == "/":
obj = portal.restrictedTraverse(uid.lstrip("/"), None)
if obj is not None:
Expand Down