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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Cédric Le Ninivin
erp5
Commits
6f2014a7
Commit
6f2014a7
authored
Apr 09, 2024
by
Titouan Soulard
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_api_style: rewrite most of `jIOWebSection`
parent
b815419f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
96 additions
and
106 deletions
+96
-106
bt5/erp5_api_style/DocumentTemplateItem/portal_components/document.erp5.jIOWebSection.py
...lateItem/portal_components/document.erp5.jIOWebSection.py
+96
-106
No files found.
bt5/erp5_api_style/DocumentTemplateItem/portal_components/document.erp5.jIOWebSection.py
View file @
6f2014a7
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
##############################################################################
##############################################################################
#
#
# Copyright (c) 2016 Nexedi SA and Contributors. All Rights Reserved.
# Copyright (c) 2024 Nexedi SA and Contributors. All Rights Reserved.
# Cédric Le Ninivin <cedric.leninivin@nexedi.com>
#
#
# WARNING: This program as such is intended to be used by professional
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# programmers who take the whole responsability of assessing all potential
...
@@ -28,90 +27,104 @@
...
@@ -28,90 +27,104 @@
##############################################################################
##############################################################################
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
Unauthorized
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_inner
from
OFS.Traversable
import
NotFound
from
erp5.component.document.WebSection
import
WebSection
from
OFS.Traversable
import
NotFound
,
Unauthorized
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type
import
Permissions
from
zExceptions
import
HTTPClientError
from
zLOG
import
LOG
,
INFO
from
erp5.component.mixin.DocumentExtensibleTraversableMixin
import
DocumentExtensibleTraversableMixin
from
erp5.component.document.WebSection
import
WebSection
MARKER
=
[]
MARKER
=
[]
ALLOWED_MODES
=
[
"put"
,
"get"
,
"post"
,
"allDocs"
]
class
jIOError
(
object
):
"""
Describes a JSON error, to avoid ERP5 default error pages.
Publishable but non-Persistent (since errors are logged in a separate module) and without Acquisition.
"""
def
__init__
(
self
,
context
,
portal
,
request
):
self
.
context
=
context
self
.
portal
=
portal
self
.
request
=
request
# Redefine an Unauthorized error to avoid Zope redirecting the user to the main ERP5 login form
# Method not expected to be called without context, return Bad Request
class
jIOUnauthorized
(
HTTPClientError
):
if
not
self
.
context
:
errmsg
=
'Unauthorized'
self
.
context
=
{
status
=
401
"error_code"
:
400
,
"error_name"
:
"BadRequest"
}
def
__init__
(
self
,
underlyingError
):
self
.
context
[
"text_content"
]
=
request
.
get
(
"BODY"
)
HTTPClientError
.
__init__
(
self
)
self
.
underlyingError
=
underlyingError
# Used for debugging, especially in tests
def
__str__
(
self
):
def
__str__
(
self
):
return
str
(
self
.
underlyingError
)
return
str
(
self
.
context
)
def
__bytes__
(
self
):
def
__call__
(
self
):
return
bytes
(
self
.
underlyingError
)
portal
=
self
.
portal
response
=
self
.
request
.
response
def
convertTojIOAPICall
(
function
):
response
.
setHeader
(
"Content-Type"
,
"application/json"
)
response
.
setStatus
(
self
.
context
[
"error_code"
],
lock
=
True
)
# Skin used to allow replacement and because Manager proxy role is needed
error_log
=
portal
.
ERP5Site_logApiErrorAndReturn
(
**
self
.
context
)
response
.
setBody
(
error_log
,
lock
=
True
)
class
jIOMethod
(
object
):
"""
"""
Wrap the method to create a log entry for each invocation to the zope logger
Represents one of the four possible jIO methods.
Publishable but non-Persistent and without Acquisition.
XXX: Acquisition might be suitable here
"""
"""
def
wrapper
(
self
,
*
args
,
**
kwd
):
"""
def
__init__
(
self
,
mode_name
,
web_section
):
Log the call, and the result of the call
super
(
jIOMethod
,
self
).
__init__
()
"""
self
.
mode_name
=
mode_name
#assert(self.REQUEST.REQUEST_METHOD == "POST")
self
.
web_section
=
web_section
def
__call__
(
self
):
self
.
web_section
.
REQUEST
.
response
.
setHeader
(
"Content-Type"
,
"application/json"
)
try
:
try
:
self
.
REQUEST
.
response
.
setHeader
(
"Content-Type"
,
"application/json"
)
return
self
.
web_section
.
ERP5Site_asjIOStyle
(
retval
=
function
(
self
,
*
args
,
**
kwd
)
mode
=
self
.
mode_name
,
except
Unauthorized
,
e
:
text_content
=
self
.
web_section
.
REQUEST
.
get
(
'BODY'
),
body
=
self
.
ERP5Site_logApiErrorAndReturn
(
data_dict
=
None
,
error_code
=
"401"
,
error_message
=
str
(
e
),
error_name
=
"Unauthorized"
)
self
.
REQUEST
.
response
.
setBody
(
body
,
lock
=
True
)
raise
jIOUnauthorized
(
e
)
except
NotFound
,
e
:
LOG
(
'jIOWebSection'
,
INFO
,
'Converting NotFound to NotFound error mesage in JSON,'
,
error
=
True
)
body
=
self
.
ERP5Site_logApiErrorAndReturn
(
error_code
=
"404"
,
error_message
=
str
(
e
),
error_name
=
"NotFound"
)
)
self
.
REQUEST
.
response
.
setBody
(
body
,
lock
=
True
)
except
Exception
as
e
:
raise
error_context
=
{
except
:
"error_code"
:
500
,
LOG
(
'jIOWebSection'
,
INFO
,
'Converting Error to InternalError message in JSON,'
,
"error_message"
:
str
(
e
),
error
=
True
)
"error_name"
:
"InternalError"
body
=
self
.
ERP5Site_logApiErrorAndReturn
(
}
error_code
=
"500"
,
error_message
=
"Internal Server Error"
,
# This NotFound catches instance of objects not found inside API call
error_name
=
"InternalError"
if
isinstance
(
e
,
NotFound
):
)
error_context
[
"error_code"
]
=
404
self
.
REQUEST
.
response
.
setBody
(
body
,
lock
=
True
)
error_context
[
"error_name"
]
=
"NotFound"
raise
elif
isinstance
(
e
,
Unauthorized
):
error_context
[
"error_code"
]
=
403
return
'%s'
%
retval
error_context
[
"error_name"
]
=
"Unauthorized"
wrapper
.
__doc__
=
function
.
__doc__
# Avoid informations leak when Unauthorized
return
wrapper
del
error_context
[
"error_message"
]
return
jIOError
(
error_context
,
self
.
web_section
.
getPortalObject
(),
self
.
web_section
.
REQUEST
)
class
jIOWebSection
(
WebSection
):
class
jIOWebSection
(
WebSection
):
"""
portal_type
=
"jIO Web Section"
This Web Section is a wrapper to jIO to pass content in the body
"""
portal_type
=
'jIO Web Section'
# Declarative security
security
=
ClassSecurityInfo
()
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getLayoutProperty'
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
"getLayoutProperty"
)
def
getLayoutProperty
(
self
,
key
,
default
=
None
):
def
getLayoutProperty
(
self
,
key
,
default
=
None
):
"""
"""
A simple method to get a property of the current by
A simple method to get a property of the current by
acquiring it from the current section or its parents.
acquiring it from the current section or its parents.
"""
"""
section
=
aq_inner
(
self
)
section
=
aq_inner
(
self
)
while
section
.
getPortalType
()
in
(
'Web Section'
,
'Web Site'
,
'Static Web Section'
,
'Static Web Site'
,
while
section
.
getPortalType
()
in
(
'Web Section'
,
'Web Site'
,
'Static Web Section'
,
'Static Web Site'
,
...
@@ -122,46 +135,23 @@ class jIOWebSection(WebSection):
...
@@ -122,46 +135,23 @@ class jIOWebSection(WebSection):
section
=
section
.
aq_parent
section
=
section
.
aq_parent
return
default
return
default
@
convertTojIOAPICall
security
.
declareProtected
(
Permissions
.
View
,
'__bobo_traverse__'
)
def
_asjIOStyle
(
self
,
mode
,
text_content
=
""
,
data_dict
=
None
):
def
__bobo_traverse__
(
self
,
request
,
name
):
return
self
.
ERP5Site_asjIOStyle
(
if
name
in
ALLOWED_MODES
:
mode
=
mode
,
return
jIOMethod
(
name
,
self
)
text_content
=
text_content
,
data_dict
=
data_dict
,
)
security
.
declareProtected
(
Permissions
.
View
,
'get'
)
def
get
(
self
):
#pylint:disable=arguments-differ
"""
Taken from WebSection Bobo Traverse, the difference is that
__bobo_traverse__ from DocumentExtensibleTraversableMixin is not called
"""
# Register current web site physical path for later URL generation
return
self
.
_asjIOStyle
(
mode
=
"get"
,
text_content
=
self
.
REQUEST
.
get
(
'BODY'
))
security
.
declareProtected
(
Permissions
.
View
,
'post'
)
def
post
(
self
):
"""
Taken from WebSection Bobo Traverse, the difference is that
__bobo_traverse__ from DocumentExtensibleTraversableMixin is not called
"""
# Register current web site physical path for later URL generation
return
self
.
_asjIOStyle
(
mode
=
"post"
,
text_content
=
self
.
REQUEST
.
get
(
'BODY'
))
security
.
declareProtected
(
Permissions
.
View
,
'put'
)
def
put
(
self
):
"""
Taken from WebSection Bobo Traverse, the difference is that
__bobo_traverse__ from DocumentExtensibleTraversableMixin is not called
"""
# Register current web site physical path for later URL generation
return
self
.
_asjIOStyle
(
mode
=
"put"
,
text_content
=
self
.
REQUEST
.
get
(
'BODY'
))
security
.
declareProtected
(
Permissions
.
View
,
'allDocs'
)
document
=
None
def
allDocs
(
self
):
try
:
"""
# Inheritance as follows: jIOWebSection <| WebSection <| (Domain, DocumentExtensibleTraversableMixin)
Taken from WebSection Bobo Traverse, the difference is that
# Use DocumentExtensibleTraversableMixin traversal to avoid ERP5 HTML 404 page.
__bobo_traverse__ from DocumentExtensibleTraversableMixin is not called
document
=
DocumentExtensibleTraversableMixin
.
__bobo_traverse__
(
self
,
request
,
name
)
"""
# This NotFound catches objects not found during traversal
# Register current web site physical path for later URL generation
except
NotFound
as
e
:
return
self
.
_asjIOStyle
(
mode
=
"allDocs"
,
text_content
=
self
.
REQUEST
.
get
(
'BODY'
))
error_context
=
{
"error_code"
:
404
,
"error_message"
:
str
(
e
),
"error_name"
:
"NotFound"
}
document
=
jIOError
(
error_context
,
self
.
getPortalObject
(),
self
.
REQUEST
)
return
document
Titouan Soulard
@tsoulard
mentioned in merge request
!9 (closed)
·
Apr 18, 2024
mentioned in merge request
!9 (closed)
mentioned in merge request !9
Toggle commit list
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