Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
139
Merge Requests
139
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
adc331f1
Commit
adc331f1
authored
Apr 17, 2019
by
Bryton Lacquement
🚪
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
patches/WSGIPublisher: make the backport compatible with Zope2
Parts of ZPublisher.utils are also backported.
parent
91a48711
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
115 additions
and
43 deletions
+115
-43
product/ERP5Type/ZopePatch.py
product/ERP5Type/ZopePatch.py
+1
-0
product/ERP5Type/patches/WSGIPublisher.py
product/ERP5Type/patches/WSGIPublisher.py
+114
-43
No files found.
product/ERP5Type/ZopePatch.py
View file @
adc331f1
...
...
@@ -22,6 +22,7 @@
# Load all monkey patches
from
Products.ERP5Type.patches
import
backports
from
Products.ERP5Type.patches
import
WSGIPublisher
from
Products.ERP5Type.patches
import
HTTPRequest
from
Products.ERP5Type.patches
import
AccessControl_patch
from
Products.ERP5Type.patches
import
Restricted
...
...
product/ERP5Type/patches/WSGIPublisher.py
View file @
adc331f1
# Backport from Zope4
# Backport
(with modified code)
from Zope4
##############################################################################
#
...
...
@@ -19,16 +19,22 @@ from contextlib import closing
from
contextlib
import
contextmanager
from
io
import
BytesIO
from
io
import
IOBase
import
logging
from
six
import
binary_type
from
six
import
PY3
from
six
import
reraise
from
six
import
text_type
from
six.moves._thread
import
allocate_lock
import
transaction
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl.SecurityManagement
import
noSecurityManager
from
Acquisition
import
aq_acquire
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
from
transaction.interfaces
import
TransientError
from
zExceptions
import
Redirect
from
zExceptions
import
Unauthorized
from
zExceptions
import
upgradeException
from
zope.component
import
queryMultiAdapter
...
...
@@ -38,12 +44,12 @@ from zope.globalrequest import setRequest
from
zope.publisher.skinnable
import
setDefaultSkin
from
zope.security.management
import
endInteraction
from
zope.security.management
import
newInteraction
from
Z
Publisher
import
pubevents
from
ZPublisher
.HTTPRequest
import
WSGIRequest
from
ZPublisher.HTTPRe
sponse
import
WSGIResponse
from
Z
ope2.App.startup
import
validated_hook
from
ZPublisher
import
pubevents
,
Retry
from
ZPublisher.HTTPRe
quest
import
HTTPRequest
from
ZPublisher.Iterators
import
IUnboundStreamIterator
from
ZPublisher.mapply
import
mapply
from
ZPublisher.
utils
import
recordMetaData
from
ZPublisher.
WSGIPublisher
import
call_object
,
missing_name
,
WSGIResponse
if
sys
.
version_info
>=
(
3
,
):
...
...
@@ -57,32 +63,69 @@ _MODULE_LOCK = allocate_lock()
_MODULES
=
{}
def
call_object
(
obj
,
args
,
request
):
return
obj
(
*
args
)
AC_LOGGER
=
logging
.
getLogger
(
'event.AccessControl'
)
def
dont_publish_class
(
klass
,
request
):
request
.
response
.
forbiddenError
(
"class %s"
%
klass
.
__name__
)
def
missing_name
(
name
,
request
):
if
name
==
'self'
:
return
request
[
'PARENTS'
][
0
]
request
.
response
.
badRequestError
(
name
)
# From ZPublisher.utils
def
recordMetaData
(
object
,
request
):
if
hasattr
(
object
,
'getPhysicalPath'
):
path
=
'/'
.
join
(
object
.
getPhysicalPath
())
else
:
# Try hard to get the physical path of the object,
# but there are many circumstances where that's not possible.
to_append
=
()
if
hasattr
(
object
,
'__self__'
)
and
hasattr
(
object
,
'__name__'
):
# object is a Python method.
to_append
=
(
object
.
__name__
,)
object
=
object
.
__self__
while
object
is
not
None
and
not
hasattr
(
object
,
'getPhysicalPath'
):
if
getattr
(
object
,
'__name__'
,
None
)
is
None
:
object
=
None
break
to_append
=
(
object
.
__name__
,)
+
to_append
object
=
aq_parent
(
aq_inner
(
object
))
if
object
is
not
None
:
path
=
'/'
.
join
(
object
.
getPhysicalPath
()
+
to_append
)
else
:
# As Jim would say, "Waaaaaaaa!"
# This may cause problems with virtual hosts
# since the physical path is different from the path
# used to retrieve the object.
path
=
request
.
get
(
'PATH_INFO'
)
def
validate_user
(
request
,
user
):
newSecurityManager
(
request
,
user
)
T
=
transaction
.
get
()
T
.
note
(
safe_unicode
(
path
))
auth_user
=
request
.
get
(
'AUTHENTICATED_USER'
,
None
)
if
auth_user
:
auth_folder
=
aq_parent
(
auth_user
)
if
auth_folder
is
None
:
AC_LOGGER
.
warning
(
'A user object of type %s has no aq_parent.'
,
type
(
auth_user
))
auth_path
=
request
.
get
(
'AUTHENTICATION_PATH'
)
else
:
auth_path
=
'/'
.
join
(
auth_folder
.
getPhysicalPath
()[
1
:
-
1
])
user_id
=
auth_user
.
getId
()
user_id
=
safe_unicode
(
user_id
)
if
user_id
else
u'None'
T
.
setUser
(
user_id
,
safe_unicode
(
auth_path
))
def
set_default_debug_mode
(
debug_mode
):
global
_DEFAULT_DEBUG_MODE
_DEFAULT_DEBUG_MODE
=
debug_mode
def
safe_unicode
(
value
):
if
isinstance
(
value
,
text_type
):
return
value
elif
isinstance
(
value
,
binary_type
):
try
:
value
=
text_type
(
value
,
'utf-8'
)
except
UnicodeDecodeError
:
value
=
value
.
decode
(
'utf-8'
,
'replace'
)
return
value
def
set_default_authentication_realm
(
realm
):
global
_DEFAULT_REALM
_DEFAULT_REALM
=
realm
def
dont_publish_class
(
klass
,
request
):
request
.
response
.
forbiddenError
(
"class %s"
%
klass
.
__name__
)
def
get_module_info
(
module_name
=
'Zope2'
):
...
...
@@ -95,7 +138,8 @@ def get_module_info(module_name='Zope2'):
module
=
__import__
(
module_name
)
app
=
getattr
(
module
,
'bobo_application'
,
module
)
realm
=
_DEFAULT_REALM
if
_DEFAULT_REALM
is
not
None
else
module_name
_MODULES
[
module_name
]
=
info
=
(
app
,
realm
,
_DEFAULT_DEBUG_MODE
)
error_hook
=
getattr
(
module
,
'zpublisher_exception_hook'
,
None
)
_MODULES
[
module_name
]
=
info
=
(
app
,
realm
,
_DEFAULT_DEBUG_MODE
,
error_hook
)
return
info
...
...
@@ -135,7 +179,7 @@ def _exc_view_created_response(exc, request, response):
@
contextmanager
def
transaction_pubevents
(
request
,
response
,
tm
=
transaction
.
manager
):
def
transaction_pubevents
(
request
,
response
,
err_hook
,
tm
=
transaction
.
manager
):
try
:
setDefaultSkin
(
request
)
newInteraction
()
...
...
@@ -166,6 +210,31 @@ def transaction_pubevents(request, response, tm=transaction.manager):
if
request
.
environ
.
get
(
'x-wsgiorg.throw_errors'
,
False
):
reraise
(
*
exc_info
)
if
err_hook
:
parents
=
request
[
'PARENTS'
]
if
parents
:
parents
=
parents
[
0
]
retry
=
False
try
:
try
:
r
=
err_hook
(
parents
,
request
,
*
exc_info
)
assert
r
is
response
exc_view_created
=
True
except
Retry
:
if
request
.
supports_retry
():
retry
=
True
else
:
r
=
err_hook
(
parents
,
request
,
*
sys
.
exc_info
())
assert
r
is
response
exc_view_created
=
True
except
(
Redirect
,
Unauthorized
):
response
.
exception
()
exc_view_created
=
True
except
BaseException
as
e
:
if
e
is
not
exc
:
raise
exc_view_created
=
False
else
:
# Handle exception view
exc_view_created
=
_exc_view_created_response
(
exc
,
request
,
response
)
...
...
@@ -178,9 +247,7 @@ def transaction_pubevents(request, response, tm=transaction.manager):
response
.
_unauthorized
()
response
.
setStatus
(
exc
.
getStatus
())
retry
=
False
if
isinstance
(
exc
,
TransientError
)
and
request
.
supports_retry
():
retry
=
True
retry
=
isinstance
(
exc
,
TransientError
)
and
request
.
supports_retry
()
notify
(
pubevents
.
PubBeforeAbort
(
request
,
exc_info
,
retry
))
tm
.
abort
()
...
...
@@ -217,7 +284,7 @@ def publish(request, module_info):
path
=
request
.
get
(
'PATH_INFO'
)
request
[
'PARENTS'
]
=
[
obj
]
obj
=
request
.
traverse
(
path
,
validated_hook
=
validate
_user
)
obj
=
request
.
traverse
(
path
,
validated_hook
=
validate
d_hook
)
notify
(
pubevents
.
PubAfterTraversal
(
request
))
recordMetaData
(
obj
,
request
)
...
...
@@ -245,7 +312,7 @@ def load_app(module_info):
try
:
yield
(
app
,
realm
,
debug_mode
)
finally
:
if
transaction
.
manager
.
manager
.
_txn
is
not
None
:
if
transaction
.
manager
.
_txn
is
not
None
:
# Only abort a transaction, if one exists. Otherwise the
# abort creates a new transaction just to abort it.
transaction
.
abort
()
...
...
@@ -257,9 +324,10 @@ def publish_module(environ, start_response,
_response
=
None
,
_response_factory
=
WSGIResponse
,
_request
=
None
,
_request_factory
=
WSGI
Request
,
_request_factory
=
HTTP
Request
,
_module_name
=
'Zope2'
):
module_info
=
get_module_info
(
_module_name
)
module_info
,
err_hook
=
module_info
[:
3
],
module_info
[
3
]
result
=
()
path_info
=
environ
.
get
(
'PATH_INFO'
)
...
...
@@ -294,7 +362,7 @@ def publish_module(environ, start_response,
setRequest
(
request
)
try
:
with
load_app
(
module_info
)
as
new_mod_info
:
with
transaction_pubevents
(
request
,
response
):
with
transaction_pubevents
(
request
,
response
,
err_hook
):
response
=
_publish
(
request
,
new_mod_info
)
break
except
TransientError
:
...
...
@@ -324,3 +392,6 @@ def publish_module(environ, start_response,
# Return the result body iterable.
return
result
sys
.
modules
[
'ZPublisher.WSGIPublisher'
]
=
sys
.
modules
[
__name__
]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment