Skip to content

Commit

Permalink
Add back proxy role support.
Browse files Browse the repository at this point in the history
  • Loading branch information
hannosch committed Oct 30, 2016
1 parent 7b8e55c commit a6dfb8e
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/OFS/DTMLDocument.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DTMLDocument(PropertyManager, DTMLMethod):
def manage_upload(self, file='', REQUEST=None):
""" Replace the contents of the document with the text in 'file'.
"""
self._validateProxy(REQUEST)
if self.wl_isLocked():
raise ResourceLockedError('This document has been locked.')

Expand Down
46 changes: 46 additions & 0 deletions src/OFS/DTMLMethod.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl import getSecurityManager
from AccessControl.Permissions import view_management_screens
from AccessControl.Permissions import change_proxy_roles
from AccessControl.Permissions import view as View # NOQA
from AccessControl.Permissions import ftp_access
from AccessControl.requestmethod import requestmethod
from AccessControl.tainted import TaintedString
from Acquisition import Implicit
from DocumentTemplate.permissions import change_dtml_methods
from DocumentTemplate.security import RestrictedDTML
from six.moves.urllib.parse import quote
from zExceptions import Forbidden
from zExceptions import Redirect
from zExceptions import ResourceLockedError
from zExceptions.TracebackSupplement import PathTracebackSupplement
Expand Down Expand Up @@ -59,6 +62,7 @@ class DTMLMethod(RestrictedDTML,
""" DocumentTemplate.HTML objects that act as methods of their containers.
"""
meta_type = 'DTML Method'
_proxy_roles = ()
index_html = None # Prevent accidental acquisition
_cache_namespace_keys = ()

Expand All @@ -72,6 +76,7 @@ class DTMLMethod(RestrictedDTML,

manage_options = ((
{'label': 'Edit', 'action': 'manage_main'},
{'label': 'Proxy', 'action': 'manage_proxyForm'},
) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Expand Down Expand Up @@ -229,10 +234,14 @@ def get_size(self):
security.declareProtected(change_dtml_methods, 'manage_main')
manage = manage_main = manage_editDocument = manage_editForm

security.declareProtected(change_proxy_roles, 'manage_proxyForm')
manage_proxyForm = DTMLFile('dtml/documentProxy', globals())

security.declareProtected(change_dtml_methods, 'manage_edit')
def manage_edit(self, data, title, SUBMIT='Change', REQUEST=None):
""" Replace contents with 'data', title with 'title'.
"""
self._validateProxy(REQUEST)
if self.wl_isLocked():
raise ResourceLockedError('This item is locked.')

Expand All @@ -251,6 +260,7 @@ def manage_edit(self, data, title, SUBMIT='Change', REQUEST=None):
def manage_upload(self, file='', REQUEST=None):
""" Replace the contents of the document with the text in 'file'.
"""
self._validateProxy(REQUEST)
if self.wl_isLocked():
raise ResourceLockedError('This DTML Method is locked.')

Expand All @@ -265,6 +275,41 @@ def manage_upload(self, file='', REQUEST=None):
message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message)

def manage_haveProxy(self, r):
return r in self._proxy_roles

def _validateProxy(self, request, roles=None):
if roles is None:
roles = self._proxy_roles
if not roles:
return
user = u = getSecurityManager().getUser()
user = user.allowed
for r in roles:
if r and not user(self, (r,)):
user = None
break

if user is not None:
return

raise Forbidden(
'You are not authorized to change <em>%s</em> because you '
'do not have proxy roles.\n<!--%s, %s-->' % (
self.__name__, u, roles))

security.declareProtected(change_proxy_roles, 'manage_proxy')
@requestmethod('POST')
def manage_proxy(self, roles=(), REQUEST=None):
"Change Proxy Roles"
self._validateProxy(REQUEST, roles)
self._validateProxy(REQUEST)
self._proxy_roles = tuple(roles)
if REQUEST:
message = "Saved changes."
return self.manage_proxyForm(self, REQUEST,
manage_tabs_message=message)

security.declareProtected(view_management_screens, 'PrincipiaSearchSource')
def PrincipiaSearchSource(self):
# Support for searching - the document's contents are searched.
Expand All @@ -285,6 +330,7 @@ def PUT(self, REQUEST, RESPONSE):
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
body = REQUEST.get('BODY', '')
self._validateProxy(REQUEST)
self.munge(body)
self.ZCacheable_invalidate()
RESPONSE.setStatus(204)
Expand Down
52 changes: 52 additions & 0 deletions src/OFS/dtml/documentProxy.dtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<dtml-var manage_page_header>
<dtml-with "_(management_view='Proxy')">
<dtml-var manage_tabs>
</dtml-with>

<p class="form-help">
Proxy roles allow you to control the access that a DTML document or
method has. Proxy roles replace the roles of the user who is viewing
the document or method. This can be used to both expand and limit
access to resources. Select the proxy roles for this object from
the list below.
</p>

<form action="manage_proxy" method="post">
<table cellpadding="2" cellspacing="0" border="0">
<tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Proxy Roles
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<select name="roles:list" size="7" multiple>
<dtml-in valid_roles>
<dtml-if expr="_vars['sequence-item'] != 'Shared'">
<option <dtml-if
expr="manage_haveProxy(_vars['sequence-item'])">selected</dtml-if
>>&dtml-sequence-item;</option>
</dtml-if>
</dtml-in valid_roles>
</select>
</div>
</td>
</tr>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<input class="form-element" type="submit" name="SUBMIT" value="Save Changes">
</div>
</td>
</tr>
</table>

</form>

<dtml-var manage_page_footer>




3 changes: 2 additions & 1 deletion src/OFS/dtml/owner.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<p class="form-help">
Almost all Zope objects can be owned. When you create an object you
become its owner. Ownership matters for method objects since
it determines what roles they have when they are executed.
it determines what roles they have when they are executed. See the
<em>Proxy Roles</em> view of method objects for more information.
</p>

<p>
Expand Down

0 comments on commit a6dfb8e

Please sign in to comment.