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
Levin Zimmermann
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
Show 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
...
@@ -27,12 +27,13 @@
...
@@ -27,12 +27,13 @@
#
#
##############################################################################
##############################################################################
import
unittest
import
six
from
six.moves.urllib_parse
import
urlparse
,
parse_qsl
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.Sequence
import
SequenceList
from
DateTime
import
DateTime
from
DateTime
import
DateTime
class
TestPasswordTool
(
ERP5TypeTestCase
):
class
TestPasswordTool
(
ERP5TypeTestCase
):
"""
"""
Test reset of password
Test reset of password
...
@@ -47,6 +48,22 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -47,6 +48,22 @@ class TestPasswordTool(ERP5TypeTestCase):
self
.
portal
.
email_from_address
=
'site@example.invalid'
self
.
portal
.
email_from_address
=
'site@example.invalid'
self
.
portal
.
MailHost
.
reset
()
self
.
portal
.
MailHost
.
reset
()
self
.
portal
.
portal_caches
.
clearAllCache
()
self
.
portal
.
portal_caches
.
clearAllCache
()
self
.
_createUser
(
"userA"
)
def
_createUser
(
self
,
base_name
):
person
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
"Person"
,
reference
=
base_name
,
default_email_text
=
"{base_name}@example.invalid"
.
format
(
base_name
=
base_name
))
assignment
=
person
.
newContent
(
portal_type
=
'Assignment'
)
assignment
.
open
()
login
=
person
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
'{base_name}-login'
.
format
(
base_name
=
base_name
),
password
=
'{base_name}-password'
.
format
(
base_name
=
base_name
),
)
login
.
validate
()
self
.
tic
()
def
beforeTearDown
(
self
):
def
beforeTearDown
(
self
):
self
.
abort
()
self
.
abort
()
...
@@ -92,275 +109,175 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -92,275 +109,175 @@ class TestPasswordTool(ERP5TypeTestCase):
"Plugin %s should not have authenticated '%s' with password '%s'"
%
"Plugin %s should not have authenticated '%s' with password '%s'"
%
(
plugin_name
,
login
,
password
))
(
plugin_name
,
login
,
password
))
def
stepAddUser
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
def
test_password_reset
(
self
):
"""
self
.
_assertUserExists
(
'userA-login'
,
'userA-password'
)
Create a user
self
.
_assertUserDoesNotExists
(
'userA-login'
,
'bad'
)
"""
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
person
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
"Person"
,
user_login
=
'userA-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
reference
=
"userA"
,
default_email_text
=
"userA@example.invalid"
)
assignment
=
person
.
newContent
(
portal_type
=
'Assignment'
)
assignment
.
open
()
login
=
person
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
'userA-login'
,
password
=
'passwordA'
,
)
login
.
validate
()
def
stepCheckPasswordToolExists
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Check existence of password tool
"""
self
.
assertTrue
(
self
.
getPasswordTool
()
is
not
None
)
def
stepCheckUserLogin
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Check existence of password tool
"""
self
.
_assertUserExists
(
'userA-login'
,
'passwordA'
)
def
stepCheckUserLoginWithNewPassword
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Check existence of password tool
"""
self
.
_assertUserExists
(
'userA-login'
,
'secret'
)
def
stepCheckUserNotLoginWithBadPassword
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Check existence of password tool
"""
self
.
_assertUserDoesNotExists
(
'userA'
,
'secret'
)
def
stepCheckUserNotLoginWithFormerPassword
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Check existence of password tool
"""
self
.
_assertUserDoesNotExists
(
'userA'
,
'passwordA'
)
def
stepLostPassword
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Required a new password
"""
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userA-login"
)
def
stepTryLostPasswordWithBadUser
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Required a new password
"""
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userZ-login"
)
def
stepCheckNoMailSent
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
"""
self
.
assertIn
((
"portal_status_message"
,
"An email has been sent to you."
),
query_string_param
)
Check mail has not been sent after fill in wrong the form password
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
"""
self
.
tic
()
last_message
=
self
.
portal
.
MailHost
.
_last_message
self
.
assertEqual
((),
last_message
)
def
stepCheckMailSent
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
(
mfrom
,
mto
,
mbody
),
=
self
.
portal
.
MailHost
.
getMessageList
()
"""
Check mail has been sent after fill in the form password
"""
last_message
=
self
.
portal
.
MailHost
.
_last_message
self
.
assertNotEqual
((),
last_message
)
mfrom
,
mto
,
_
=
last_message
self
.
assertEqual
(
'Portal Administrator <site@example.invalid>'
,
mfrom
)
self
.
assertEqual
(
'Portal Administrator <site@example.invalid>'
,
mfrom
)
self
.
assertEqual
([
'userA@example.invalid'
],
mto
)
self
.
assertEqual
([
'userA@example.invalid'
],
mto
)
reset_key
,
=
list
(
six
.
iterkeys
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
assertIn
(
(
'PasswordTool_viewResetPassword?reset_key='
+
reset_key
).
encode
(),
mbody
)
ret
=
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
password
=
"new-password"
,
password_confirm
=
"new-password"
,
password_key
=
reset_key
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
self
.
assertIn
((
"portal_status_message"
,
"Password changed."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'new-password'
)
self
.
_assertUserDoesNotExists
(
'userA-login'
,
'userA-password'
)
# key no longer work
ret
=
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
password
=
"new-password"
,
password_confirm
=
"new-password"
,
password_key
=
reset_key
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
self
.
assertIn
((
"portal_status_message"
,
"Key not known. Please ask reset password."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"error"
),
query_string_param
)
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'new-password'
)
self
.
_assertUserDoesNotExists
(
'userA-login'
,
'userA-password'
)
def
stepGoToRandomAddress
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
def
test_password_reset_request_for_non_existing_user
(
self
):
"""
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
Call method that change the password
user_login
=
'not exist'
,
REQUEST
=
self
.
portal
.
REQUEST
)
We don't check use of random url in mail here as we have on request
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
But random is also check by changeUserPassword, so it's the same
self
.
assertIn
((
"portal_status_message"
,
"An email has been sent to you."
),
query_string_param
)
"""
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
key
=
self
.
portal
.
portal_password
.
_password_request_dict
.
keys
()[
0
]
self
.
tic
()
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
self
.
assertFalse
(
self
.
portal
.
MailHost
.
getMessageList
())
password
=
"secret"
,
password_confirmation
=
"secret"
,
password_key
=
key
)
# reset cache
self
.
portal
.
portal_caches
.
clearAllCache
()
def
stepGoToRandomAddressWithBadUserName
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Call method that change the password with a bad user name
This must not work
"""
key
=
self
.
portal
.
portal_password
.
_password_request_dict
.
keys
()[
0
]
sequence
.
edit
(
key
=
key
)
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userZ-login"
,
password
=
"secret"
,
password_confirmation
=
"secret"
,
password_key
=
key
)
# reset cache
self
.
portal
.
portal_caches
.
clearAllCache
()
def
stepGoToRandomAddressTwice
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
def
test_password_reset_request_for_wildcard_username
(
self
):
"""
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
As we already change password, this must npot work anylonger
user_login
=
'%'
,
REQUEST
=
self
.
portal
.
REQUEST
)
"""
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
key
=
sequence
.
get
(
'key'
)
self
.
assertIn
((
"portal_status_message"
,
"An email has been sent to you."
),
query_string_param
)
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
password
=
"passwordA"
,
self
.
tic
()
password_confirmation
=
"passwordA"
,
self
.
assertFalse
(
self
.
portal
.
MailHost
.
getMessageList
())
password_key
=
key
)
# reset cache
def
test_password_reset_request_for_different_user
(
self
):
self
.
portal
.
portal_caches
.
clearAllCache
()
self
.
_createUser
(
'userB'
)
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
'userA-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
reset_key
,
=
list
(
six
.
iterkeys
(
self
.
portal
.
portal_password
.
_password_request_dict
))
ret
=
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userB-login"
,
password
=
"new-password"
,
password_confirm
=
"new-password"
,
password_key
=
reset_key
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
self
.
assertIn
((
"portal_status_message"
,
"Bad login provided."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"error"
),
query_string_param
)
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'userA-password'
)
self
.
_assertUserExists
(
'userB-login'
,
'userB-password'
)
self
.
_assertUserDoesNotExists
(
'userB-login'
,
'new-password'
)
def
test_password_reset_unknown_key
(
self
):
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
'userA-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
ret
=
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
password
=
"new-password"
,
password_confirm
=
"new-password"
,
password_key
=
'wrong key'
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
self
.
assertIn
((
"portal_status_message"
,
"Key not known. Please ask reset password."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"error"
),
query_string_param
)
self
.
tic
()
def
stepGoToBadRandomAddress
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
def
test_password_reset_date_expired
(
self
):
"""
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
'userA-login'
)
Try to reset a password with bad random part
(
reset_key
,
(
login
,
date
)),
=
list
(
six
.
iteritems
(
"""
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
self
.
assertTrue
(
date
.
isFuture
())
password
=
"secret"
,
self
.
portal
.
portal_password
.
_password_request_dict
[
reset_key
]
=
(
password_confirmation
=
"secret"
,
login
,
password_key
=
"toto"
)
DateTime
()
-
1
# reset cache
)
self
.
portal
.
portal_caches
.
clearAllCache
()
ret
=
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
password
=
"new-password"
,
password_confirm
=
"new-password"
,
password_key
=
reset_key
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
self
.
assertIn
((
"portal_status_message"
,
"Date has expired."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"error"
),
query_string_param
)
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'userA-password'
)
self
.
_assertUserDoesNotExists
(
'userA-login'
,
'new-password'
)
def
stepModifyExpirationDate
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Change expiration date so that reset of password is not available
"""
# save key for url
key
=
self
.
portal
.
portal_password
.
_password_request_dict
.
keys
()[
0
]
sequence
.
edit
(
key
=
key
)
# modify date
for
k
,
v
in
self
.
portal
.
portal_password
.
_password_request_dict
.
items
():
login
,
date
=
v
date
=
DateTime
()
-
1
self
.
portal
.
portal_password
.
_password_request_dict
[
k
]
=
(
login
,
date
)
def
stepSimulateExpirationAlarm
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Simulate alarm wich remove expired request
"""
self
.
portal
.
portal_password
.
removeExpiredRequests
()
self
.
portal
.
portal_password
.
removeExpiredRequests
()
self
.
assertFalse
(
list
(
six
.
iterkeys
(
def
stepCheckNoRequestRemains
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
self
.
portal
.
portal_password
.
_password_request_dict
)))
"""
after alarm all expired request must have been removed
def
test_password_reset_password_and_confirmation_do_not_match
(
self
):
"""
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
self
.
assertEqual
(
len
(
self
.
portal
.
portal_password
.
_password_request_dict
),
0
)
user_login
=
'userA-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
reset_key
,
=
list
(
six
.
iterkeys
(
def
stepLogout
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
self
.
portal
.
portal_password
.
_password_request_dict
))
"""
Logout
ret
=
self
.
portal
.
portal_password
.
changeUserPassword
(
"""
user_login
=
"userA-login"
,
self
.
logout
()
password
=
"new-password"
,
password_confirm
=
"wrong-password"
,
# tests
password_key
=
reset_key
)
def
test_01_checkPasswordTool
(
self
):
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
sequence_list
=
SequenceList
()
self
.
assertIn
((
"portal_status_message"
,
"Password does not match the confirm password."
),
query_string_param
)
sequence_string
=
'CheckPasswordToolExists '
\
self
.
assertIn
((
"portal_status_level"
,
"error"
),
query_string_param
)
'AddUser Tic '
\
'Logout '
\
'CheckUserLogin CheckUserNotLoginWithBadPassword '
\
'TryLostPasswordWithBadUser Tic '
\
'CheckNoMailSent '
\
'GoToBadRandomAddress Tic '
\
'CheckUserLogin CheckUserNotLoginWithBadPassword '
\
'LostPassword Tic '
\
'CheckMailSent GoToRandomAddress Tic '
\
'CheckUserLoginWithNewPassword '
\
'CheckUserNotLoginWithFormerPassword '
\
'GoToRandomAddressTwice Tic '
\
'CheckUserLoginWithNewPassword '
\
'CheckUserNotLoginWithFormerPassword '
\
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
play
(
self
)
def
test_02_checkPasswordToolDateExpired
(
self
):
sequence_list
=
SequenceList
()
sequence_string
=
'CheckPasswordToolExists '
\
'AddUser Tic '
\
'Logout '
\
'CheckUserLogin CheckUserNotLoginWithBadPassword '
\
'LostPassword Tic '
\
'CheckMailSent '
\
'ModifyExpirationDate '
\
'GoToRandomAddress Tic '
\
'CheckUserLogin CheckUserNotLoginWithBadPassword '
\
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
play
(
self
)
def
test_03_checkPasswordToolAlarm
(
self
):
sequence_list
=
SequenceList
()
sequence_string
=
'CheckPasswordToolExists '
\
'AddUser Tic '
\
'Logout '
\
'CheckUserLogin CheckUserNotLoginWithBadPassword '
\
'LostPassword Tic '
\
'CheckMailSent '
\
'ModifyExpirationDate '
\
'SimulateExpirationAlarm '
\
'CheckNoRequestRemains '
\
'GoToRandomAddressTwice Tic '
\
'CheckUserLogin CheckUserNotLoginWithBadPassword '
\
sequence_list
.
addSequenceString
(
sequence_string
)
sequence_list
.
play
(
self
)
def
test_two_concurrent_password_reset
(
self
):
def
test_two_concurrent_password_reset
(
self
):
personA
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
"Person"
,
self
.
_createUser
(
'userB'
)
reference
=
"userA"
,
self
.
_assertUserExists
(
'userA-login'
,
'userA-password'
)
default_email_text
=
"userA@example.invalid"
)
self
.
_assertUserExists
(
'userB-login'
,
'userB-password'
)
assignment
=
personA
.
newContent
(
portal_type
=
'Assignment'
)
assignment
.
open
()
login
=
personA
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
'userA-login'
,
password
=
'passwordA'
,
)
login
.
validate
()
personB
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
"Person"
,
reference
=
"userB"
,
default_email_text
=
"userB@example.invalid"
)
assignment
=
personB
.
newContent
(
portal_type
=
'Assignment'
)
assignment
.
open
()
login
=
personB
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
'userB-login'
,
password
=
'passwordB'
,
)
login
.
validate
()
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'passwordA'
)
self
.
_assertUserExists
(
'userB-login'
,
'passwordB'
)
self
.
assertEqual
(
0
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
assertEqual
(
0
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userA-login"
)
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userA-login"
)
self
.
assertEqual
(
1
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
assertEqual
(
1
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
key_a
=
self
.
portal
.
portal_password
.
_password_request_dict
.
keys
(
)[
0
]
key_a
=
list
(
six
.
iterkeys
(
self
.
portal
.
portal_password
.
_password_request_dict
)
)[
0
]
self
.
tic
()
self
.
tic
()
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userB-login"
)
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userB-login"
)
possible_key_list
=
\
possible_key_list
=
\
self
.
portal
.
portal_password
.
_password_request_dict
.
keys
(
)
list
(
six
.
iterkeys
(
self
.
portal
.
portal_password
.
_password_request_dict
)
)
self
.
assertEqual
(
2
,
len
(
possible_key_list
))
self
.
assertEqual
(
2
,
len
(
possible_key_list
))
key_b
=
[
k
for
k
in
possible_key_list
if
k
!=
key_a
][
0
]
key_b
=
[
k
for
k
in
possible_key_list
if
k
!=
key_a
][
0
]
self
.
tic
()
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'
passwordA
'
)
self
.
_assertUserExists
(
'userA-login'
,
'
userA-password
'
)
self
.
_assertUserExists
(
'userB-login'
,
'
passwordB
'
)
self
.
_assertUserExists
(
'userB-login'
,
'
userB-password
'
)
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userA-login"
,
password
=
"newA"
,
password
=
"newA"
,
password_confirm
ation
=
"newA"
,
password_confirm
=
"newA"
,
password_key
=
key_a
)
password_key
=
key_a
)
self
.
tic
()
self
.
tic
()
self
.
_assertUserExists
(
'userA-login'
,
'newA'
)
self
.
_assertUserExists
(
'userA-login'
,
'newA'
)
self
.
_assertUserExists
(
'userB-login'
,
'
passwordB
'
)
self
.
_assertUserExists
(
'userB-login'
,
'
userB-password
'
)
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userB-login"
,
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userB-login"
,
password
=
"newB"
,
password
=
"newB"
,
password_confirm
ation
=
"newB"
,
password_confirm
=
"newB"
,
password_key
=
key_b
)
password_key
=
key_b
)
self
.
tic
()
self
.
tic
()
...
@@ -390,8 +307,7 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -390,8 +307,7 @@ class TestPasswordTool(ERP5TypeTestCase):
self
.
assertEqual
(
0
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
assertEqual
(
0
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userZ-login "
)
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
"userZ-login "
)
self
.
assertEqual
(
1
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
self
.
assertEqual
(
1
,
len
(
self
.
portal
.
portal_password
.
_password_request_dict
))
key_a
,
=
list
(
six
.
iterkeys
(
self
.
portal
.
portal_password
.
_password_request_dict
))
key_a
=
self
.
portal
.
portal_password
.
_password_request_dict
.
keys
()[
0
]
self
.
tic
()
self
.
tic
()
self
.
_assertUserExists
(
'userZ-login '
,
'passwordZ'
)
self
.
_assertUserExists
(
'userZ-login '
,
'passwordZ'
)
...
@@ -399,7 +315,7 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -399,7 +315,7 @@ class TestPasswordTool(ERP5TypeTestCase):
# Check that password is not changed if trailing space is not entered
# Check that password is not changed if trailing space is not entered
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userZ-login"
,
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userZ-login"
,
password
=
"newZ"
,
password
=
"newZ"
,
password_confirm
ation
=
"newZ"
,
password_confirm
=
"newZ"
,
password_key
=
key_a
)
password_key
=
key_a
)
self
.
tic
()
self
.
tic
()
self
.
_assertUserExists
(
'userZ-login '
,
'passwordZ'
)
self
.
_assertUserExists
(
'userZ-login '
,
'passwordZ'
)
...
@@ -407,7 +323,7 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -407,7 +323,7 @@ class TestPasswordTool(ERP5TypeTestCase):
# Check that password is changed if trailing space is entered
# Check that password is changed if trailing space is entered
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userZ-login "
,
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"userZ-login "
,
password
=
"newZ2"
,
password
=
"newZ2"
,
password_confirm
ation
=
"newZ2"
,
password_confirm
=
"newZ2"
,
password_key
=
key_a
)
password_key
=
key_a
)
self
.
tic
()
self
.
tic
()
self
.
_assertUserExists
(
'userZ-login '
,
'newZ2'
)
self
.
_assertUserExists
(
'userZ-login '
,
'newZ2'
)
...
@@ -429,10 +345,13 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -429,10 +345,13 @@ class TestPasswordTool(ERP5TypeTestCase):
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
'user-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
user_login
=
'user-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
# For security reasons, the message should always be the same
# For security reasons, the message should always be the same
self
.
assertIn
(
"portal_status_message=An+email+has+been+sent+to+you."
,
str
(
ret
))
self
.
assertIn
((
"portal_status_message"
,
"An email has been sent to you."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
# But no mail has been sent
# But no mail has been sent
self
.
stepCheckNoMailSent
(
)
self
.
assertFalse
(
self
.
portal
.
MailHost
.
getMessageList
()
)
def
test_unreachable_email_on_person
(
self
):
def
test_unreachable_email_on_person
(
self
):
person
=
self
.
portal
.
person_module
.
newContent
(
person
=
self
.
portal
.
person_module
.
newContent
(
...
@@ -455,10 +374,13 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -455,10 +374,13 @@ class TestPasswordTool(ERP5TypeTestCase):
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
'user-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
user_login
=
'user-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
# For security reasons, the message should always be the same
# For security reasons, the message should always be the same
self
.
assertIn
(
"portal_status_message=An+email+has+been+sent+to+you."
,
str
(
ret
))
self
.
assertIn
((
"portal_status_message"
,
"An email has been sent to you."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
# But no mail has been sent
# But no mail has been sent
self
.
stepCheckNoMailSent
(
)
self
.
assertFalse
(
self
.
portal
.
MailHost
.
getMessageList
()
)
def
test_acquired_email_on_person
(
self
):
def
test_acquired_email_on_person
(
self
):
organisation
=
self
.
portal
.
organisation_module
.
newContent
(
organisation
=
self
.
portal
.
organisation_module
.
newContent
(
...
@@ -482,12 +404,10 @@ class TestPasswordTool(ERP5TypeTestCase):
...
@@ -482,12 +404,10 @@ class TestPasswordTool(ERP5TypeTestCase):
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
ret
=
self
.
portal
.
portal_password
.
mailPasswordResetRequest
(
user_login
=
'user-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
user_login
=
'user-login'
,
REQUEST
=
self
.
portal
.
REQUEST
)
query_string_param
=
parse_qsl
(
urlparse
(
str
(
ret
)).
query
)
# For security reasons, the message should always be the same
# For security reasons, the message should always be the same
self
.
assertIn
(
"portal_status_message=An+email+has+been+sent+to+you."
,
str
(
ret
))
self
.
assertIn
((
"portal_status_message"
,
"An email has been sent to you."
),
query_string_param
)
self
.
assertIn
((
"portal_status_level"
,
"success"
),
query_string_param
)
# But no mail has been sent
# But no mail has been sent
self
.
stepCheckNoMailSent
(
)
self
.
assertFalse
(
self
.
portal
.
MailHost
.
getMessageList
()
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestPasswordTool
))
return
suite
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,15 +363,17 @@ class ComponentDynamicPackage(ModuleType):
...
@@ -355,15 +363,17 @@ 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
,
"%s: cannot load Component %s :
\
n
%s"
%
(
fullname
,
name
,
traceback
.
format_exc
()),
sys
.
exc_info
()[
2
])
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
...
...
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,6 +154,7 @@ class _(PatchClass(PythonScript)):
...
@@ -153,6 +154,7 @@ class _(PatchClass(PythonScript)):
# Add proxy role icon in ZMI
# Add proxy role icon in ZMI
if
IS_ZOPE2
:
def
om_icons
(
self
):
def
om_icons
(
self
):
"""Return a list of icon URLs to be displayed by an ObjectManager"""
"""Return a list of icon URLs to be displayed by an ObjectManager"""
if
self
.
_proxy_roles
:
if
self
.
_proxy_roles
:
...
@@ -164,7 +166,13 @@ class _(PatchClass(PythonScript)):
...
@@ -164,7 +166,13 @@ class _(PatchClass(PythonScript)):
p_
.
PythonScript_ProxyRole_icon
=
\
p_
.
PythonScript_ProxyRole_icon
=
\
ImageFile
(
'pyscript_proxyrole.gif'
,
globals
())
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