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
0
Merge Requests
0
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
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Paul Graydon
erp5
Commits
5224c417
Commit
5224c417
authored
Jul 04, 2023
by
Rafael Monnerat
👻
Browse files
Options
Browse Files
Download
Plain Diff
Update from upstream/master
parents
a4c33bde
dc9ffa12
Changes
30
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
489 additions
and
318 deletions
+489
-318
bt5/erp5_authentication_policy/TestTemplateItem/portal_components/test.erp5.testAuthenticationPolicy.py
...m/portal_components/test.erp5.testAuthenticationPolicy.py
+7
-4
bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testPasswordTool.py
...plateItem/portal_components/test.erp5.testPasswordTool.py
+172
-252
bt5/erp5_oauth_google_login/PathTemplateItem/portal_caches/google_server_auth_token_cache_factory.xml
.../portal_caches/google_server_auth_token_cache_factory.xml
+1
-1
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.js
...hTemplateItem/web_page_module/drone_simulator_logic_js.js
+22
-8
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.xml
...TemplateItem/web_page_module/drone_simulator_logic_js.xml
+3
-3
bt5/erp5_openid_connect_client_login/PathTemplateItem/portal_caches/openid_connect_server_auth_token_cache_factory.xml
...caches/openid_connect_server_auth_token_cache_factory.xml
+1
-1
bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/Resource_getReversedMovementHistoryList.py
...skins/erp5_pdm/Resource_getReversedMovementHistoryList.py
+5
-0
bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/Resource_getReversedMovementHistoryList.xml
...kins/erp5_pdm/Resource_getReversedMovementHistoryList.xml
+62
-0
bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/Resource_viewMovementHistoryDialog/listbox.xml
...s/erp5_pdm/Resource_viewMovementHistoryDialog/listbox.xml
+1
-1
bt5/erp5_trade/PortalTypeTemplateItem/portal_types/Delivery%20Node%20Module.xml
...ypeTemplateItem/portal_types/Delivery%20Node%20Module.xml
+38
-0
bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs_ui/PasswordTool_changeUserPassword.py
...s/erp5_web_renderjs_ui/PasswordTool_changeUserPassword.py
+1
-1
bt5/erp5_web_ui_test/TestTemplateItem/portal_components/test.erp5.testStaticWebSiteRedirection.py
...rtal_components/test.erp5.testStaticWebSiteRedirection.py
+1
-0
product/CMFActivity/tests/testCMFActivity.py
product/CMFActivity/tests/testCMFActivity.py
+1
-1
product/ERP5/Document/Alarm.py
product/ERP5/Document/Alarm.py
+1
-1
product/ERP5/Document/PythonScript.py
product/ERP5/Document/PythonScript.py
+3
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/PasswordTool_changeUserPassword.py
...portal_skins/erp5_core/PasswordTool_changeUserPassword.py
+1
-1
product/ERP5/bootstrap/erp5_core/ToolComponentTemplateItem/portal_components/tool.erp5.PasswordTool.py
...tTemplateItem/portal_components/tool.erp5.PasswordTool.py
+11
-8
product/ERP5Security/ERP5KeyAuthPlugin.py
product/ERP5Security/ERP5KeyAuthPlugin.py
+7
-7
product/ERP5Type/Message.py
product/ERP5Type/Message.py
+2
-0
product/ERP5Type/dynamic/component_package.py
product/ERP5Type/dynamic/component_package.py
+14
-4
product/ERP5Type/patches/PythonScript.py
product/ERP5Type/patches/PythonScript.py
+20
-12
product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
+1
-1
product/ERP5Type/tests/ERP5TypeLiveTestCase.py
product/ERP5Type/tests/ERP5TypeLiveTestCase.py
+3
-1
product/ERP5Type/tests/ERP5TypeTestCase.py
product/ERP5Type/tests/ERP5TypeTestCase.py
+1
-1
product/ERP5Type/tests/ProcessingNodeTestCase.py
product/ERP5Type/tests/ProcessingNodeTestCase.py
+18
-6
product/ERP5Type/tests/custom_zodb.py
product/ERP5Type/tests/custom_zodb.py
+2
-1
product/ERP5Type/tests/runUnitTest.py
product/ERP5Type/tests/runUnitTest.py
+1
-0
product/ERP5Type/tests/testDynamicClassGeneration.py
product/ERP5Type/tests/testDynamicClassGeneration.py
+61
-0
product/ZMySQLDA/connectionAdd.dtml
product/ZMySQLDA/connectionAdd.dtml
+11
-1
product/ZMySQLDA/db.py
product/ZMySQLDA/db.py
+17
-2
No files found.
bt5/erp5_authentication_policy/TestTemplateItem/portal_components/test.erp5.testAuthenticationPolicy.py
View file @
5224c417
...
@@ -808,7 +808,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -808,7 +808,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
preference
=
self
.
portal
.
portal_catalog
.
getResultValue
(
preference
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
title
=
'Authentication'
,)
# Here we activate the "password should contain usename" policy
# Here we activate the "password should contain use
r
name" policy
# as a way to check that password reset checks are done in the
# as a way to check that password reset checks are done in the
# context of the login
# context of the login
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
...
@@ -856,8 +856,11 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -856,8 +856,11 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
# now with a password complying to the policy
# now with a password complying to the policy
ret
=
submit_reset_password_dialog
(
'ok'
)
ret
=
submit_reset_password_dialog
(
'ok'
)
self
.
assertEqual
(
httplib
.
FOUND
,
ret
.
getStatus
())
self
.
assertEqual
(
httplib
.
FOUND
,
ret
.
getStatus
())
self
.
assertTrue
(
ret
.
getHeader
(
'Location'
).
endswith
(
redirect_url
=
urlparse
.
urlparse
(
ret
.
getHeader
(
"Location"
))
'/login_form?portal_status_message=Password+changed.'
))
self
.
assertEqual
(
redirect_url
.
path
,
'{}/login_form'
.
format
(
self
.
portal
.
absolute_url_path
()))
redirect_url_params
=
urlparse
.
parse_qsl
(
redirect_url
.
query
)
self
.
assertIn
((
'portal_status_message'
,
'Password changed.'
),
redirect_url_params
)
self
.
assertIn
((
'portal_status_level'
,
'success'
),
redirect_url_params
)
def
test_PreferenceTool_changePassword_checks_policy
(
self
):
def
test_PreferenceTool_changePassword_checks_policy
(
self
):
person
=
self
.
createUser
(
self
.
id
(),
password
=
'current'
)
person
=
self
.
createUser
(
self
.
id
(),
password
=
'current'
)
...
@@ -918,7 +921,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -918,7 +921,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
# long enough password is accepted
# long enough password is accepted
ret
=
submit_change_password_dialog
(
'long_enough_password'
)
ret
=
submit_change_password_dialog
(
'long_enough_password'
)
# When password reset is succesful, user is logged out
# When password reset is succes
s
ful, user is logged out
self
.
assertEqual
(
httplib
.
FOUND
,
ret
.
getStatus
())
self
.
assertEqual
(
httplib
.
FOUND
,
ret
.
getStatus
())
self
.
assertEqual
(
self
.
portal
.
portal_preferences
.
absolute_url
(),
self
.
assertEqual
(
self
.
portal
.
portal_preferences
.
absolute_url
(),
ret
.
getHeader
(
"Location"
))
ret
.
getHeader
(
"Location"
))
...
...
bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testPasswordTool.py
View file @
5224c417
This diff is collapsed.
Click to expand it.
bt5/erp5_oauth_google_login/PathTemplateItem/portal_caches/google_server_auth_token_cache_factory.xml
View file @
5224c417
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
cache_duration
</string>
</key>
<key>
<string>
cache_duration
</string>
</key>
<value>
<int>
86400
</int>
</value>
<value>
<int>
86400
0
</int>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
description
</string>
</key>
<key>
<string>
description
</string>
</key>
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.js
View file @
5224c417
...
@@ -513,6 +513,8 @@ var GameManager = /** @class */ (function () {
...
@@ -513,6 +513,8 @@ var GameManager = /** @class */ (function () {
function
GameManager
(
canvas
,
game_parameters_json
)
{
function
GameManager
(
canvas
,
game_parameters_json
)
{
var
drone
,
header_list
;
var
drone
,
header_list
;
this
.
_canvas
=
canvas
;
this
.
_canvas
=
canvas
;
this
.
_canvas_width
=
canvas
.
width
;
this
.
_canvas_height
=
canvas
.
height
;
this
.
_scene
=
null
;
this
.
_scene
=
null
;
this
.
_engine
=
null
;
this
.
_engine
=
null
;
this
.
_droneList
=
[];
this
.
_droneList
=
[];
...
@@ -575,7 +577,7 @@ var GameManager = /** @class */ (function () {
...
@@ -575,7 +577,7 @@ var GameManager = /** @class */ (function () {
});
});
};
};
GameManager
.
prototype
.
update
=
function
()
{
GameManager
.
prototype
.
update
=
function
(
fullscreen
)
{
// time delta means that drone are updated every virtual second
// time delta means that drone are updated every virtual second
// This is fixed and must not be modified
// This is fixed and must not be modified
// otherwise, it will lead to different scenario results
// otherwise, it will lead to different scenario results
...
@@ -587,10 +589,8 @@ var GameManager = /** @class */ (function () {
...
@@ -587,10 +589,8 @@ var GameManager = /** @class */ (function () {
function
triggerUpdateIfPossible
()
{
function
triggerUpdateIfPossible
()
{
if
((
_this
.
_canUpdate
)
&&
(
_this
.
ongoing_update_promise
===
null
)
&&
if
((
_this
.
_canUpdate
)
&&
(
_this
.
ongoing_update_promise
===
null
)
&&
(
0
<
_this
.
waiting_update_count
))
{
(
0
<
_this
.
waiting_update_count
))
{
_this
.
ongoing_update_promise
=
_this
.
_update
(
_this
.
ongoing_update_promise
=
_this
.
_update
(
TIME_DELTA
,
fullscreen
)
TIME_DELTA
,
.
push
(
function
()
{
(
_this
.
waiting_update_count
===
1
)
).
push
(
function
()
{
_this
.
waiting_update_count
-=
1
;
_this
.
waiting_update_count
-=
1
;
_this
.
ongoing_update_promise
=
null
;
_this
.
ongoing_update_promise
=
null
;
triggerUpdateIfPossible
();
triggerUpdateIfPossible
();
...
@@ -626,7 +626,7 @@ var GameManager = /** @class */ (function () {
...
@@ -626,7 +626,7 @@ var GameManager = /** @class */ (function () {
return
false
;
return
false
;
};
};
GameManager
.
prototype
.
_update
=
function
(
delta_time
)
{
GameManager
.
prototype
.
_update
=
function
(
delta_time
,
fullscreen
)
{
var
_this
=
this
,
var
_this
=
this
,
queue
=
new
RSVP
.
Queue
(),
queue
=
new
RSVP
.
Queue
(),
i
;
i
;
...
@@ -642,6 +642,20 @@ var GameManager = /** @class */ (function () {
...
@@ -642,6 +642,20 @@ var GameManager = /** @class */ (function () {
}
}
}
}
if
(
fullscreen
)
{
//Only resize if size changes
if
(
this
.
_canvas
.
width
!==
GAMEPARAMETERS
.
fullscreen
.
width
)
{
this
.
_canvas
.
width
=
GAMEPARAMETERS
.
fullscreen
.
width
;
this
.
_canvas
.
height
=
GAMEPARAMETERS
.
fullscreen
.
height
;
}
}
else
{
if
(
this
.
_canvas
.
width
!==
this
.
_canvas_width
)
{
this
.
_canvas
.
width
=
this
.
_canvas_width
;
this
.
_canvas
.
height
=
this
.
_canvas_height
;
this
.
_engine
.
resize
(
true
);
}
}
this
.
_droneList
.
forEach
(
function
(
drone
)
{
this
.
_droneList
.
forEach
(
function
(
drone
)
{
queue
.
push
(
function
()
{
queue
.
push
(
function
()
{
drone
.
_tick
+=
1
;
drone
.
_tick
+=
1
;
...
@@ -1043,9 +1057,9 @@ var runGame, updateGame;
...
@@ -1043,9 +1057,9 @@ var runGame, updateGame;
return
game_manager_instance
.
run
();
return
game_manager_instance
.
run
();
};
};
updateGame
=
function
()
{
updateGame
=
function
(
fullscreen
)
{
if
(
game_manager_instance
)
{
if
(
game_manager_instance
)
{
return
game_manager_instance
.
update
();
return
game_manager_instance
.
update
(
fullscreen
);
}
}
};
};
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.xml
View file @
5224c417
...
@@ -226,7 +226,7 @@
...
@@ -226,7 +226,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
actor
</string>
</key>
<key>
<string>
actor
</string>
</key>
<value>
<
string>
zope
</string
>
</value>
<value>
<
unicode>
zope
</unicode
>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
comment
</string>
</key>
<key>
<string>
comment
</string>
</key>
...
@@ -240,7 +240,7 @@
...
@@ -240,7 +240,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
100
6.43905.28804.11980
</string>
</value>
<value>
<string>
100
9.7345.31305.44339
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -260,7 +260,7 @@
...
@@ -260,7 +260,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
16
77600104.11
</float>
<float>
16
87455790.77
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_openid_connect_client_login/PathTemplateItem/portal_caches/openid_connect_server_auth_token_cache_factory.xml
View file @
5224c417
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
cache_duration
</string>
</key>
<key>
<string>
cache_duration
</string>
</key>
<value>
<int>
86400
</int>
</value>
<value>
<int>
86400
0
</int>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
description
</string>
</key>
<key>
<string>
description
</string>
</key>
...
...
bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/Resource_getReversedMovementHistoryList.py
0 → 100644
View file @
5224c417
history_list
=
context
.
getMovementHistoryList
(
**
kw
)
reverse_list
=
[]
for
x
in
history_list
:
reverse_list
.
insert
(
0
,
x
)
return
reverse_list
bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/Resource_getReversedMovementHistoryList.xml
0 → 100644
View file @
5224c417
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
Script_magic
</string>
</key>
<value>
<int>
3
</int>
</value>
</item>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
**kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Resource_getReversedMovementHistoryList
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/Resource_viewMovementHistoryDialog/listbox.xml
View file @
5224c417
...
@@ -561,7 +561,7 @@
...
@@ -561,7 +561,7 @@
<dictionary>
<dictionary>
<item>
<item>
<key>
<string>
method_name
</string>
</key>
<key>
<string>
method_name
</string>
</key>
<value>
<string>
get
MovementHistoryList
</string>
</value>
<value>
<string>
Resource_getReversed
MovementHistoryList
</string>
</value>
</item>
</item>
</dictionary>
</dictionary>
</pickle>
</pickle>
...
...
bt5/erp5_trade/PortalTypeTemplateItem/portal_types/Delivery%20Node%20Module.xml
View file @
5224c417
...
@@ -16,14 +16,40 @@
...
@@ -16,14 +16,40 @@
<key>
<string>
content_icon
</string>
</key>
<key>
<string>
content_icon
</string>
</key>
<value>
<string>
folder_icon.gif
</string>
</value>
<value>
<string>
folder_icon.gif
</string>
</value>
</item>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<item>
<key>
<string>
factory
</string>
</key>
<key>
<string>
factory
</string>
</key>
<value>
<string>
addFolder
</string>
</value>
<value>
<string>
addFolder
</string>
</value>
</item>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<tuple>
<string>
module
</string>
</tuple>
</value>
</item>
<item>
<item>
<key>
<string>
id
</string>
</key>
<key>
<string>
id
</string>
</key>
<value>
<string>
Delivery Node Module
</string>
</value>
<value>
<string>
Delivery Node Module
</string>
</value>
</item>
</item>
<item>
<key>
<string>
init_script
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
permission
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<item>
<key>
<string>
portal_type
</string>
</key>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Base Type
</string>
</value>
<value>
<string>
Base Type
</string>
</value>
...
@@ -44,6 +70,18 @@
...
@@ -44,6 +70,18 @@
<key>
<string>
type_group
</string>
</key>
<key>
<string>
type_group
</string>
</key>
<value>
<string>
module
</string>
</value>
<value>
<string>
module
</string>
</value>
</item>
</item>
<item>
<key>
<string>
type_interface
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
type_mixin
</string>
</key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</dictionary>
</pickle>
</pickle>
</record>
</record>
...
...
bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs_ui/PasswordTool_changeUserPassword.py
View file @
5224c417
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
"""
"""
REQUEST
=
context
.
REQUEST
REQUEST
=
context
.
REQUEST
next_url
=
context
.
portal_password
.
changeUserPassword
(
password
=
REQUEST
[
'password'
],
next_url
=
context
.
portal_password
.
changeUserPassword
(
password
=
REQUEST
[
'password'
],
password_confirm
ation
=
REQUEST
[
'password_confirm'
],
password_confirm
=
REQUEST
[
'password_confirm'
],
password_key
=
REQUEST
[
'password_key'
],
password_key
=
REQUEST
[
'password_key'
],
user_login
=
REQUEST
.
get
(
'user_login'
,
None
),
user_login
=
REQUEST
.
get
(
'user_login'
,
None
),
REQUEST
=
REQUEST
)
REQUEST
=
REQUEST
)
...
...
bt5/erp5_web_ui_test/TestTemplateItem/portal_components/test.erp5.testStaticWebSiteRedirection.py
View file @
5224c417
...
@@ -117,6 +117,7 @@ class TestStaticWebSiteRedirection(ERP5TypeTestCase):
...
@@ -117,6 +117,7 @@ class TestStaticWebSiteRedirection(ERP5TypeTestCase):
connection
=
httplib
.
HTTPSConnection
(
netloc_to_check
,
context
=
ssl
.
_create_unverified_context
(),
timeout
=
10
)
connection
=
httplib
.
HTTPSConnection
(
netloc_to_check
,
context
=
ssl
.
_create_unverified_context
(),
timeout
=
10
)
else
:
else
:
connection
=
httplib
.
HTTPConnection
(
netloc_to_check
,
timeout
=
10
)
connection
=
httplib
.
HTTPConnection
(
netloc_to_check
,
timeout
=
10
)
self
.
addCleanup
(
connection
.
close
)
connection
.
request
(
connection
.
request
(
method
=
"GET"
,
method
=
"GET"
,
url
=
url_to_check
url
=
url_to_check
...
...
product/CMFActivity/tests/testCMFActivity.py
View file @
5224c417
...
@@ -2603,7 +2603,7 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
...
@@ -2603,7 +2603,7 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
self
.
assertEqual
(
activity_node
,
current_node
)
self
.
assertEqual
(
activity_node
,
current_node
)
def
test_getServerAddress
(
self
):
def
test_getServerAddress
(
self
):
host
,
port
=
self
.
start
Z
Server
()
host
,
port
=
self
.
start
HTTP
Server
()
ip
=
socket
.
gethostbyname
(
host
)
ip
=
socket
.
gethostbyname
(
host
)
server_address
=
'%s:%s'
%
(
ip
,
port
)
server_address
=
'%s:%s'
%
(
ip
,
port
)
address
=
getServerAddress
()
address
=
getServerAddress
()
...
...
product/ERP5/Document/Alarm.py
View file @
5224c417
...
@@ -164,7 +164,7 @@ class Alarm(XMLObject, PeriodicityMixin):
...
@@ -164,7 +164,7 @@ class Alarm(XMLObject, PeriodicityMixin):
activate_kw
[
'tag'
]
=
'%s_%x'
%
(
self
.
getRelativeUrl
(),
getrandbits
(
32
))
activate_kw
[
'tag'
]
=
'%s_%x'
%
(
self
.
getRelativeUrl
(),
getrandbits
(
32
))
tag
=
activate_kw
[
'tag'
]
tag
=
activate_kw
[
'tag'
]
method
=
getattr
(
self
,
method_id
)
method
=
getattr
(
self
,
method_id
)
func_code
=
method
.
__code__
func_code
=
getattr
(
method
,
'__code__'
,
None
)
if
func_code
is
None
:
# BBB Zope2
if
func_code
is
None
:
# BBB Zope2
func_code
=
method
.
func_code
func_code
=
method
.
func_code
try
:
try
:
...
...
product/ERP5/Document/PythonScript.py
View file @
5224c417
...
@@ -31,6 +31,7 @@ from AccessControl import ClassSecurityInfo
...
@@ -31,6 +31,7 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
App.special_dtml
import
HTMLFile
from
App.special_dtml
import
HTMLFile
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type
import
IS_ZOPE2
from
Products.PythonScripts.PythonScript
import
\
from
Products.PythonScripts.PythonScript
import
\
PythonScript
as
ZopePythonScript
PythonScript
as
ZopePythonScript
from
Products.ERP5Type.mixin.expression
import
ExpressionMixin
from
Products.ERP5Type.mixin.expression
import
ExpressionMixin
...
@@ -71,6 +72,8 @@ class PythonScript(XMLObject, ZopePythonScript, ExpressionMixin('expression')):
...
@@ -71,6 +72,8 @@ class PythonScript(XMLObject, ZopePythonScript, ExpressionMixin('expression')):
meta_type
=
'ERP5 Python Script'
meta_type
=
'ERP5 Python Script'
portal_type
=
'Python Script'
portal_type
=
'Python Script'
add_permission
=
Permissions
.
AddPortalContent
add_permission
=
Permissions
.
AddPortalContent
if
not
IS_ZOPE2
:
zmi_icon
=
ZopePythonScript
.
zmi_icon
# Declarative security
# Declarative security
security
=
ClassSecurityInfo
()
security
=
ClassSecurityInfo
()
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/PasswordTool_changeUserPassword.py
View file @
5224c417
REQUEST
=
context
.
REQUEST
REQUEST
=
context
.
REQUEST
return
context
.
portal_password
.
changeUserPassword
(
password
=
REQUEST
[
'password'
],
return
context
.
portal_password
.
changeUserPassword
(
password
=
REQUEST
[
'password'
],
password_confirm
ation
=
REQUEST
[
'password_confirm'
],
password_confirm
=
REQUEST
[
'password_confirm'
],
password_key
=
REQUEST
[
'password_key'
],
password_key
=
REQUEST
[
'password_key'
],
user_login
=
REQUEST
.
get
(
'user_login'
,
None
),
user_login
=
REQUEST
.
get
(
'user_login'
,
None
),
REQUEST
=
REQUEST
)
REQUEST
=
REQUEST
)
product/ERP5/bootstrap/erp5_core/ToolComponentTemplateItem/portal_components/tool.erp5.PasswordTool.py
View file @
5224c417
...
@@ -41,9 +41,9 @@ from BTrees.OOBTree import OOBTree
...
@@ -41,9 +41,9 @@ from BTrees.OOBTree import OOBTree
from
six.moves.urllib.parse
import
urlencode
from
six.moves.urllib.parse
import
urlencode
redirect_path
=
'/login_form'
redirect_path
=
'/login_form'
def
redirect
(
REQUEST
,
site_url
,
message
):
def
redirect
(
REQUEST
,
site_url
,
message
,
level
):
if
REQUEST
is
not
None
and
getattr
(
REQUEST
.
RESPONSE
,
'redirect'
,
None
)
is
not
None
:
if
REQUEST
is
not
None
and
getattr
(
REQUEST
.
RESPONSE
,
'redirect'
,
None
)
is
not
None
:
parameter
=
urlencode
({
'portal_status_message'
:
message
})
parameter
=
urlencode
({
'portal_status_message'
:
message
,
'portal_status_level'
:
level
})
ret_url
=
'%s%s?%s'
%
(
site_url
,
redirect_path
,
parameter
)
ret_url
=
'%s%s?%s'
%
(
site_url
,
redirect_path
,
parameter
)
return
REQUEST
.
RESPONSE
.
redirect
(
ret_url
)
return
REQUEST
.
RESPONSE
.
redirect
(
ret_url
)
else
:
else
:
...
@@ -171,10 +171,13 @@ class PasswordTool(BaseTool):
...
@@ -171,10 +171,13 @@ class PasswordTool(BaseTool):
"User {user} does not have a valid email address"
.
format
(
user
=
user_login
)
"User {user} does not have a valid email address"
.
format
(
user
=
user_login
)
)
)
if
error_encountered
:
if
error_encountered
:
# note that we intentionally use the same msg here regardless of whether the
# email was successfully sent or not in order not to leak information about user
# existence.
if
batch
:
if
batch
:
raise
RuntimeError
(
msg
)
raise
RuntimeError
(
msg
)
else
:
else
:
return
redirect
(
REQUEST
,
site_url
,
msg
)
return
redirect
(
REQUEST
,
site_url
,
msg
,
'success'
)
key
=
self
.
getResetPasswordKey
(
user_login
=
user_login
,
key
=
self
.
getResetPasswordKey
(
user_login
=
user_login
,
expiration_date
=
expiration_date
)
expiration_date
=
expiration_date
)
...
@@ -222,8 +225,7 @@ class PasswordTool(BaseTool):
...
@@ -222,8 +225,7 @@ class PasswordTool(BaseTool):
message_text_format
=
message_text_format
,
message_text_format
=
message_text_format
,
event_keyword_argument_dict
=
event_keyword_argument_dict
)
event_keyword_argument_dict
=
event_keyword_argument_dict
)
if
not
batch
:
if
not
batch
:
return
redirect
(
REQUEST
,
site_url
,
return
redirect
(
REQUEST
,
site_url
,
msg
,
'success'
)
translateString
(
"An email has been sent to you."
))
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'removeExpiredRequests'
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'removeExpiredRequests'
)
def
removeExpiredRequests
(
self
):
def
removeExpiredRequests
(
self
):
...
@@ -266,13 +268,12 @@ class PasswordTool(BaseTool):
...
@@ -266,13 +268,12 @@ class PasswordTool(BaseTool):
"""
"""
Reset the password for a given login
Reset the password for a given login
"""
"""
# BBB: password_confirm: unused argument
def
error
(
message
):
def
error
(
message
):
# BBB: should "raise Redirect" instead of just returning, simplifying
# BBB: should "raise Redirect" instead of just returning, simplifying
# calling code and making mistakes more difficult
# calling code and making mistakes more difficult
# BBB: should probably not translate message when REQUEST is None
# BBB: should probably not translate message when REQUEST is None
message
=
translateString
(
message
)
message
=
translateString
(
message
)
return
redirect
(
REQUEST
,
site_url
,
message
)
return
redirect
(
REQUEST
,
site_url
,
message
,
'error'
)
if
REQUEST
is
None
:
if
REQUEST
is
None
:
REQUEST
=
get_request
()
REQUEST
=
get_request
()
...
@@ -291,6 +292,8 @@ class PasswordTool(BaseTool):
...
@@ -291,6 +292,8 @@ class PasswordTool(BaseTool):
if
user_login
is
not
None
and
register_user_login
!=
user_login
:
if
user_login
is
not
None
and
register_user_login
!=
user_login
:
# XXX: not descriptive enough
# XXX: not descriptive enough
return
error
(
"Bad login provided."
)
return
error
(
"Bad login provided."
)
if
password_confirm
is
not
None
and
password_confirm
!=
password
:
return
error
(
"Password does not match the confirm password."
)
if
DateTime
()
>
expiration_date
:
if
DateTime
()
>
expiration_date
:
return
error
(
"Date has expired."
)
return
error
(
"Date has expired."
)
del
self
.
_password_request_dict
[
password_key
]
del
self
.
_password_request_dict
[
password_key
]
...
@@ -303,6 +306,6 @@ class PasswordTool(BaseTool):
...
@@ -303,6 +306,6 @@ class PasswordTool(BaseTool):
login
=
portal
.
unrestrictedTraverse
(
login_dict
[
'path'
])
login
=
portal
.
unrestrictedTraverse
(
login_dict
[
'path'
])
login
.
setPassword
(
password
)
# this will raise if password does not match policy
login
.
setPassword
(
password
)
# this will raise if password does not match policy
return
redirect
(
REQUEST
,
site_url
,
return
redirect
(
REQUEST
,
site_url
,
translateString
(
"Password changed."
))
translateString
(
"Password changed."
)
,
'success'
)
InitializeClass
(
PasswordTool
)
InitializeClass
(
PasswordTool
)
product/ERP5Security/ERP5KeyAuthPlugin.py
View file @
5224c417
...
@@ -151,7 +151,7 @@ def addERP5KeyAuthPlugin(dispatcher, id, title=None,
...
@@ -151,7 +151,7 @@ def addERP5KeyAuthPlugin(dispatcher, id, title=None,
class
ERP5KeyAuthPlugin
(
ERP5UserManager
,
CookieAuthHelper
):
class
ERP5KeyAuthPlugin
(
ERP5UserManager
,
CookieAuthHelper
):
"""
"""
Key authenti
fi
cation PAS plugin which support key authentication in URL.
Key authentication PAS plugin which support key authentication in URL.
<ERP5_Root>/web_page_module/1?__ac_key=207221200213146153166
<ERP5_Root>/web_page_module/1?__ac_key=207221200213146153166
...
@@ -309,7 +309,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
...
@@ -309,7 +309,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
################################
################################
security
.
declarePrivate
(
'resetCredentials'
)
security
.
declarePrivate
(
'resetCredentials'
)
def
resetCredentials
(
self
,
request
,
response
):
def
resetCredentials
(
self
,
request
,
response
):
"""Expire cookies of authenti
fi
cation """
"""Expire cookies of authentication """
response
.
expireCookie
(
self
.
cookie_name
,
path
=
'/'
)
response
.
expireCookie
(
self
.
cookie_name
,
path
=
'/'
)
response
.
expireCookie
(
self
.
default_cookie_name
,
path
=
'/'
)
response
.
expireCookie
(
self
.
default_cookie_name
,
path
=
'/'
)
...
@@ -319,7 +319,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
...
@@ -319,7 +319,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
################################
################################
security
.
declarePrivate
(
'authenticateCredentials'
)
security
.
declarePrivate
(
'authenticateCredentials'
)
def
authenticateCredentials
(
self
,
credentials
):
def
authenticateCredentials
(
self
,
credentials
):
"""Authenti
fi
cate with credentials"""
"""Authenticate with credentials"""
key
=
credentials
.
get
(
'key'
,
None
)
key
=
credentials
.
get
(
'key'
,
None
)
if
key
!=
None
:
if
key
!=
None
:
login
=
self
.
decrypt
(
key
)
login
=
self
.
decrypt
(
key
)
...
@@ -377,9 +377,9 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
...
@@ -377,9 +377,9 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
LOG
(
'ERP5KeyAuthPlugin.authenticateCredentials'
,
PROBLEM
,
str
(
e
))
LOG
(
'ERP5KeyAuthPlugin.authenticateCredentials'
,
PROBLEM
,
str
(
e
))
return
None
return
None
################################
################################
#
# Properties for ZMI managment #
# Properties for ZMI manag
e
ment #
################################
################################
#
#'Edit' option form
#'Edit' option form
manage_editERP5KeyAuthPluginForm
=
PageTemplateFile
(
manage_editERP5KeyAuthPluginForm
=
PageTemplateFile
(
...
@@ -393,7 +393,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
...
@@ -393,7 +393,7 @@ class ERP5KeyAuthPlugin(ERP5UserManager, CookieAuthHelper):
"""Edit the object"""
"""Edit the object"""
error_message
=
''
error_message
=
''
#Test param
a
eters
#Test parameters
if
"__ac_key"
in
[
cookie_name
,
default_cookie_name
]:
if
"__ac_key"
in
[
cookie_name
,
default_cookie_name
]:
raise
ValueError
(
"Cookie name must be different of __ac_key"
)
raise
ValueError
(
"Cookie name must be different of __ac_key"
)
...
...
product/ERP5Type/Message.py
View file @
5224c417
...
@@ -96,6 +96,8 @@ class Message(Persistent):
...
@@ -96,6 +96,8 @@ class Message(Persistent):
def
__init__
(
self
,
domain
=
None
,
message
=
''
,
def
__init__
(
self
,
domain
=
None
,
message
=
''
,
mapping
=
None
,
default
=
None
):
mapping
=
None
,
default
=
None
):
self
.
message
=
message
self
.
message
=
message
if
mapping
is
not
None
:
assert
isinstance
(
mapping
,
dict
)
self
.
mapping
=
mapping
self
.
mapping
=
mapping
self
.
domain
=
domain
self
.
domain
=
domain
if
default
is
None
:
if
default
is
None
:
...
...
product/ERP5Type/dynamic/component_package.py
View file @
5224c417
...
@@ -35,6 +35,7 @@ import sys
...
@@ -35,6 +35,7 @@ import sys
import
imp
import
imp
import
collections
import
collections
from
six
import
reraise
from
six
import
reraise
import
traceback
import
coverage
import
coverage
from
Products.ERP5Type.Utils
import
ensure_list
from
Products.ERP5Type.Utils
import
ensure_list
...
@@ -60,6 +61,13 @@ except NameError: # < 3.6
...
@@ -60,6 +61,13 @@ except NameError: # < 3.6
class
ModuleNotFoundError
(
ImportError
):
class
ModuleNotFoundError
(
ImportError
):
pass
pass
class
ComponentImportError
(
ImportError
):
"""Error when importing an existing, but invalid component, typically
because it contains syntax errors or import errors.
"""
class
ComponentDynamicPackage
(
ModuleType
):
class
ComponentDynamicPackage
(
ModuleType
):
"""
"""
A top-level component is a package as it contains modules, this is required
A top-level component is a package as it contains modules, this is required
...
@@ -355,16 +363,18 @@ class ComponentDynamicPackage(ModuleType):
...
@@ -355,16 +363,18 @@ class ComponentDynamicPackage(ModuleType):
# in a deadlock
# in a deadlock
source_code_obj
=
compile
(
source_code_str
,
module
.
__file__
,
'exec'
)
source_code_obj
=
compile
(
source_code_str
,
module
.
__file__
,
'exec'
)
exec
(
source_code_obj
,
module
.
__dict__
)
exec
(
source_code_obj
,
module
.
__dict__
)
except
Exception
as
error
:
except
Exception
:
del
sys
.
modules
[
module_fullname
]
del
sys
.
modules
[
module_fullname
]
if
module_fullname_alias
:
if
module_fullname_alias
:
del
sys
.
modules
[
module_fullname_alias
]
del
sys
.
modules
[
module_fullname_alias
]
if
module_fullname_filesystem
:
if
module_fullname_filesystem
:
del
sys
.
modules
[
module_fullname_filesystem
]
del
sys
.
modules
[
module_fullname_filesystem
]
reraise
(
ImportError
,
reraise
(
"%s: cannot load Component %s (%s)"
%
(
fullname
,
name
,
error
),
ComponentImportError
,
sys
.
exc_info
()[
2
])
"%s: cannot load Component %s :
\
n
%s"
%
(
fullname
,
name
,
traceback
.
format_exc
()),
sys
.
exc_info
()[
2
])
# Add the newly created module to the Version package and add it as an
# Add the newly created module to the Version package and add it as an
# alias to the top-level package as well
# alias to the top-level package as well
...
...
product/ERP5Type/patches/PythonScript.py
View file @
5224c417
...
@@ -22,6 +22,7 @@ from OFS.misc_ import p_
...
@@ -22,6 +22,7 @@ from OFS.misc_ import p_
from
App.ImageFile
import
ImageFile
from
App.ImageFile
import
ImageFile
from
Acquisition
import
aq_base
,
aq_parent
from
Acquisition
import
aq_base
,
aq_parent
from
zExceptions
import
Forbidden
from
zExceptions
import
Forbidden
from
Products.ERP5Type
import
IS_ZOPE2
### Guards
### Guards
...
@@ -153,18 +154,25 @@ class _(PatchClass(PythonScript)):
...
@@ -153,18 +154,25 @@ class _(PatchClass(PythonScript)):
# Add proxy role icon in ZMI
# Add proxy role icon in ZMI
def
om_icons
(
self
):
if
IS_ZOPE2
:
"""Return a list of icon URLs to be displayed by an ObjectManager"""
def
om_icons
(
self
):
if
self
.
_proxy_roles
:
"""Return a list of icon URLs to be displayed by an ObjectManager"""
return
{
'path'
:
'p_/PythonScript_ProxyRole_icon'
,
if
self
.
_proxy_roles
:
'alt'
:
'Proxy Roled Python Script'
,
return
{
'path'
:
'p_/PythonScript_ProxyRole_icon'
,
'title'
:
'This script has proxy role.'
},
'alt'
:
'Proxy Roled Python Script'
,
return
{
'path'
:
'misc_/PythonScripts/pyscript.gif'
,
'title'
:
'This script has proxy role.'
},
'alt'
:
self
.
meta_type
,
'title'
:
self
.
meta_type
},
return
{
'path'
:
'misc_/PythonScripts/pyscript.gif'
,
'alt'
:
self
.
meta_type
,
'title'
:
self
.
meta_type
},
p_
.
PythonScript_ProxyRole_icon
=
\
ImageFile
(
'pyscript_proxyrole.gif'
,
globals
())
p_
.
PythonScript_ProxyRole_icon
=
\
ImageFile
(
'pyscript_proxyrole.gif'
,
globals
())
else
:
@
property
def
zmi_icon
(
self
):
if
self
.
_proxy_roles
:
return
'fa fa-terminal fa-spin'
else
:
return
'fa fa-terminal'
# Guards
# Guards
...
...
product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
View file @
5224c417
...
@@ -428,7 +428,7 @@ class ERP5TypeFunctionalTestCase(ERP5TypeTestCase):
...
@@ -428,7 +428,7 @@ class ERP5TypeFunctionalTestCase(ERP5TypeTestCase):
# non-recursive results clean of portal_tests/ or portal_tests/``run_only``
# non-recursive results clean of portal_tests/ or portal_tests/``run_only``
self
.
portal
.
portal_tests
.
TestTool_cleanUpTestResults
(
self
.
run_only
or
None
)
self
.
portal
.
portal_tests
.
TestTool_cleanUpTestResults
(
self
.
run_only
or
None
)
self
.
tic
()
self
.
tic
()
host
,
port
=
self
.
start
Z
Server
()
host
,
port
=
self
.
start
HTTP
Server
()
self
.
runner
=
FunctionalTestRunner
(
host
,
port
,
self
)
self
.
runner
=
FunctionalTestRunner
(
host
,
port
,
self
)
def
setSystemPreference
(
self
):
def
setSystemPreference
(
self
):
...
...
product/ERP5Type/tests/ERP5TypeLiveTestCase.py
View file @
5224c417
...
@@ -185,7 +185,7 @@ class ERP5TypeLiveTestCase(ERP5TypeTestCaseMixin):
...
@@ -185,7 +185,7 @@ class ERP5TypeLiveTestCase(ERP5TypeTestCaseMixin):
finally
:
finally
:
restoreInteraction
()
restoreInteraction
()
from
Products.ERP5Type.dynamic.component_package
import
ComponentDynamicPackage
from
Products.ERP5Type.dynamic.component_package
import
ComponentDynamicPackage
,
ComponentImportError
from
Products.ERP5Type.tests.runUnitTest
import
ERP5TypeTestLoader
from
Products.ERP5Type.tests.runUnitTest
import
ERP5TypeTestLoader
class
ERP5TypeTestReLoader
(
ERP5TypeTestLoader
):
class
ERP5TypeTestReLoader
(
ERP5TypeTestLoader
):
...
@@ -221,6 +221,8 @@ class ERP5TypeTestReLoader(ERP5TypeTestLoader):
...
@@ -221,6 +221,8 @@ class ERP5TypeTestReLoader(ERP5TypeTestLoader):
if
module
is
None
:
if
module
is
None
:
try
:
try
:
self
.
_importZodbTestComponent
(
name
.
split
(
'.'
)[
0
])
self
.
_importZodbTestComponent
(
name
.
split
(
'.'
)[
0
])
except
ComponentImportError
:
raise
except
ImportError
:
except
ImportError
:
pass
pass
else
:
else
:
...
...
product/ERP5Type/tests/ERP5TypeTestCase.py
View file @
5224c417
...
@@ -1284,7 +1284,7 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin):
...
@@ -1284,7 +1284,7 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin):
if
len
(
setup_done
)
==
1
:
# make sure it is run only once
if
len
(
setup_done
)
==
1
:
# make sure it is run only once
self
.
_setUpDummyMailHost
()
self
.
_setUpDummyMailHost
()
self
.
start
Z
Server
(
verbose
=
True
)
self
.
start
HTTP
Server
(
verbose
=
True
)
self
.
_registerNode
(
distributing
=
1
,
processing
=
1
)
self
.
_registerNode
(
distributing
=
1
,
processing
=
1
)
self
.
loadPromise
()
self
.
loadPromise
()
...
...
product/ERP5Type/tests/ProcessingNodeTestCase.py
View file @
5224c417
...
@@ -151,9 +151,10 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -151,9 +151,10 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
pass
pass
Lifetime
.
graceful_shutdown_loop
()
Lifetime
.
graceful_shutdown_loop
()
def
startZServer
(
self
,
verbose
=
False
):
@
staticmethod
"""Start HTTP ZServer in background"""
def
startHTTPServer
(
verbose
=
False
):
if
self
.
_server_address
is
None
:
"""Start HTTP Server in background"""
if
ProcessingNodeTestCase
.
_server_address
is
None
:
from
Products.ERP5Type.tests.runUnitTest
import
log_directory
from
Products.ERP5Type.tests.runUnitTest
import
log_directory
log
=
os
.
path
.
join
(
log_directory
,
"Z2.log"
)
log
=
os
.
path
.
join
(
log_directory
,
"Z2.log"
)
message
=
"Running %s server at %s:%s
\
n
"
message
=
"Running %s server at %s:%s
\
n
"
...
@@ -199,8 +200,11 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -199,8 +200,11 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
webdav_ports
=
webdav_ports
),
webdav_ports
=
webdav_ports
),
logger
,
logger
,
sockets
=
sockets
)
sockets
=
sockets
)
ProcessingNodeTestCase
.
_server
=
hs
ProcessingNodeTestCase
.
_server_address
=
hs
.
addr
ProcessingNodeTestCase
.
_server_address
=
hs
.
addr
t
=
Thread
(
target
=
hs
.
run
)
ProcessingNodeTestCase
.
_server_thread
=
t
=
Thread
(
target
=
hs
.
run
,
name
=
'ProcessingNodeTestCase.startHTTPServer'
)
t
.
setDaemon
(
1
)
t
.
setDaemon
(
1
)
t
.
start
()
t
.
start
()
from
Products.CMFActivity
import
ActivityTool
from
Products.CMFActivity
import
ActivityTool
...
@@ -210,7 +214,15 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -210,7 +214,15 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
if
ActivityTool
.
currentNode
==
ActivityTool
.
_server_address
:
if
ActivityTool
.
currentNode
==
ActivityTool
.
_server_address
:
ActivityTool
.
currentNode
=
None
ActivityTool
.
currentNode
=
None
ActivityTool
.
_server_address
=
None
ActivityTool
.
_server_address
=
None
return
self
.
_server_address
return
ProcessingNodeTestCase
.
_server_address
startZServer
=
startHTTPServer
# BBB
@
staticmethod
def
stopHTTPServer
():
if
ProcessingNodeTestCase
.
_server_address
is
not
None
:
ProcessingNodeTestCase
.
_server_address
=
None
ProcessingNodeTestCase
.
_server
.
close
()
ProcessingNodeTestCase
.
_server_thread
.
join
(
5
)
def
_registerNode
(
self
,
distributing
,
processing
):
def
_registerNode
(
self
,
distributing
,
processing
):
"""Register node to process and/or distribute activities"""
"""Register node to process and/or distribute activities"""
...
@@ -338,7 +350,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -338,7 +350,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
def
afterSetUp
(
self
):
def
afterSetUp
(
self
):
"""Initialize a node that will only process activities"""
"""Initialize a node that will only process activities"""
self
.
start
Z
Server
()
self
.
start
HTTP
Server
()
# Make sure to still have possibilities to edit components
# Make sure to still have possibilities to edit components
addUserToDeveloperRole
(
'ERP5TypeTestCase'
)
addUserToDeveloperRole
(
'ERP5TypeTestCase'
)
from
Zope2.custom_zodb
import
cluster
from
Zope2.custom_zodb
import
cluster
...
...
product/ERP5Type/tests/custom_zodb.py
View file @
5224c417
...
@@ -40,10 +40,11 @@ if save_mysql:
...
@@ -40,10 +40,11 @@ if save_mysql:
# The output of mysqldump needs to merge many lines at a time
# The output of mysqldump needs to merge many lines at a time
# for performance reasons (merging lines is at most 10 times
# for performance reasons (merging lines is at most 10 times
# faster, so this produce somewhat not nice to read sql
# faster, so this produce somewhat not nice to read sql
command
=
'mysqldump %s > %s'
%
(
getMySQLArguments
(),
dump_sql_path
,)
command
=
'mysqldump %s > %s
.tmp
'
%
(
getMySQLArguments
(),
dump_sql_path
,)
if
verbosity
:
if
verbosity
:
_print
(
'Dumping MySQL database with %s ...'
%
command
)
_print
(
'Dumping MySQL database with %s ...'
%
command
)
subprocess
.
check_call
(
command
,
shell
=
True
)
subprocess
.
check_call
(
command
,
shell
=
True
)
os
.
rename
(
dump_sql_path
+
'.tmp'
,
dump_sql_path
)
if
load
:
if
load
:
if
save_mysql
:
if
save_mysql
:
...
...
product/ERP5Type/tests/runUnitTest.py
View file @
5224c417
...
@@ -693,6 +693,7 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
...
@@ -693,6 +693,7 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
raise
raise
finally
:
finally
:
ProcessingNodeTestCase
.
unregisterNode
()
ProcessingNodeTestCase
.
unregisterNode
()
ProcessingNodeTestCase
.
stopHTTPServer
()
db_factory
.
close
()
db_factory
.
close
()
Storage
.
close
()
Storage
.
close
()
if
node_pid_list
is
not
None
:
if
node_pid_list
is
not
None
:
...
...
product/ERP5Type/tests/testDynamicClassGeneration.py
View file @
5224c417
...
@@ -3296,6 +3296,67 @@ class Test(ERP5TypeTestCase):
...
@@ -3296,6 +3296,67 @@ class Test(ERP5TypeTestCase):
expected_msg_re = re.compile('
Ran
3
test
.
*
OK
', re.DOTALL)
expected_msg_re = re.compile('
Ran
3
test
.
*
OK
', re.DOTALL)
self.assertRegex(output, expected_msg_re)
self.assertRegex(output, expected_msg_re)
def testRunLiveTestImportError(self):
source_code = '''
def break_at_import():
import non.existing.module # pylint:disable=import-error
break_at_import()
'''
component = self._newComponent('
testRunLiveTestImportError
', source_code)
component.validate()
self.tic()
from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader
ERP5TypeTestLoader_loadTestsFromNames = ERP5TypeTestLoader.loadTestsFromNames
def loadTestsFromNames(self, *args, **kwargs):
"""
Monkey patched to simulate a reset right after importing the ZODB Test
Component whose Unit Tests are going to be executed
"""
ret = ERP5TypeTestLoader_loadTestsFromNames(self, *args, **kwargs)
from Products.ERP5.ERP5Site import getSite
getSite().portal_components.reset(force=True)
# Simulate a new REQUEST while the old one has been GC'
ed
import
erp5.component
erp5
.
component
.
ref_manager
.
clear
()
import
gc
gc
.
collect
()
return
ret
self
.
assertEqual
(
component
.
getValidationState
(),
'validated'
)
self
.
_component_tool
.
reset
(
force
=
True
,
reset_portal_type_at_transaction_boundary
=
True
)
def
runLiveTest
(
test_name
):
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple
=
ERP5TypeTestCase
.
__bases__
ERP5TypeTestLoader
.
loadTestsFromNames
=
loadTestsFromNames
try
:
self
.
_component_tool
.
runLiveTest
(
test_name
)
finally
:
ERP5TypeTestCase
.
__bases__
=
base_tuple
ERP5TypeTestLoader
.
loadTestsFromNames
=
ERP5TypeTestLoader_loadTestsFromNames
return
self
.
_component_tool
.
readTestOutput
()
output
=
runLiveTest
(
'testRunLiveTestImportError'
)
self
.
assertIn
(
'''
File "<portal_components/test.erp5.testRunLiveTestImportError>", line 4, in <module>
break_at_import()
File "<portal_components/test.erp5.testRunLiveTestImportError>", line 3, in break_at_import
import non.existing.module # pylint:disable=import-error
ImportError: No module named non.existing.module
'''
,
output
)
output
=
runLiveTest
(
'testDoesNotExist_import_error_because_module_does_not_exist'
)
self
.
assertIn
(
"ImportError: No module named testDoesNotExist_import_error_because_module_does_not_exist"
,
output
)
def
testERP5Broken
(
self
):
def
testERP5Broken
(
self
):
# Create a broken ghost object
# Create a broken ghost object
import
erp5.portal_type
import
erp5.portal_type
...
...
product/ZMySQLDA/connectionAdd.dtml
View file @
5224c417
...
@@ -56,7 +56,7 @@
...
@@ -56,7 +56,7 @@
<dd>
<dd>
The connection string used for Z MySQL Database Connection is of the form:
The connection string used for Z MySQL Database Connection is of the form:
<br />
<br />
<code>[*lock] [+/-][database][@host[:port]] [user [password [unix_socket]]]</code>
<code>[
%ssl_name] [
*lock] [+/-][database][@host[:port]] [user [password [unix_socket]]]</code>
<br />
<br />
or typically:
or typically:
<br />
<br />
...
@@ -73,6 +73,16 @@
...
@@ -73,6 +73,16 @@
If the UNIX socket is in a non-standard location, you can specify
If the UNIX socket is in a non-standard location, you can specify
the full path to it after the password.
the full path to it after the password.
</dd>
</dd>
<dd>
%<em>ssl_name</em> at the begining of the connection string means to use
a ssl client certificate for authentication.
This will use a CA certificate located at
<code>$INSTANCEHOME/etc/zmysqlda/[%ssl_name]-ca.pem</code>, a client certificate
at <code>$INSTANCEHOME/etc/zmysqlda/[%ssl_name]-cert.pem</code> with a key
at <code>$INSTANCEHOME/etc/zmysqlda/[%ssl_name]-key.pem</code>.
This will also verify that the connection is using ssl and cause an error
when an encrypted connection can not be established.
</dd>
<dd>
<dd>
A '-' in front of the database tells ZMySQLDA to not use Zope's
A '-' in front of the database tells ZMySQLDA to not use Zope's
Transaction Manager, even if the server supports transactions. A
Transaction Manager, even if the server supports transactions. A
...
...
product/ZMySQLDA/db.py
View file @
5224c417
...
@@ -107,6 +107,7 @@ if _v < MySQLdb_version_required:
...
@@ -107,6 +107,7 @@ if _v < MySQLdb_version_required:
from
MySQLdb.converters
import
conversions
from
MySQLdb.converters
import
conversions
from
MySQLdb.constants
import
FIELD_TYPE
,
CR
,
ER
,
CLIENT
from
MySQLdb.constants
import
FIELD_TYPE
,
CR
,
ER
,
CLIENT
from
App.config
import
getConfiguration
from
Shared.DC.ZRDB.TM
import
TM
from
Shared.DC.ZRDB.TM
import
TM
from
DateTime
import
DateTime
from
DateTime
import
DateTime
from
zLOG
import
LOG
,
ERROR
,
WARNING
from
zLOG
import
LOG
,
ERROR
,
WARNING
...
@@ -115,7 +116,8 @@ from ZODB.POSException import ConflictError
...
@@ -115,7 +116,8 @@ from ZODB.POSException import ConflictError
hosed_connection
=
(
hosed_connection
=
(
CR
.
SERVER_GONE_ERROR
,
CR
.
SERVER_GONE_ERROR
,
CR
.
SERVER_LOST
,
CR
.
SERVER_LOST
,
CR
.
COMMANDS_OUT_OF_SYNC
CR
.
COMMANDS_OUT_OF_SYNC
,
1927
,
# ER_CONNECTION_KILLED "Connection was killed" in MariaDB
)
)
query_syntax_error
=
(
query_syntax_error
=
(
...
@@ -245,6 +247,14 @@ class DB(TM):
...
@@ -245,6 +247,14 @@ class DB(TM):
items = self._connection.split()
items = self._connection.split()
if not items:
if not items:
return
return
if items[0][0] == "%":
cert_base_name = items.pop(0)[1:]
instancehome = getConfiguration().instancehome
kwargs['
ssl
'] = {
'
ca
': os.path.join(instancehome, '
etc
', '
zmysqlda
', cert_base_name + '
-
ca
.
pem
'),
'
cert
': os.path.join(instancehome, '
etc
', '
zmysqlda
', cert_base_name + '
-
cert
.
pem
'),
'
key
': os.path.join(instancehome, '
etc
', '
zmysqlda
', cert_base_name + '
-
key
.
pem
'),
}
if items[0] == "~":
if items[0] == "~":
kwargs['
compress
'] = True
kwargs['
compress
'] = True
del items[0]
del items[0]
...
@@ -319,7 +329,12 @@ class DB(TM):
...
@@ -319,7 +329,12 @@ class DB(TM):
error
=
True
,
error
=
True
,
)
)
self
.
db
=
MySQLdb
.
connect
(
**
self
.
_kw_args
)
self
.
db
=
MySQLdb
.
connect
(
**
self
.
_kw_args
)
self
.
_query
(
"SET time_zone='+00:00'"
)
self
.
_query
(
b"SET time_zone='+00:00'"
)
# BBB mysqlclient on python2 does not support sql_mode, check that
# the connection is actually encrypted.
if
self
.
_kw_args
.
get
(
'ssl'
)
and
\
not
self
.
_query
(
b"SHOW STATUS LIKE 'Ssl_version'"
).
fetch_row
()[
0
][
1
]:
raise
NotSupportedError
(
"Connection established without SSL"
)
def
tables
(
self
,
rdb
=
0
,
def
tables
(
self
,
rdb
=
0
,
_care
=
(
'TABLE'
,
'VIEW'
)):
_care
=
(
'TABLE'
,
'VIEW'
)):
...
...
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