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

Removed the docstring from methods to avoid publishing them [6.0] #3282

Merged
merged 1 commit into from
Jun 21, 2021
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
164 changes: 83 additions & 81 deletions Products/CMFPlone/PloneTool.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,9 @@ def getIconFor(self, category, id, default=_marker, context=None):

@security.protected(View)
def getReviewStateTitleFor(self, obj):
"""Utility method that gets the workflow state title for the
object's review_state.

Returns None if no review_state found.
"""
# Utility method that gets the workflow state title for the
# object's review_state.
# Returns None if no review_state found.
wf_tool = getToolByName(self, 'portal_workflow')
wfs = ()
objstate = None
Expand Down Expand Up @@ -395,18 +393,17 @@ def fixOwnerRole(object, user_id):

@security.public
def urlparse(self, url):
"""Returns the pieces of url in a six-part tuple.

Since Python 2.6: urlparse now returns a ParseResult object.
We just need the tuple form which is tuple(result).
"""
# Returns the pieces of url in a six-part tuple.
# Since Python 2.6: urlparse now returns a ParseResult object.
# We just need the tuple form which is tuple(result).
# Note: no docstring please, to avoid reflected XSS.
return tuple(parse.urlparse(url))

@security.public
def urlunparse(self, url_tuple):
"""Puts a url back together again, in the manner that
urlparse breaks it.
"""
# Puts a url back together again, in the manner that
# urlparse breaks it.
# Note: no docstring please, to avoid reflected XSS.
return parse.urlunparse(url_tuple)

# Enable scripts to get the string value of an exception even if the
Expand Down Expand Up @@ -539,30 +536,32 @@ def getDefaultPage(self, obj, request=None):

@security.public
def addPortalMessage(self, message, type='info', request=None):
"""\
Call this once or more to add messages to be displayed at the
top of the web page.

The arguments are:
message: a string, with the text message you want to show,
or a HTML fragment (see type='structure' below)
type: optional, defaults to 'info'. The type determines how
the message will be rendered, as it is used to select
the CSS class for the message. Predefined types are:
'info' - for informational messages
'warning' - for warning messages
'error' - for messages about restricted access or
errors.

Portal messages are by default rendered by the global_statusmessage.pt
page template.

It is also possible to add messages from page templates, as
long as they are processed before the portal_message macro is
called by the main template. Example:

<tal:block tal:define="temp python:context.plone_utils.addPortalMessage('A random info message')" /> # noqa
"""
# Call this once or more to add messages to be displayed at the
# top of the web page.

# Note: no docstring please, to avoid reflected XSS.
# This might not be possible, but type="structure" below sounds dangerous,
# although I find no support for it in code.

# The arguments are:
# message: a string, with the text message you want to show,
# or a HTML fragment (see type='structure' below)
# type: optional, defaults to 'info'. The type determines how
# the message will be rendered, as it is used to select
# the CSS class for the message. Predefined types are:
# 'info' - for informational messages
# 'warning' - for warning messages
# 'error' - for messages about restricted access or
# errors.

# Portal messages are by default rendered by the global_statusmessage.pt
# page template.

# It is also possible to add messages from page templates, as
# long as they are processed before the portal_message macro is
# called by the main template. Example:

# <tal:block tal:define="temp python:context.plone_utils.addPortalMessage('A random info message')" /> # noqa
if request is None:
request = self.REQUEST
IStatusMessage(request).add(message, type=type)
Expand All @@ -580,42 +579,43 @@ def showPortalMessages(self, request=None):

@security.public
def browserDefault(self, obj):
"""Sets default so we can return whatever we want instead of index_html.

This method is complex, and interacts with mechanisms such as
IBrowserDefault (implemented in CMFDynamicViewFTI), LinguaPlone and
various mechanisms for setting the default page.

The method returns a tuple (obj, [path]) where path is a path to
a template or other object to be acquired and displayed on the object.
The path is determined as follows:

0. If we're c oming from WebDAV, make sure we don't return a contained
object "default page" ever
1. If there is an index_html attribute (either a contained object or
an explicit attribute) on the object, return that as the
"default page". Note that this may be used by things like
File and Image to return the contents of the file, for example,
not just content-space objects created by the user.
2. If the object implements IBrowserDefault, query this for the
default page.
3. If the object has a property default_page set and this gives a list
of, or single, object id, and that object is is found in the
folder or is the name of a skin template, return that id
4. If the property default_page is set in site_properties and that
property contains a list of ids of which one id is found in the
folder, return that id
5. If the object implements IBrowserDefault, try to get the selected
layout.
6. If the type has a 'folderlisting' action and no default page is
set, use this action. This permits folders to have the default
'view' action be 'string:${object_url}/' and hence default to
a default page when clicking the 'view' tab, whilst allowing the
fallback action to be specified TTW in portal_types (this action
is typically hidden)
7. If nothing else is found, fall back on the object's 'view' action.
8. If this is not found, raise an AttributeError
"""
# Sets default so we can return whatever we want instead of index_html.

# Note: no docstring please, to avoid reflected XSS.

# This method is complex, and interacts with mechanisms such as
# IBrowserDefault (implemented in CMFDynamicViewFTI), LinguaPlone and
# various mechanisms for setting the default page.

# The method returns a tuple (obj, [path]) where path is a path to
# a template or other object to be acquired and displayed on the object.
# The path is determined as follows:

# 0. If we're c oming from WebDAV, make sure we don't return a contained
# object "default page" ever
# 1. If there is an index_html attribute (either a contained object or
# an explicit attribute) on the object, return that as the
# "default page". Note that this may be used by things like
# File and Image to return the contents of the file, for example,
# not just content-space objects created by the user.
# 2. If the object implements IBrowserDefault, query this for the
# default page.
# 3. If the object has a property default_page set and this gives a list
# of, or single, object id, and that object is is found in the
# folder or is the name of a skin template, return that id
# 4. If the property default_page is set in site_properties and that
# property contains a list of ids of which one id is found in the
# folder, return that id
# 5. If the object implements IBrowserDefault, try to get the selected
# layout.
# 6. If the type has a 'folderlisting' action and no default page is
# set, use this action. This permits folders to have the default
# 'view' action be 'string:${object_url}/' and hence default to
# a default page when clicking the 'view' tab, whilst allowing the
# fallback action to be specified TTW in portal_types (this action
# is typically hidden)
# 7. If nothing else is found, fall back on the object's 'view' action.
# 8. If this is not found, raise an AttributeError

# WebDAV in Zope is odd it takes the incoming verb eg: PROPFIND
# and then requests that object, for example for: /, with verb PROPFIND
Expand Down Expand Up @@ -777,22 +777,23 @@ def isLocalRoleAcquired(self, obj):

@security.public
def getOwnerName(self, obj):
""" Returns the userid of the owner of an object."""
# Returns the userid of the owner of an object.
# Note: no docstring please, to avoid reflected XSS.
mt = getToolByName(self, 'portal_membership')
if not mt.checkPermission(View, obj):
raise Unauthorized
return obj.getOwner().getId()

@security.public
def normalizeString(self, text):
"""Normalizes a title to an id.
# Normalizes a title to an id.
# Note: no docstring please, to avoid reflected XSS.

The relaxed mode was removed in Plone 4.0. You should use either the
url or file name normalizer from the plone.i18n package instead.
# The relaxed mode was removed in Plone 4.0. You should use either the
# url or file name normalizer from the plone.i18n package instead.

normalizeString() converts a whole string to a normalized form that
should be safe to use as in a url, as a css id, etc.
"""
# normalizeString() converts a whole string to a normalized form that
# should be safe to use as in a url, as a css id, etc.
return utils.normalizeString(text, context=self)

@security.public
Expand Down Expand Up @@ -951,7 +952,8 @@ def isIDAutoGenerated(self, id):

@security.public
def getEmptyTitle(self, translated=True):
"""Returns string to be used for objects with no title or id."""
# Returns string to be used for objects with no title or id.
# Note: no docstring please, to avoid reflected XSS.
return utils.getEmptyTitle(self, translated)

@security.public
Expand Down
22 changes: 14 additions & 8 deletions Products/CMFPlone/patches/publishing.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
# From Products.PloneHotfix20160419
# Plus extras for properties.
# Plus Products.PloneHotfix20210518.
from OFS.PropertyManager import PropertyManager
from Products.CMFPlone.Portal import PloneSite
from plone.dexterity.content import Item
from plone.dexterity.content import Container


def delete_method_docstring(klass, method_name):
# Delete the docstring from the class method.
# Objects must have a docstring to be published.
# So this avoids them getting published.
method = getattr(klass, method_name, None)
if method is None:
return
if hasattr(method, "__doc__"):
del method.__doc__


klasses = (
# Node,
# Document,
Expand Down Expand Up @@ -36,10 +48,7 @@

for klass in klasses:
for method_name in methods:
method = getattr(klass, method_name, None)
if (method is not None and hasattr(method, 'im_func') and
hasattr(method.im_func, '__doc__')):
del method.im_func.__doc__
delete_method_docstring(klass, method_name)

property_methods = (
'getProperty',
Expand All @@ -54,7 +63,4 @@
)

for method_name in property_methods:
method = getattr(PropertyManager, method_name, None)
if (method is not None and hasattr(method, 'im_func') and
hasattr(method.im_func, '__doc__')):
del method.im_func.__doc__
delete_method_docstring(PropertyManager, method_name)
Loading