Skip to content

Instantly share code, notes, and snippets.

@rnixx
Created July 18, 2013 07:47
Show Gist options
  • Save rnixx/6027502 to your computer and use it in GitHub Desktop.
Save rnixx/6027502 to your computer and use it in GitHub Desktop.
patch for plone.app.async providing REQUEST on context
"""plone.app.async patch to provide old school Zope2 REQUEST on context.
Contributions:
* Jean Jordaan
* Robert Niederreiter
"""
import Zope2
import sys
from AccessControl.SecurityManagement import (
noSecurityManager,
newSecurityManager,
)
from zExceptions import BadRequest
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.HTTPRequest import HTTPRequest
from zope.component.hooks import setSite
from plone.app.async import service
def _executeAsUser(context_path, portal_path, uf_path,
user_id, func, *args, **kwargs):
"""Reconstruct environment and execute func.
"""
transaction = Zope2.zpublisher_transactions_manager # Supports isDoomed
transaction.begin()
app = Zope2.app()
result = None
try:
try:
portal = app.unrestrictedTraverse(portal_path, None)
if portal is None:
raise BadRequest(
'Portal path %s not found' % '/'.join(portal_path))
setSite(portal)
if uf_path:
acl_users = app.unrestrictedTraverse(uf_path, None)
if acl_users is None:
raise BadRequest(
'Userfolder path %s not found' % '/'.join(uf_path))
user = acl_users.getUserById(user_id)
if user is None:
raise BadRequest('User %s not found' % user_id)
newSecurityManager(None, user)
context = portal.unrestrictedTraverse(context_path, None)
if context is None:
raise BadRequest(
'Context path %s not found' % '/'.join(context_path))
# Create a request to work with
response = HTTPResponse(stdout=sys.stdout)
env = {'SERVER_NAME':'fake_server',
'SERVER_PORT':'80',
'REQUEST_METHOD':'GET'}
request = HTTPRequest(sys.stdin, env, response)
# Set values from original request
original_request = kwargs.get('original_request')
if original_request:
for k,v in original_request.items():
request.set(k, v)
context.REQUEST = request
result = func(context, *args, **kwargs)
# Avoid "can't pickle file objects"
del context.REQUEST
transaction.commit()
except:
transaction.abort()
raise
finally:
noSecurityManager()
setSite(None)
app._p_jar.close()
return result
service._executeAsUser = _executeAsUser
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment