Skip to content

Commit

Permalink
Porta PR #567 para IDG 2.x.
Browse files Browse the repository at this point in the history
  • Loading branch information
idgserpro committed Aug 13, 2019
1 parent bb57514 commit 8e0756a
Show file tree
Hide file tree
Showing 13 changed files with 597 additions and 21 deletions.
22 changes: 22 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ Changelog
2.1.2 (unreleased)
^^^^^^^^^^^^^^^^^^

- Adiciona Browser Page remote_url_utils.
Tratamento do valor de getRemoteUrl ou remoteUrl para evitar que o path do
site fique exposto nos links.
<https://github.com/plonegovbr/brasil.gov.portal/issues/463>
[idgserpro]

- Adiciona patch para Products.CMFPlone.browser.navtree.SitemapNavtreeStrategy.decoratorFactory
para substituição do path do site pela url em getRemoteUrl.
<https://github.com/plonegovbr/brasil.gov.portal/issues/463>
[idgserpro]

- Altera viewlet servicos para que trate o valor de getRemoteUrl através da
remote_url_utils.
<https://github.com/plonegovbr/brasil.gov.portal/issues/463>
[idgserpro]

- Customiza Browser Page link_redirect_view para que trate o valor de remote_url
através da remote_url_utils; e para que a formação url de links relativos (../, ./)
deixasse de utilizar como base a url do próprio objeto Link.
<https://github.com/plonegovbr/brasil.gov.portal/issues/463>
[idgserpro]

- Adiciona collective.recaptcha. (fecha `#292 <https://github.com/plonegovbr/brasil.gov.portal/issues/292>`_).
[rodfersou]

Expand Down
11 changes: 11 additions & 0 deletions src/brasil/gov/portal/browser/content/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,15 @@
layer="brasil.gov.portal.interfaces.IBrasilGov"
/>

<includeOverrides file="overrides.zcml" />

<!-- RemoteUrlUtils -->
<browser:page
name="remote_url_utils"
for="*"
permission="zope.Public"
class=".remote_url_utils.RemoteUrlUtils"
layer="brasil.gov.portal.interfaces.IBrasilGov"
/>

</configure>
52 changes: 52 additions & 0 deletions src/brasil/gov/portal/browser/content/link_redirect_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-

from plone.app.contenttypes.browser.link_redirect_view import LinkRedirectView as OriginalView
from plone.app.contenttypes.browser.link_redirect_view import NON_RESOLVABLE_URL_SCHEMES
from plone.app.contenttypes.utils import replace_link_variables_by_paths
from zope.component import getMultiAdapter


class LinkRedirectView(OriginalView):
"""
Substituicao do path pela url do site ao utilizar variaveis ${portal_url}
ou ${navigation_root_url} no campo remoteUrl do Link.
Acertada tambem a url de links relativos (../, ./), pois gerava a url
utilizando como base a url do proprio objeto Link.
Isso fazia com que a url, mesmo redirecionando corretamente, ficasse
diferente da real, e não seria atingida pelo purge.
Demanda PR para correção da issue 463:
https://github.com/plonegovbr/brasil.gov.portal/issues/463
"""

def absolute_target_url(self):
"""Compute the absolute target URL."""
url = self.context.remoteUrl

if self._url_uses_scheme(NON_RESOLVABLE_URL_SCHEMES):
# For non http/https url schemes, there is no path to resolve.
return url

remote_url_utils = getMultiAdapter(
(self.context, self.request),
name=u'remote_url_utils',
)
path = '/'.join(self.context.getPhysicalPath())

if url.startswith('.'):
# ./ ../ ../../
url = remote_url_utils.remote_url_transform(
path,
url,
)
else:
url = replace_link_variables_by_paths(self.context, url)
url = remote_url_utils.remote_url_transform(
path,
url,
)
if not url.startswith(('http://', 'https://')):
portal_state = self.context.restrictedTraverse(
'@@plone_portal_state',
)
url = '{0}{1}'.format(portal_state.portal_url(), url)
return url
37 changes: 37 additions & 0 deletions src/brasil/gov/portal/browser/content/overrides.zcml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">

<include package="z3c.unconfigure" file="meta.zcml" />

<!-- override link_redirect_view -->
<!-- Com Interface herdando do layer original ou mesmo no overrides
continuava o erro: ConfigurationConflictError
Foi necessario utilizar unconfigure -->
<include package="plone.app.contenttypes.browser" file="configure.zcml" />
<unconfigure>
<browser:page
name="link_redirect_view"
for="plone.app.contenttypes.interfaces.ILink"
class=".link_redirect_view.LinkRedirectView"
layer="plone.app.contenttypes.interfaces.IPloneAppContenttypesLayer"
permission="zope2.View"
menu="plone_displayviews"
title="View Link"
/>
</unconfigure>

<!-- customize link_redirect_view -->
<configure package="plone.app.contenttypes.browser">
<browser:page
name="link_redirect_view"
for="plone.app.contenttypes.interfaces.ILink"
class="brasil.gov.portal.browser.content.link_redirect_view.LinkRedirectView"
layer="brasil.gov.portal.interfaces.IBrasilGov"
permission="zope2.View"
menu="plone_displayviews"
title="View Link"
/>
</configure>

</configure>
75 changes: 75 additions & 0 deletions src/brasil/gov/portal/browser/content/remote_url_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-

from plone.app.contenttypes.browser.link_redirect_view import NON_RESOLVABLE_URL_SCHEMES
from Products.Five import BrowserView
from zope.component import getMultiAdapter
from zope.interface import implements
from zope.interface import Interface


class IRemoteUrlUtils(Interface):

def _url_uses_scheme(self):
""""""

def remote_url_transform(self):
"""Transforma o path em url do site."""


class RemoteUrlUtils(BrowserView):
"""
Substituicao do path pela url do site.
Utilizado para o tratamento do valor obtido do metadado getRemoteUrl
via portal_catalog e pela visao padrao do tipo Link (link_redirect_view).
Demanda PR para correção da issue 463:
https://github.com/plonegovbr/brasil.gov.portal/issues/463
"""
implements(IRemoteUrlUtils)

def __init__(self, context, request):
self.context = context
self.request = request
self.portal_state = getMultiAdapter(
(self.context, self.request),
name=u'plone_portal_state',
)
self.portal_path = self.portal_state.navigation_root_path()
self.portal_url = self.portal_state.portal_url()

def _url_uses_scheme(self, url=None):
for scheme in NON_RESOLVABLE_URL_SCHEMES:
if url.startswith(scheme):
return True
return False

def remote_url_transform(self, path=None, url=None):
"""Transforma o path em url do site."""
if url:
# http:// https://
if url.startswith('http://') or url.startswith('https://'):
return url
# file: ftp: mailto: webdav: ...
if self._url_uses_scheme(url):
return url
# ./ ../
if path:
if url.startswith('.'):
path_items = path.split('/')
url_items = url.split('/')
# ./
if url_items[0] == '.':
url = url.replace(
'./',
'/'.join(path_items[:-1]) + '/',
)
# ../ ../../../
elif url_items[0] == '..':
count = url.count('../')
position = count + 1
url = url.replace(
'../' * count,
'/'.join(path_items[:-position]) + '/',
)
# /path/site
url = url.replace(self.portal_path, self.portal_url)
return url
38 changes: 30 additions & 8 deletions src/brasil/gov/portal/browser/viewlets/servicos.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
""" Modulo que implementa o viewlet de servicos do Portal"""
from plone.app.layout.viewlets import ViewletBase
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.component import getMultiAdapter


class ServicosViewlet(ViewletBase):
Expand All @@ -14,8 +15,18 @@ def update(self):
""" Prepara/Atualiza os valores utilizados pelo Viewlet
"""
super(ServicosViewlet, self).update()
ps = self.context.restrictedTraverse('@@plone_portal_state')
tools = self.context.restrictedTraverse('@@plone_tools')
ps = getMultiAdapter(
(self.context, self.request),
name='plone_portal_state',
)
tools = getMultiAdapter(
(self.context, self.request),
name='plone_tools',
)
self.remote_url_utils = getMultiAdapter(
(self.context, self.request),
name='remote_url_utils',
)
portal = ps.portal()
self._folder = 'servicos' in portal.objectIds() and portal['servicos']
self._ct = tools.catalog()
Expand All @@ -24,10 +35,21 @@ def available(self):
return self._folder and True or False

def servicos(self):
ct = self._ct
folder_path = '/'.join(self._folder.getPhysicalPath())
portal_types = ['Link']
results = ct.searchResults(portal_type=portal_types,
path=folder_path,
sort_on='getObjPositionInParent')
return results
query = {
'portal_type': ['Link'],
'path': folder_path,
'sort_on': 'getObjPositionInParent',
}
return [
{
'getId': l.getId,
'Title': l.Title,
'Description': l.Description,
'getRemoteUrl': self.remote_url_utils.remote_url_transform(
l.getPath(),
l.getRemoteUrl,
),
}
for l in self._ct(query)
]
11 changes: 2 additions & 9 deletions src/brasil/gov/portal/browser/viewlets/templates/servicos.pt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,8 @@
class string:portalservicos-item;">
<a href=""
tal:content="tab/Title"
tal:condition="tab/Description"
tal:attributes="href tab/getURL;
title tab/Description|nothing;">
Tab Name
</a>
<a href=""
tal:content="tab/Title"
tal:condition="not:tab/Description"
tal:attributes="href tab/getRemoteUrl">
tal:attributes="href tab/getRemoteUrl;
title python:tab['Description'] and tab['Description'] or None;">
Tab Name
</a>
</li>
Expand Down
77 changes: 77 additions & 0 deletions src/brasil/gov/portal/patches.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# -*- coding: utf-8 -*-
from Acquisition import aq_inner
from brasil.gov.portal.logger import logger
from plone.app.contenttypes.content import Link
from plone.i18n.normalizer.interfaces import IIDNormalizer
from plone.outputfilters.filters import resolveuid_and_caption as base
from Products.CMFPlone import utils
from zope.component import getMultiAdapter
from zope.component import queryUtility


def outputfilters():
Expand Down Expand Up @@ -54,6 +59,78 @@ def image_tag(self):
return self._old_image_tag()


def decoratorFactory(self, node):
"""Substituicao do path pela url do site ao utilizar o metadado getRemoteUrl
obtido via portal_catalog.
Demanda PR para correção da issue 463:
https://github.com/plonegovbr/brasil.gov.portal/issues/463
"""
context = aq_inner(self.context)
request = context.REQUEST

newNode = node.copy()
item = node['item']

portalType = getattr(item, 'portal_type', None)
itemUrl = item.getURL()
if portalType is not None and portalType in self.viewActionTypes:
itemUrl += '/view'

useRemoteUrl = False
getRemoteUrl = getattr(item, 'getRemoteUrl', None)
isCreator = self.memberId == getattr(item, 'Creator', None)
if getRemoteUrl and not isCreator:
useRemoteUrl = True

isFolderish = getattr(item, 'is_folderish', None)
showChildren = False
if isFolderish and \
(portalType is None or portalType not in self.parentTypesNQ):
showChildren = True

ploneview = getMultiAdapter((context, request), name=u'plone')

newNode['Title'] = utils.pretty_title_or_id(context, item)
newNode['id'] = item.getId
newNode['UID'] = item.UID
newNode['absolute_url'] = itemUrl
newNode['getURL'] = itemUrl
newNode['path'] = item.getPath()
newNode['item_icon'] = ploneview.getIcon(item)
newNode['Creator'] = getattr(item, 'Creator', None)
newNode['creation_date'] = getattr(item, 'CreationDate', None)
newNode['portal_type'] = portalType
newNode['review_state'] = getattr(item, 'review_state', None)
newNode['Description'] = getattr(item, 'Description', None)
newNode['show_children'] = showChildren
newNode['no_display'] = False # We sort this out with the nodeFilter
# BBB getRemoteUrl and link_remote are deprecated, remove in Plone 4
# patch: Substitui o path pela url do site.
remote_url_utils = getMultiAdapter(
(context, request),
name=u'remote_url_utils',
)
remote_url = item.getRemoteUrl and item.getRemoteUrl or None
newNode['getRemoteUrl'] = remote_url_utils.remote_url_transform(
newNode['path'],
remote_url,
)
# patch
newNode['useRemoteUrl'] = useRemoteUrl
newNode['link_remote'] = newNode['getRemoteUrl'] \
and newNode['Creator'] != self.memberId

idnormalizer = queryUtility(IIDNormalizer)
newNode['normalized_portal_type'] = idnormalizer.normalize(portalType)
newNode['normalized_review_state'] = \
idnormalizer.normalize(newNode['review_state'])
newNode['normalized_id'] = idnormalizer.normalize(newNode['id'])

return newNode

logger.info('Patched Products.CMFPlone.browser.navtree.SitemapNavtreeStrategy:decoratorFactory:191')


def run():
outputfilters()
link()
7 changes: 7 additions & 0 deletions src/brasil/gov/portal/patches.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,11 @@
preserveOriginal="True"
/>

<monkey:patch
description="Substituicao do path pela url do site em getRemoteUrl."
class="Products.CMFPlone.browser.navtree.SitemapNavtreeStrategy"
original="decoratorFactory"
replacement=".patches.decoratorFactory"
/>

</configure>
Loading

0 comments on commit 8e0756a

Please sign in to comment.