Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
erp5_rtl_support
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Romain Courteaud
erp5_rtl_support
Commits
cd9feb3c
Commit
cd9feb3c
authored
Oct 27, 2016
by
Kazuhiko Shiozaki
Committed by
Vincent Pelletier
Dec 23, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_authentication_policy: migrate to ERP5 Login authentication.
parent
5ae11aeb
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
204 additions
and
189 deletions
+204
-189
bt5/erp5_authentication_policy/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
...rtalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_analyzePassword.py
...skins/erp5_authentication_policy/Login_analyzePassword.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_analyzePassword.xml
...kins/erp5_authentication_policy/Login_analyzePassword.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_getListboxUrl.py
...l_skins/erp5_authentication_policy/Login_getListboxUrl.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_getListboxUrl.xml
..._skins/erp5_authentication_policy/Login_getListboxUrl.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_isLoginBlocked.py
..._skins/erp5_authentication_policy/Login_isLoginBlocked.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_isLoginBlocked.xml
...skins/erp5_authentication_policy/Login_isLoginBlocked.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_isPasswordExpired.py
...ins/erp5_authentication_policy/Login_isPasswordExpired.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_isPasswordExpired.xml
...ns/erp5_authentication_policy/Login_isPasswordExpired.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_isPasswordValid.py
...skins/erp5_authentication_policy/Login_isPasswordValid.py
+3
-17
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_isPasswordValid.xml
...kins/erp5_authentication_policy/Login_isPasswordValid.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_notifyLoginFailure.py
...ns/erp5_authentication_policy/Login_notifyLoginFailure.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_notifyLoginFailure.xml
...s/erp5_authentication_policy/Login_notifyLoginFailure.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_notifyPasswordExpire.py
.../erp5_authentication_policy/Login_notifyPasswordExpire.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_notifyPasswordExpire.xml
...erp5_authentication_policy/Login_notifyPasswordExpire.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_unblockLogin.py
...al_skins/erp5_authentication_policy/Login_unblockLogin.py
+0
-0
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/Login_unblockLogin.xml
...l_skins/erp5_authentication_policy/Login_unblockLogin.xml
+1
-1
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/SystemEventModule_viewBlockUseLoginList/listbox.xml
...olicy/SystemEventModule_viewBlockUseLoginList/listbox.xml
+3
-3
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/interactions/changePassword.xml
...word_interaction_workflow/interactions/changePassword.xml
+8
-2
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/scripts/afterChangePassword.py
...sword_interaction_workflow/scripts/afterChangePassword.py
+7
-8
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/scripts/afterChangePassword.xml
...word_interaction_workflow/scripts/afterChangePassword.xml
+1
-1
bt5/erp5_authentication_policy/bt/template_portal_type_workflow_chain_list
...cation_policy/bt/template_portal_type_workflow_chain_list
+1
-1
bt5/erp5_system_event/SkinTemplateItem/portal_skins/erp5_system_event/PasswordEvent_view/my_destination_title.xml
..._system_event/PasswordEvent_view/my_destination_title.xml
+2
-2
bt5/erp5_system_event/SkinTemplateItem/portal_skins/erp5_system_event/PasswordEvent_view/my_source_title.xml
.../erp5_system_event/PasswordEvent_view/my_source_title.xml
+2
-2
product/ERP5/tests/testAuthenticationPolicy.py
product/ERP5/tests/testAuthenticationPolicy.py
+168
-144
No files found.
bt5/erp5_authentication_policy/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
View file @
cd9feb3c
<workflow_chain>
<chain>
<type>
Perso
n
</type>
<type>
ERP5 Logi
n
</type>
<workflow>
password_interaction_workflow
</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_analyzePassword.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_analyzePassword.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_analyzePassword.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_analyzePassword.xml
View file @
cd9feb3c
...
...
@@ -62,7 +62,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_analyzePassword
</string>
</value>
<value>
<string>
Logi
n_analyzePassword
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_getListboxUrl.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_getListboxUrl.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_getListboxUrl.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_getListboxUrl.xml
View file @
cd9feb3c
...
...
@@ -54,7 +54,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_getListboxUrl
</string>
</value>
<value>
<string>
Logi
n_getListboxUrl
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_isLoginBlocked.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_isLoginBlocked.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_isLoginBlocked.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_isLoginBlocked.xml
View file @
cd9feb3c
...
...
@@ -62,7 +62,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_isLoginBlocked
</string>
</value>
<value>
<string>
Logi
n_isLoginBlocked
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_isPasswordExpired.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_isPasswordExpired.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_isPasswordExpired.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_isPasswordExpired.xml
View file @
cd9feb3c
...
...
@@ -62,7 +62,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_isPasswordExpired
</string>
</value>
<value>
<string>
Logi
n_isPasswordExpired
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Base
_isPasswordValid.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Login
_isPasswordValid.py
View file @
cd9feb3c
...
...
@@ -13,27 +13,13 @@ message_dict = { 0: 'Unknown error',
-
4
:
'You have already used this password.'
,
-
5
:
'You can not use any parts of your first and last name in password.'
}
def
doValidation
(
perso
n
,
password
):
def
doValidation
(
logi
n
,
password
):
# raise so Formulator shows proper message
result_code_list
=
person
.
Person_
analyzePassword
(
password
)
result_code_list
=
login
.
analyzePassword
(
password
)
if
result_code_list
!=
[]:
translateString
=
context
.
Base_translateString
message
=
' '
.
join
([
translateString
(
message_dict
[
x
])
for
x
in
result_code_list
])
raise
ValidationError
(
'external_validator_failed'
,
context
,
error_text
=
message
)
return
1
user_login
=
request
.
get
(
'field_user_login'
,
None
)
# find Person object (or authenticated member) and validate it on it (password recovered for an existing account)
person
=
context
.
ERP5Site_getAuthenticatedMemberPersonValue
(
user_login
)
if
person
is
not
None
:
return
doValidation
(
person
,
password
)
# use a temp object (new account created)
first_name
=
request
.
get
(
'field_your_first_name'
,
None
)
last_name
=
request
.
get
(
'field_your_last_name'
,
None
)
kw
=
{
'title'
:
'%s %s'
%
(
first_name
,
last_name
),
'first_name'
:
first_name
,
'last_name'
:
last_name
}
person
=
newTempBase
(
portal
,
kw
[
'title'
],
**
kw
)
return
doValidation
(
person
,
password
)
return
doValidation
(
context
,
password
)
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Base
_isPasswordValid.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Login
_isPasswordValid.xml
View file @
cd9feb3c
...
...
@@ -62,7 +62,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Base
_isPasswordValid
</string>
</value>
<value>
<string>
Login
_isPasswordValid
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_notifyLoginFailure.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_notifyLoginFailure.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_notifyLoginFailure.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_notifyLoginFailure.xml
View file @
cd9feb3c
...
...
@@ -63,7 +63,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_notifyLoginFailure
</string>
</value>
<value>
<string>
Logi
n_notifyLoginFailure
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_notifyPasswordExpire.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_notifyPasswordExpire.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_notifyPasswordExpire.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_notifyPasswordExpire.xml
View file @
cd9feb3c
...
...
@@ -63,7 +63,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_notifyPasswordExpire
</string>
</value>
<value>
<string>
Logi
n_notifyPasswordExpire
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_unblockLogin.py
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_unblockLogin.py
View file @
cd9feb3c
File moved
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Perso
n_unblockLogin.xml
→
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/
Logi
n_unblockLogin.xml
View file @
cd9feb3c
...
...
@@ -54,7 +54,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Perso
n_unblockLogin
</string>
</value>
<value>
<string>
Logi
n_unblockLogin
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/SkinTemplateItem/portal_skins/erp5_authentication_policy/SystemEventModule_viewBlockUseLoginList/listbox.xml
View file @
cd9feb3c
...
...
@@ -174,15 +174,15 @@
<list>
<tuple>
<string>
title
</string>
<string>
Perso
n_getListboxUrl
</string>
<string>
Logi
n_getListboxUrl
</string>
</tuple>
<tuple>
<string>
reference
</string>
<string>
Perso
n_getListboxUrl
</string>
<string>
Logi
n_getListboxUrl
</string>
</tuple>
<tuple>
<string>
count
</string>
<string>
Perso
n_getListboxUrl
</string>
<string>
Logi
n_getListboxUrl
</string>
</tuple>
</list>
</value>
...
...
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/interactions/changePassword.xml
View file @
cd9feb3c
...
...
@@ -28,7 +28,7 @@
<key>
<string>
after_script_name
</string>
</key>
<value>
<list>
<string>
Person_c
hangePassword
</string>
<string>
afterC
hangePassword
</string>
</list>
</value>
</item>
...
...
@@ -72,10 +72,16 @@
<key>
<string>
portal_type_filter
</string>
</key>
<value>
<list>
<string>
Perso
n
</string>
<string>
ERP5 Logi
n
</string>
</list>
</value>
</item>
<item>
<key>
<string>
portal_type_group_filter
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
script_name
</string>
</key>
<value>
...
...
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/scripts/
Person_c
hangePassword.py
→
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/scripts/
afterC
hangePassword.py
View file @
cd9feb3c
from
DateTime
import
DateTime
portal
=
context
.
getPortalObject
()
person
=
state_change
[
'object'
]
login
=
state_change
[
'object'
]
portal
=
login
.
getPortalObject
()
# check preferences and save only if set
number_of_last_password_to_check
=
portal
.
portal_preferences
.
getPreferredNumberOfLastPasswordToCheck
()
if
number_of_last_password_to_check
is
not
None
and
number_of_last_password_to_check
:
# save password and modification date
current_password
=
perso
n
.
getPassword
()
current_password
=
logi
n
.
getPassword
()
if
current_password
is
not
None
:
password_event
=
portal
.
system_event_module
.
newContent
(
portal_type
=
'Password Event'
,
source_value
=
perso
n
,
destination_value
=
perso
n
,
password
=
current_password
)
password_event
=
portal
.
system_event_module
.
newContent
(
portal_type
=
'Password Event'
,
source_value
=
logi
n
,
destination_value
=
logi
n
,
password
=
current_password
)
password_event
.
confirm
()
# Person_isPasswordExpired cache the wrong result if document is not in catalog.
# As the document is created in the same transaction, it is possible to force reindexation
...
...
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/scripts/
Person_c
hangePassword.xml
→
bt5/erp5_authentication_policy/WorkflowTemplateItem/portal_workflow/password_interaction_workflow/scripts/
afterC
hangePassword.xml
View file @
cd9feb3c
...
...
@@ -63,7 +63,7 @@
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Person_c
hangePassword
</string>
</value>
<value>
<string>
afterC
hangePassword
</string>
</value>
</item>
</dictionary>
</pickle>
...
...
bt5/erp5_authentication_policy/bt/template_portal_type_workflow_chain_list
View file @
cd9feb3c
Person | password_interaction_workflow
\ No newline at end of file
ERP5 Login | password_interaction_workflow
\ No newline at end of file
bt5/erp5_system_event/SkinTemplateItem/portal_skins/erp5_system_event/PasswordEvent_view/my_destination_title.xml
View file @
cd9feb3c
...
...
@@ -102,8 +102,8 @@
<value>
<list>
<tuple>
<string>
Perso
n
</string>
<string>
Perso
n
</string>
<string>
ERP5 Logi
n
</string>
<string>
ERP5 Logi
n
</string>
</tuple>
</list>
</value>
...
...
bt5/erp5_system_event/SkinTemplateItem/portal_skins/erp5_system_event/PasswordEvent_view/my_source_title.xml
View file @
cd9feb3c
...
...
@@ -102,8 +102,8 @@
<value>
<list>
<tuple>
<string>
Perso
n
</string>
<string>
Perso
n
</string>
<string>
ERP5 Logi
n
</string>
<string>
ERP5 Logi
n
</string>
</tuple>
</list>
</value>
...
...
product/ERP5/tests/testAuthenticationPolicy.py
View file @
cd9feb3c
...
...
@@ -66,10 +66,12 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
reference
=
'test'
)
if
portal
.
portal_catalog
.
getResultValue
(
**
kw
)
is
None
:
# add a loggable Person
person
=
portal
.
person_module
.
newContent
(
password
=
'test'
,
first_name
=
'First'
,
last_name
=
'Last'
,
**
kw
)
person
=
self
.
createUser
(
kw
[
'reference'
],
password
=
'test'
,
person_kw
=
{
'first_name'
:
'First'
,
'last_name'
:
'Last'
},
)
person
.
validate
()
assignment
=
person
.
newContent
(
portal_type
=
'Assignment'
)
assignment
.
open
()
...
...
@@ -91,16 +93,33 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
'erp5_content_short'
,
# for authentication cache
))
def
_getPasswordEventList
(
self
,
perso
n
):
def
_getPasswordEventList
(
self
,
logi
n
):
return
[
x
.
getObject
()
for
x
in
self
.
portal
.
portal_catalog
(
portal_type
=
'Password Event'
,
default_destination_uid
=
perso
n
.
getUid
(),
default_destination_uid
=
logi
n
.
getUid
(),
sort_on
=
((
'creation_date'
,
'DESC'
,),))]
def
_cleanUp
Person
(
self
,
perso
n
):
self
.
portal
.
system_event_module
.
manage_delObjects
([
x
.
getId
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
def
_cleanUp
Login
(
self
,
logi
n
):
self
.
portal
.
system_event_module
.
manage_delObjects
([
x
.
getId
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
def
createUser
(
self
,
reference
,
password
=
None
,
person_kw
=
None
):
"""
Modified version from ERP5TypeTestCase, that does set reference as
password when password is None.
"""
if
person_kw
is
None
:
person_kw
=
{}
person
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
reference
,
**
person_kw
)
login
=
person
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
reference
,
password
=
password
)
login
.
validate
()
return
person
def
test_01_BlockLogin
(
self
):
"""
Test that a recataloging works for Web Site documents
...
...
@@ -110,73 +129,74 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
reference
=
'test'
)
login
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)[
0
]
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
# login should be allowed
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# file some failures so we should detect and block account
perso
n
.
notifyLoginFailure
()
perso
n
.
notifyLoginFailure
()
perso
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
self
.
tic
()
# should be blocked
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
# set check back interval to actualy disable blocking
preference
.
setPreferredAuthenticationFailureCheckDuration
(
0
)
self
.
_clearCache
()
self
.
tic
()
time
.
sleep
(
1
)
# we need to give a moment
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# .. and revert it back
preference
.
setPreferredAuthenticationFailureCheckDuration
(
600
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
# increase failures attempts
preference
.
setPreferredMaxAuthenticationFailure
(
4
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# .. and revert it back
preference
.
setPreferredMaxAuthenticationFailure
(
3
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
# set short block interval so we can test it as well
preference
.
setPreferredAuthenticationFailureBlockDuration
(
3
)
self
.
_clearCache
()
self
.
tic
()
time
.
sleep
(
4
)
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# test multiple concurrent transactions without waiting for activities to be over
preference
.
setPreferredAuthenticationFailureCheckDuration
(
600
)
preference
.
setPreferredAuthenticationFailureBlockDuration
(
600
)
preference
.
setPreferredMaxAuthenticationFailure
(
3
)
person
.
Perso
n_unblockLogin
()
login
.
Logi
n_unblockLogin
()
self
.
_clearCache
()
self
.
tic
()
perso
n
.
notifyLoginFailure
()
perso
n
.
notifyLoginFailure
()
perso
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
self
.
commit
()
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
# test unblock account
person
.
Perso
n_unblockLogin
()
login
.
Logi
n_unblockLogin
()
self
.
tic
()
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
def
test_02_PasswordHistory
(
self
):
...
...
@@ -186,61 +206,61 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
portal
=
self
.
getPortal
()
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
person
=
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'test-02'
)
person
=
self
.
createUser
(
'test-02'
)
login
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)[
0
]
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
self
.
tic
()
# Check that last (X where X is set in preferences) passwords are saved.
self
.
assertEqual
([],
self
.
_getPasswordEventList
(
perso
n
))
self
.
assertEqual
([],
self
.
_getPasswordEventList
(
logi
n
))
preference
.
setPreferredNumberOfLastPasswordToCheck
(
10
)
self
.
tic
()
self
.
_clearCache
()
perso
n
.
setPassword
(
'12345678'
)
logi
n
.
setPassword
(
'12345678'
)
self
.
tic
()
# password change date should be saved as well hashed old password value
old_password
=
perso
n
.
getPassword
()
self
.
assertSameSet
([
old_password
],
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
old_password
=
logi
n
.
getPassword
()
self
.
assertSameSet
([
old_password
],
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
# .. test one more time to check history of password is saved in a list
perso
n
.
setPassword
(
'123456789'
)
logi
n
.
setPassword
(
'123456789'
)
self
.
tic
()
old_password1
=
perso
n
.
getPassword
()
old_password1
=
logi
n
.
getPassword
()
# password change date should be saved as well hashed old password value
self
.
assertSameSet
([
old_password1
,
old_password
],
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
self
.
assertSameSet
([
old_password1
,
old_password
],
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
# other methods (_setPassword)...
perso
n
.
_setPassword
(
'123456789-1'
)
logi
n
.
_setPassword
(
'123456789-1'
)
self
.
tic
()
old_password2
=
perso
n
.
getPassword
()
old_password2
=
logi
n
.
getPassword
()
self
.
assertSameSet
([
old_password2
,
old_password1
,
old_password
],
\
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
# other methods (_forceSetPassword)...
perso
n
.
_forceSetPassword
(
'123456789-2'
)
logi
n
.
_forceSetPassword
(
'123456789-2'
)
self
.
tic
()
old_password3
=
perso
n
.
getPassword
()
old_password3
=
logi
n
.
getPassword
()
self
.
assertSameSet
([
old_password3
,
old_password2
,
old_password1
,
old_password
],
\
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
# other methods (setEncodedPassword)...
perso
n
.
setEncodedPassword
(
'123456789-3'
)
logi
n
.
setEncodedPassword
(
'123456789-3'
)
self
.
tic
()
old_password4
=
perso
n
.
getPassword
()
old_password4
=
logi
n
.
getPassword
()
self
.
assertSameSet
([
old_password4
,
old_password3
,
old_password2
,
old_password1
,
old_password
],
\
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
# other methods (edit)...
perso
n
.
edit
(
password
=
'123456789-4'
)
logi
n
.
edit
(
password
=
'123456789-4'
)
self
.
tic
()
old_password5
=
perso
n
.
getPassword
()
old_password5
=
logi
n
.
getPassword
()
self
.
assertSameSet
([
old_password5
,
old_password4
,
old_password3
,
old_password2
,
old_password1
,
old_password
],
\
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
perso
n
)])
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
logi
n
)])
def
test_03_PasswordValidity
(
self
):
...
...
@@ -258,105 +278,107 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
person
=
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'test-03'
,
password
=
'test'
,
first_name
=
'First'
,
last_name
=
'Last'
)
person
=
self
.
createUser
(
'test-03'
,
password
=
'test'
,
person_kw
=
{
'first_name'
:
'First'
,
'last_name'
:
'Last'
},
)
login
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)[
0
]
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
self
.
tic
()
# by default an empty password if nothing set in preferences is OK
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
''
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
''
))
# Not long enough passwords used
self
.
_cleanUp
Person
(
perso
n
)
self
.
_cleanUp
Login
(
logi
n
)
preference
.
setPreferredMinPasswordLength
(
8
)
preference
.
setPreferredNumberOfLastPasswordToCheck
(
0
)
self
.
tic
()
self
.
_clearCache
()
self
.
assertEqual
([
-
1
],
perso
n
.
analyzePassword
(
''
))
self
.
assertEqual
([
-
1
],
perso
n
.
analyzePassword
(
'1234567'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'12345678'
))
self
.
assertEqual
([
-
1
],
logi
n
.
analyzePassword
(
''
))
self
.
assertEqual
([
-
1
],
logi
n
.
analyzePassword
(
'1234567'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'12345678'
))
# not changed in last x days
self
.
_cleanUp
Person
(
perso
n
)
self
.
_cleanUp
Login
(
logi
n
)
preference
.
setPreferredMinPasswordLifetimeDuration
(
24
)
preference
.
setPreferredNumberOfLastPasswordToCheck
(
3
)
self
.
tic
()
self
.
_clearCache
()
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'12345678'
))
perso
n
.
setPassword
(
'12345678'
)
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'12345678'
))
logi
n
.
setPassword
(
'12345678'
)
self
.
tic
()
# if we try to change now we should fail with any password
self
.
assertSameSet
([
-
3
],
perso
n
.
analyzePassword
(
'87654321'
))
self
.
assertSameSet
([
-
1
,
-
3
],
perso
n
.
analyzePassword
(
'short'
))
# multiple failures
self
.
assertFalse
(
perso
n
.
isPasswordValid
(
'short'
))
# multiple failures
self
.
assertRaises
(
ValueError
,
perso
n
.
setPassword
,
'87654321'
)
self
.
assertSameSet
([
-
3
],
logi
n
.
analyzePassword
(
'87654321'
))
self
.
assertSameSet
([
-
1
,
-
3
],
logi
n
.
analyzePassword
(
'short'
))
# multiple failures
self
.
assertFalse
(
logi
n
.
isPasswordValid
(
'short'
))
# multiple failures
self
.
assertRaises
(
ValueError
,
logi
n
.
setPassword
,
'87654321'
)
preference
.
setPreferredMinPasswordLifetimeDuration
(
0
)
# remove restriction
self
.
tic
()
self
.
_clearCache
()
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'87654321'
))
# it's OK to change
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'87654321'
))
# it's OK to change
# password not used in previous X passwords
preference
.
setPreferredMinPasswordLength
(
None
)
# disable for now
self
.
_cleanUp
Person
(
perso
n
)
self
.
_cleanUp
Login
(
logi
n
)
self
.
_clearCache
()
self
.
tic
()
perso
n
.
setPassword
(
'12345678-new'
)
logi
n
.
setPassword
(
'12345678-new'
)
self
.
tic
()
self
.
assertSameSet
([
-
4
],
perso
n
.
analyzePassword
(
'12345678-new'
))
# if we try to change now we should fail with this EXACT password
self
.
assertRaises
(
ValueError
,
perso
n
.
setPassword
,
'12345678-new'
)
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'12345678_'
))
# it's OK with another one not used yet
self
.
assertSameSet
([
-
4
],
logi
n
.
analyzePassword
(
'12345678-new'
))
# if we try to change now we should fail with this EXACT password
self
.
assertRaises
(
ValueError
,
logi
n
.
setPassword
,
'12345678-new'
)
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'12345678_'
))
# it's OK with another one not used yet
for
password
in
[
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
]:
# this sleep is not so beautiful, but mysql datetime columns has a
# precision of one second only, and we use creation_date to order
# "Password Event" objects. So without this sleep, the test is
# failing randomly.
time
.
sleep
(
1
)
perso
n
.
setPassword
(
password
)
logi
n
.
setPassword
(
password
)
self
.
tic
()
self
.
_clearCache
()
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'12345678-new'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'a'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'b'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'c'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'12345678-new'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'a'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'b'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'c'
))
# only last 3 (including current one are invalid)
self
.
assertSameSet
([
-
4
],
perso
n
.
analyzePassword
(
'd'
))
self
.
assertSameSet
([
-
4
],
perso
n
.
analyzePassword
(
'e'
))
self
.
assertSameSet
([
-
4
],
perso
n
.
analyzePassword
(
'f'
))
self
.
assertSameSet
([
-
4
],
logi
n
.
analyzePassword
(
'd'
))
self
.
assertSameSet
([
-
4
],
logi
n
.
analyzePassword
(
'e'
))
self
.
assertSameSet
([
-
4
],
logi
n
.
analyzePassword
(
'f'
))
# if we remove restricted then all password are usable
preference
.
setPreferredNumberOfLastPasswordToCheck
(
None
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'd'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'e'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'f'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'd'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'e'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'f'
))
# if we set only last password to check
preference
.
setPreferredNumberOfLastPasswordToCheck
(
1
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'c'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'd'
))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'e'
))
self
.
assertSameSet
([
-
4
],
perso
n
.
analyzePassword
(
'f'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'c'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'd'
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'e'
))
self
.
assertSameSet
([
-
4
],
logi
n
.
analyzePassword
(
'f'
))
preference
.
setPreferredRegularExpressionGroupList
(
regular_expression_list
)
preference
.
setPreferredMinPasswordLength
(
7
)
preference
.
setPreferredNumberOfLastPasswordToCheck
(
None
)
self
.
_cleanUp
Person
(
perso
n
)
self
.
_cleanUp
Login
(
logi
n
)
self
.
_clearCache
()
self
.
tic
()
...
...
@@ -370,47 +392,47 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
self
.
tic
()
for
password
in
four_group_password_list
:
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
password
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
password
))
for
password
in
three_group_password_list
+
two_group_password_list
+
one_group_password_list
:
self
.
assertSameSet
([
-
2
],
perso
n
.
analyzePassword
(
password
))
self
.
assertSameSet
([
-
2
],
logi
n
.
analyzePassword
(
password
))
# min 3 out of all groups
preference
.
setPreferredMinRegularExpressionGroupNumber
(
3
)
self
.
_clearCache
()
self
.
_cleanUp
Person
(
perso
n
)
self
.
_cleanUp
Login
(
logi
n
)
self
.
tic
()
for
password
in
four_group_password_list
+
three_group_password_list
:
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
password
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
password
))
for
password
in
two_group_password_list
+
one_group_password_list
:
self
.
assertSameSet
([
-
2
],
perso
n
.
analyzePassword
(
password
))
self
.
assertSameSet
([
-
2
],
logi
n
.
analyzePassword
(
password
))
# min 2 out of all groups
preference
.
setPreferredMinRegularExpressionGroupNumber
(
2
)
self
.
_clearCache
()
self
.
tic
()
for
password
in
four_group_password_list
+
three_group_password_list
+
two_group_password_list
:
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
password
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
password
))
for
password
in
one_group_password_list
:
self
.
assertSameSet
([
-
2
],
perso
n
.
analyzePassword
(
password
))
self
.
assertSameSet
([
-
2
],
logi
n
.
analyzePassword
(
password
))
# min 1 out of all groups
preference
.
setPreferredMinRegularExpressionGroupNumber
(
1
)
self
.
_clearCache
()
self
.
tic
()
for
password
in
four_group_password_list
+
three_group_password_list
+
two_group_password_list
+
one_group_password_list
:
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
password
))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
password
))
# not contain the full name of the user
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertSameSet
([
-
5
],
perso
n
.
analyzePassword
(
'abAB#12_%s'
%
person
.
getFirstName
()))
self
.
assertSameSet
([
-
5
],
perso
n
.
analyzePassword
(
'abAB#12_%s'
%
person
.
getLastName
()))
self
.
assertSameSet
([
-
5
],
logi
n
.
analyzePassword
(
'abAB#12_%s'
%
person
.
getFirstName
()))
self
.
assertSameSet
([
-
5
],
logi
n
.
analyzePassword
(
'abAB#12_%s'
%
person
.
getLastName
()))
preference
.
setPrefferedForceUsernameCheckInPassword
(
0
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'abAB#12_%s'
%
person
.
getFirstName
()))
self
.
assertTrue
(
perso
n
.
isPasswordValid
(
'abAB#12_%s'
%
person
.
getLastName
()))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'abAB#12_%s'
%
person
.
getFirstName
()))
self
.
assertTrue
(
logi
n
.
isPasswordValid
(
'abAB#12_%s'
%
person
.
getLastName
()))
# check on temp objects just passworrd length( i.e. simulating a new user account creation)
first_name
=
'John'
...
...
@@ -425,8 +447,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
self
.
tic
()
# in this case which is basically used in new account creation only length of password matters
self
.
assertSameSet
([
-
1
],
temp_person
.
Perso
n_analyzePassword
(
'onlyNine1'
))
self
.
assertSameSet
([],
temp_person
.
Perso
n_analyzePassword
(
'longEnough1'
))
self
.
assertSameSet
([
-
1
],
temp_person
.
Logi
n_analyzePassword
(
'onlyNine1'
))
self
.
assertSameSet
([],
temp_person
.
Logi
n_analyzePassword
(
'longEnough1'
))
# make sure re check works on temp as well ( i.e. min 3 out of all groups)
preference
.
setPreferredRegularExpressionGroupList
(
regular_expression_list
)
...
...
@@ -435,22 +457,22 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
self
.
tic
()
for
password
in
four_group_password_list
+
three_group_password_list
:
self
.
assertSameSet
([],
temp_person
.
Perso
n_analyzePassword
(
password
))
self
.
assertSameSet
([],
temp_person
.
Logi
n_analyzePassword
(
password
))
for
password
in
two_group_password_list
+
one_group_password_list
:
self
.
assertSameSet
([
-
2
],
temp_person
.
Perso
n_analyzePassword
(
password
))
self
.
assertSameSet
([
-
2
],
temp_person
.
Logi
n_analyzePassword
(
password
))
# make sure peron's check on username works on temp as well (i.e. not contain the full name of the user)
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertSameSet
([
-
5
],
temp_person
.
Perso
n_analyzePassword
(
'abAB#12_%s'
%
first_name
))
self
.
assertSameSet
([
-
5
],
temp_person
.
Perso
n_analyzePassword
(
'abAB#12_%s'
%
last_name
))
self
.
assertSameSet
([
-
5
],
temp_person
.
Logi
n_analyzePassword
(
'abAB#12_%s'
%
first_name
))
self
.
assertSameSet
([
-
5
],
temp_person
.
Logi
n_analyzePassword
(
'abAB#12_%s'
%
last_name
))
preference
.
setPrefferedForceUsernameCheckInPassword
(
0
)
self
.
_clearCache
()
self
.
tic
()
self
.
assertSameSet
([],
temp_person
.
Perso
n_analyzePassword
(
'abAB#12_%s'
%
first_name
))
self
.
assertSameSet
([],
temp_person
.
Perso
n_analyzePassword
(
'abAB#12_%s'
%
last_name
))
self
.
assertSameSet
([],
temp_person
.
Logi
n_analyzePassword
(
'abAB#12_%s'
%
first_name
))
self
.
assertSameSet
([],
temp_person
.
Logi
n_analyzePassword
(
'abAB#12_%s'
%
last_name
))
# check Base_isPasswordValid is able to work in Anonymous User fashion
# but with already create Person object (i.e. recover password case)
...
...
@@ -461,20 +483,20 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
self
.
tic
()
perso
n
.
setPassword
(
'used_ALREADY_1234'
)
logi
n
.
setPassword
(
'used_ALREADY_1234'
)
self
.
_clearCache
()
self
.
tic
()
# emulate Anonymous User
self
.
logout
()
request
.
set
(
'field_user_login'
,
perso
n
.
getReference
())
self
.
assertRaises
(
ValidationError
,
portal
.
Base
_isPasswordValid
,
'abAB#12_%s'
%
person
.
getFirstName
(),
request
)
# contains name
self
.
assertRaises
(
ValidationError
,
portal
.
Base
_isPasswordValid
,
'abAB#12_%s'
%
person
.
getLastName
(),
request
)
# contains name
self
.
assertRaises
(
ValidationError
,
portal
.
Base
_isPasswordValid
,
'abAB#1'
,
request
)
# too short
self
.
assertRaises
(
ValidationError
,
portal
.
Base
_isPasswordValid
,
'abABCDEFG'
,
request
)
# too few groups
self
.
assertRaises
(
ValidationError
,
portal
.
Base
_isPasswordValid
,
'used_ALREADY_1234'
,
request
)
# already used
self
.
assertEqual
(
1
,
portal
.
Base
_isPasswordValid
(
'abAB#12_'
,
request
))
self
.
assertEqual
(
1
,
portal
.
Base
_isPasswordValid
(
'not_used_ALREADY_1234'
,
request
))
request
.
set
(
'field_user_login'
,
logi
n
.
getReference
())
self
.
assertRaises
(
ValidationError
,
login
.
Login
_isPasswordValid
,
'abAB#12_%s'
%
person
.
getFirstName
(),
request
)
# contains name
self
.
assertRaises
(
ValidationError
,
login
.
Login
_isPasswordValid
,
'abAB#12_%s'
%
person
.
getLastName
(),
request
)
# contains name
self
.
assertRaises
(
ValidationError
,
login
.
Login
_isPasswordValid
,
'abAB#1'
,
request
)
# too short
self
.
assertRaises
(
ValidationError
,
login
.
Login
_isPasswordValid
,
'abABCDEFG'
,
request
)
# too few groups
self
.
assertRaises
(
ValidationError
,
login
.
Login
_isPasswordValid
,
'used_ALREADY_1234'
,
request
)
# already used
self
.
assertEqual
(
1
,
login
.
Login
_isPasswordValid
(
'abAB#12_'
,
request
))
self
.
assertEqual
(
1
,
login
.
Login
_isPasswordValid
(
'not_used_ALREADY_1234'
,
request
))
def
test_04_PasswordExpire
(
self
):
"""
...
...
@@ -485,16 +507,16 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
person
=
portal
.
person_module
.
newContent
(
portal_type
=
'Person
'
,
reference
=
'test-04'
,
password
=
'used_ALREADY_1234'
)
person
=
self
.
createUser
(
'test-04
'
,
password
=
'used_ALREADY_1234'
)
login
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)[
0
]
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
preference
.
setPreferredMaxPasswordLifetimeDuration
(
24
)
self
.
tic
()
self
.
_clearCache
()
self
.
assertFalse
(
perso
n
.
isPasswordExpired
())
self
.
assertFalse
(
logi
n
.
isPasswordExpired
())
self
.
assertFalse
(
request
[
'is_user_account_password_expired'
])
...
...
@@ -502,21 +524,21 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
preference
.
setPreferredMaxPasswordLifetimeDuration
(
4
*
24
)
# password expire in 4 days
self
.
tic
()
self
.
_clearCache
()
self
.
assertFalse
(
perso
n
.
isPasswordExpired
())
self
.
assertFalse
(
logi
n
.
isPasswordExpired
())
self
.
assertFalse
(
request
[
'is_user_account_password_expired'
])
# test early warning password expire notification is detected
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
4
*
24
)
# password expire notification appear immediately
self
.
tic
()
self
.
_clearCache
()
self
.
assertFalse
(
perso
n
.
isPasswordExpired
())
self
.
assertFalse
(
logi
n
.
isPasswordExpired
())
self
.
assertTrue
(
request
[
'is_user_account_password_expired_expire_date'
])
# test early warning password expire notification is detected
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
4
*
24
-
24
)
# password expire notification appear 3 days befor time
self
.
tic
()
self
.
_clearCache
()
self
.
assertFalse
(
perso
n
.
isPasswordExpired
())
self
.
assertFalse
(
logi
n
.
isPasswordExpired
())
self
.
assertFalse
(
request
[
'is_user_account_password_expired_expire_date'
])
def
test_05_HttpRequest
(
self
):
...
...
@@ -525,50 +547,52 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
"""
portal
=
self
.
getPortal
()
request
=
self
.
app
.
REQUEST
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
reference
=
'test'
)
person
=
self
.
createUser
(
'test-05'
)
assignment
=
person
.
newContent
(
portal_type
=
'Assignment'
)
assignment
.
open
()
login
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)[
0
]
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
perso
n
.
setPassword
(
'used_ALREADY_1234'
)
logi
n
.
setPassword
(
'used_ALREADY_1234'
)
self
.
tic
()
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'used_ALREADY_1234'
)
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test
-05
'
,
'used_ALREADY_1234'
)
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
'Welcome to ERP5'
in
response
.
getBody
())
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# fail request #1
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'bad_test'
)
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test
-05
'
,
'bad_test'
)
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form"
))
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# fail request #2
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form"
))
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# fail request #3
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form"
))
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
self
.
tic
()
# test message that account is blocked
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
path
=
portal
.
absolute_url_path
()
+
'/logged_in?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'used_ALREADY_1234'
)
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
path
=
portal
.
absolute_url_path
()
+
'/logged_in?__ac_name=%s&__ac_password=%s'
%
(
'test
-05
'
,
'used_ALREADY_1234'
)
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form?portal_status_message=Account is blocked."
))
# test expire password message, first unblock it
person
.
Perso
n_unblockLogin
()
login
.
Logi
n_unblockLogin
()
preference
.
setPreferredMaxPasswordLifetimeDuration
(
0
)
self
.
tic
()
self
.
_clearCache
()
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form?portal_status_message=Password is expired."
))
self
.
assertTrue
(
perso
n
.
isPasswordExpired
())
self
.
assertTrue
(
logi
n
.
isPasswordExpired
())
# test we're redirected to update password due to soon expire
preference
.
setPreferredMaxPasswordLifetimeDuration
(
24
)
...
...
@@ -584,7 +608,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
12
)
self
.
tic
()
self
.
_clearCache
()
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'used_ALREADY_1234'
)
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test
-05
'
,
'used_ALREADY_1234'
)
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
'Welcome to ERP5'
in
response
.
getBody
())
...
...
@@ -593,18 +617,18 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
Check that expiring old Authentication Event list works.
"""
portal
=
self
.
getPortal
()
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
reference
=
'test'
)
person
=
self
.
createUser
(
'test-06'
)
login
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)[
0
]
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
# file some failures so we should detect and block account
perso
n
.
notifyLoginFailure
()
perso
n
.
notifyLoginFailure
()
perso
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
logi
n
.
notifyLoginFailure
()
self
.
tic
()
# should be blocked
self
.
assertTrue
(
perso
n
.
isLoginBlocked
())
self
.
assertTrue
(
logi
n
.
isLoginBlocked
())
# set 0 check interval
preference
.
setPreferredAuthenticationFailureCheckDuration
(
0
)
...
...
@@ -612,14 +636,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
time
.
sleep
(
1
)
# we need to give a moment
self
.
assertFalse
(
perso
n
.
isLoginBlocked
())
self
.
assertFalse
(
logi
n
.
isLoginBlocked
())
# expire manually old
portal
.
system_event_module
.
SystemEventModule_expireAuthenticationEventList
()
self
.
tic
()
self
.
assertEqual
(
3
,
len
(
portal
.
portal_catalog
(
portal_type
=
"Authentication Event"
,
default_destination_uid
=
perso
n
.
getUid
(),
default_destination_uid
=
logi
n
.
getUid
(),
validation_state
=
"expired"
)))
...
...
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