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
Hugo Ricateau
erp5
Commits
7e9f03f3
Commit
7e9f03f3
authored
Aug 15, 2011
by
Ivan Tyagov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow UI to show all password validation error messages by extending
API. Adjust test accordingly.
parent
65610e6b
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
190 additions
and
99 deletions
+190
-99
product/ERP5/interfaces/login_account_provider.py
product/ERP5/interfaces/login_account_provider.py
+7
-0
product/ERP5/mixin/login_account_provider.py
product/ERP5/mixin/login_account_provider.py
+20
-7
product/ERP5/tests/testAuthenticationPolicy.py
product/ERP5/tests/testAuthenticationPolicy.py
+163
-92
No files found.
product/ERP5/interfaces/login_account_provider.py
View file @
7e9f03f3
...
@@ -60,6 +60,13 @@ class ILoginAccountProvider(Interface):
...
@@ -60,6 +60,13 @@ class ILoginAccountProvider(Interface):
Is password valid?
Is password valid?
"""
"""
def
analyzePassword
(
password
,
**
kw
):
"""
Analyze password validity.
Return status code indicating if password is acceptable and if not status code
for reason for not being a valid one (i.e. too short, not complex, etc ...)
"""
def
isPasswordAlreadyUsed
(
self
,
password
):
def
isPasswordAlreadyUsed
(
self
,
password
):
"""
"""
Return if password has already been used.
Return if password has already been used.
...
...
product/ERP5/mixin/login_account_provider.py
View file @
7e9f03f3
...
@@ -82,10 +82,19 @@ class LoginAccountProviderMixin:
...
@@ -82,10 +82,19 @@ class LoginAccountProviderMixin:
"""
"""
Is password valid?
Is password valid?
"""
"""
method
=
self
.
_getTypeBasedMethod
(
'isPasswordValid'
)
result_code_list
=
self
.
analyzePassword
(
password
,
**
kw
)
if
method
is
not
None
:
if
not
len
(
result_code_list
):
return
method
(
password
,
**
kw
)
return
True
return
True
return
False
def
analyzePassword
(
self
,
password
,
**
kw
):
"""
Analyze password validity.
Return status code indicating if password is acceptable and if not status code
for reason for not being a valid one (i.e. too short, not complex, etc ...)
"""
method
=
self
.
_getTypeBasedMethod
(
'analyzePassword'
)
return
method
(
password
,
**
kw
)
security
.
declareProtected
(
Permissions
.
SetOwnPassword
,
'isPasswordAlreadyUsed'
)
security
.
declareProtected
(
Permissions
.
SetOwnPassword
,
'isPasswordAlreadyUsed'
)
def
isPasswordAlreadyUsed
(
self
,
password
):
def
isPasswordAlreadyUsed
(
self
,
password
):
...
@@ -93,9 +102,13 @@ class LoginAccountProviderMixin:
...
@@ -93,9 +102,13 @@ class LoginAccountProviderMixin:
Return if password has already been used.
Return if password has already been used.
"""
"""
preferred_number_of_last_password_to_check
=
self
.
portal_preferences
.
getPreferredNumberOfLastPasswordToCheck
()
preferred_number_of_last_password_to_check
=
self
.
portal_preferences
.
getPreferredNumberOfLastPasswordToCheck
()
password_list
=
self
.
getLastChangedPasswordValueList
()
password_event_list
=
self
.
getPortalObject
().
portal_catalog
(
password_list
.
reverse
()
portal_type
=
"Password Event"
,
for
encoded_password
in
password_list
[:
preferred_number_of_last_password_to_check
]:
default_destination_uid
=
self
.
getUid
(),
sort_on
=
((
'creation_date'
,
'DESC'
,),),
limit
=
preferred_number_of_last_password_to_check
)
password_list
=
[
x
.
getPassword
()
for
x
in
password_event_list
]
for
encoded_password
in
password_list
:
if
pw_validate
(
encoded_password
,
password
):
if
pw_validate
(
encoded_password
,
password
):
return
True
return
True
return
False
return
False
product/ERP5/tests/testAuthenticationPolicy.py
View file @
7e9f03f3
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
import
unittest
import
unittest
import
time
import
time
import
transaction
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
from
Products.Formulator.Errors
import
ValidationError
from
Products.Formulator.Errors
import
ValidationError
...
@@ -55,6 +56,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -55,6 +56,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
'erp5_base'
,
'erp5_base'
,
'erp5_web'
,
'erp5_web'
,
'erp5_credential'
,
'erp5_credential'
,
'erp5_system_event'
,
'erp5_authentication_policy'
,)
'erp5_authentication_policy'
,)
def
afterSetUp
(
self
):
def
afterSetUp
(
self
):
...
@@ -90,10 +92,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -90,10 +92,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
for
cache_factory
in
[
x
for
x
in
self
.
portal
.
portal_caches
.
getCacheFactoryList
()
if
x
!=
"erp5_session_cache"
]:
for
cache_factory
in
[
x
for
x
in
self
.
portal
.
portal_caches
.
getCacheFactoryList
()
if
x
!=
"erp5_session_cache"
]:
self
.
portal
.
portal_caches
.
clearCacheFactory
(
cache_factory
)
self
.
portal
.
portal_caches
.
clearCacheFactory
(
cache_factory
)
def
_getPasswordEventList
(
self
,
person
):
return
[
x
.
getObject
()
for
x
in
self
.
portal
.
portal_catalog
(
portal_type
=
'Password Event'
,
default_destination_uid
=
person
.
getUid
(),
sort_on
=
((
'creation_date'
,
'DESC'
,),))]
def
_cleanUpPerson
(
self
,
person
):
def
_cleanUpPerson
(
self
,
person
):
# remove all traces from password changes
self
.
portal
.
system_event_module
.
manage_delObjects
([
x
.
getId
()
for
x
in
self
.
_getPasswordEventList
(
person
)])
person
.
setLastPasswordModificationDate
(
None
)
person
.
setLastChangedPasswordValueList
([])
def
test_01_BlockLogin
(
self
):
def
test_01_BlockLogin
(
self
):
...
@@ -108,24 +114,22 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -108,24 +114,22 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
title
=
'Authentication'
,)
# login should be allowed
# login should be allowed
self
.
assertEqual
(
1
,
len
(
person
.
notifyLoginFailure
()))
# just to init structure
self
.
assertFalse
(
person
.
isLoginBlocked
())
self
.
assertFalse
(
person
.
isLoginBlocked
())
# file two more failures so we should detect and block account
# file some failures so we should detect and block account
self
.
assertEqual
(
2
,
len
(
person
.
notifyLoginFailure
()))
person
.
notifyLoginFailure
()
self
.
assertEqual
(
3
,
len
(
person
.
notifyLoginFailure
()))
person
.
notifyLoginFailure
()
person
.
notifyLoginFailure
()
# we do not need to store more than max allowed failures so check it here
self
.
stepTic
()
# this way a bot can not brute force us by filling up session storage backend
for
i
in
range
(
0
,
1000
):
self
.
assertEqual
(
3
,
len
(
person
.
notifyLoginFailure
()))
# should be blocked
self
.
assertTrue
(
person
.
isLoginBlocked
())
self
.
assertTrue
(
person
.
isLoginBlocked
())
# set check back interval to actualy disable blocking
# set check back interval to actualy disable blocking
preference
.
setPreferredAuthenticationFailureCheckDuration
(
0
)
preference
.
setPreferredAuthenticationFailureCheckDuration
(
0
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
time
.
sleep
(
1
)
# we need to give a moment
self
.
assertFalse
(
person
.
isLoginBlocked
())
self
.
assertFalse
(
person
.
isLoginBlocked
())
# .. and revert it back
# .. and revert it back
...
@@ -153,6 +157,29 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -153,6 +157,29 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
time
.
sleep
(
4
)
time
.
sleep
(
4
)
self
.
assertFalse
(
person
.
isLoginBlocked
())
self
.
assertFalse
(
person
.
isLoginBlocked
())
# test multiple concurrent transactions without waiting for activities to be over
preference
.
setPreferredAuthenticationFailureCheckDuration
(
600
)
preference
.
setPreferredAuthenticationFailureBlockDuration
(
600
)
preference
.
setPreferredMaxAuthenticationFailure
(
3
)
person
.
Person_unblockLogin
()
self
.
_clearCache
()
self
.
stepTic
()
person
.
notifyLoginFailure
()
person
.
notifyLoginFailure
()
person
.
notifyLoginFailure
()
transaction
.
commit
()
self
.
assertTrue
(
person
.
isLoginBlocked
())
self
.
stepTic
()
self
.
assertTrue
(
person
.
isLoginBlocked
())
# test unblock account
person
.
Person_unblockLogin
()
self
.
stepTic
()
self
.
assertFalse
(
person
.
isLoginBlocked
())
def
test_02_PasswordHistory
(
self
):
def
test_02_PasswordHistory
(
self
):
"""
"""
Test password history.
Test password history.
...
@@ -160,70 +187,61 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -160,70 +187,61 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
portal
=
self
.
getPortal
()
portal
=
self
.
getPortal
()
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
person
=
portal
.
p
ortal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
person
=
portal
.
p
erson_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'test'
)
reference
=
'test-02'
)
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
title
=
'Authentication'
,)
self
.
stepTic
()
# Check that last (X where X is set in preferences) passwords are saved.
# Check that last (X where X is set in preferences) passwords are saved.
self
.
assertEqual
(
None
,
person
.
getLastPasswordModificationDate
())
self
.
assertEqual
([],
self
.
_getPasswordEventList
(
person
))
self
.
assertEqual
([],
person
.
getLastChangedPasswordValueList
())
preference
.
setPreferredNumberOfLastPasswordToCheck
(
10
)
preference
.
setPreferredNumberOfLastPasswordToCheck
(
10
)
self
.
stepTic
()
self
.
stepTic
()
self
.
_clearCache
()
self
.
_clearCache
()
before
=
DateTime
()
person
.
setPassword
(
'12345678'
)
person
.
setPassword
(
'12345678'
)
self
.
stepTic
()
self
.
stepTic
()
# password change date should be saved as well hashed old password value
# password change date should be saved as well hashed old password value
old_password
=
person
.
getPassword
()
old_password
=
person
.
getPassword
()
self
.
assertTrue
(
person
.
getLastPasswordModificationDate
()
>
before
)
self
.
assertSameSet
([
old_password
],
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
person
)])
self
.
assertEqual
([
old_password
],
person
.
getLastChangedPasswordValueList
())
# .. test one more time to check history of password is saved in a list
# .. test one more time to check history of password is saved in a list
before
=
DateTime
()
person
.
setPassword
(
'123456789'
)
person
.
setPassword
(
'123456789'
)
self
.
stepTic
()
self
.
stepTic
()
old_password1
=
person
.
getPassword
()
old_password1
=
person
.
getPassword
()
# password change date should be saved as well hashed old password value
# password change date should be saved as well hashed old password value
self
.
assertTrue
(
person
.
getLastPasswordModificationDate
()
>
before
)
self
.
assertSameSet
([
old_password1
,
old_password
],
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
person
)])
self
.
assertEqual
([
old_password
,
old_password1
],
person
.
getLastChangedPasswordValueList
())
# other methods (_setPassword)...
# other methods (_setPassword)...
before
=
DateTime
()
person
.
_setPassword
(
'123456789-1'
)
person
.
_setPassword
(
'123456789-1'
)
self
.
stepTic
()
self
.
stepTic
()
old_password2
=
person
.
getPassword
()
old_password2
=
person
.
getPassword
()
self
.
assert
True
(
person
.
getLastPasswordModificationDate
()
>
before
)
self
.
assert
SameSet
([
old_password2
,
old_password1
,
old_password
],
\
self
.
assertEqual
([
old_password
,
old_password1
,
old_password2
],
person
.
getLastChangedPasswordValueList
()
)
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
person
)]
)
# other methods (_forceSetPassword)...
# other methods (_forceSetPassword)...
before
=
DateTime
()
person
.
_forceSetPassword
(
'123456789-2'
)
person
.
_forceSetPassword
(
'123456789-2'
)
self
.
stepTic
()
self
.
stepTic
()
old_password3
=
person
.
getPassword
()
old_password3
=
person
.
getPassword
()
self
.
assertTrue
(
person
.
getLastPasswordModificationDate
()
>
before
)
self
.
assertSameSet
([
old_password3
,
old_password2
,
old_password1
,
old_password
],
\
self
.
assertEqual
([
old_password
,
old_password1
,
old_password2
,
old_password3
],
person
.
getLastChangedPasswordValueList
())
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
person
)])
# other methods (setEncodedPassword)...
# other methods (setEncodedPassword)...
before
=
DateTime
()
person
.
setEncodedPassword
(
'123456789-3'
)
person
.
setEncodedPassword
(
'123456789-3'
)
self
.
stepTic
()
self
.
stepTic
()
old_password4
=
person
.
getPassword
()
old_password4
=
person
.
getPassword
()
self
.
assertTrue
(
person
.
getLastPasswordModificationDate
()
>
before
)
self
.
assertSameSet
([
old_password4
,
old_password3
,
old_password2
,
old_password1
,
old_password
],
\
self
.
assertEqual
([
old_password
,
old_password1
,
old_password2
,
old_password3
,
old_password4
],
\
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
person
)])
person
.
getLastChangedPasswordValueList
())
# other methods (edit)...
# other methods (edit)...
before
=
DateTime
()
person
.
edit
(
password
=
'123456789-4'
)
person
.
edit
(
password
=
'123456789-4'
)
self
.
stepTic
()
self
.
stepTic
()
old_password5
=
person
.
getPassword
()
old_password5
=
person
.
getPassword
()
self
.
assertTrue
(
person
.
getLastPasswordModificationDate
()
>
before
)
self
.
assertSameSet
([
old_password5
,
old_password4
,
old_password3
,
old_password2
,
old_password1
,
old_password
],
\
self
.
assertEqual
([
old_password
,
old_password1
,
old_password2
,
old_password3
,
old_password4
,
old_password5
],
\
[
x
.
getPassword
()
for
x
in
self
.
_getPasswordEventList
(
person
)])
person
.
getLastChangedPasswordValueList
())
def
test_03_PasswordValidity
(
self
):
def
test_03_PasswordValidity
(
self
):
...
@@ -241,10 +259,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -241,10 +259,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
person
=
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'test'
)
reference
=
'test-03'
,
password
=
'test'
,
first_name
=
'First'
,
last_name
=
'Last'
)
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
title
=
'Authentication'
,)
self
.
stepTic
()
# by default an empty password if nothing set in preferences is OK
# by default an empty password if nothing set in preferences is OK
self
.
assertTrue
(
person
.
isPasswordValid
(
''
))
self
.
assertTrue
(
person
.
isPasswordValid
(
''
))
...
@@ -256,8 +278,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -256,8 +278,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
stepTic
()
self
.
stepTic
()
self
.
_clearCache
()
self
.
_clearCache
()
self
.
assertEqual
(
-
1
,
person
.
isPasswordVali
d
(
''
))
self
.
assertEqual
(
[
-
1
],
person
.
analyzePasswor
d
(
''
))
self
.
assertEqual
(
-
1
,
person
.
isPasswordVali
d
(
'1234567'
))
self
.
assertEqual
(
[
-
1
],
person
.
analyzePasswor
d
(
'1234567'
))
self
.
assertTrue
(
person
.
isPasswordValid
(
'12345678'
))
self
.
assertTrue
(
person
.
isPasswordValid
(
'12345678'
))
# not changed in last x days
# not changed in last x days
...
@@ -267,12 +289,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -267,12 +289,14 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
stepTic
()
self
.
stepTic
()
self
.
_clearCache
()
self
.
_clearCache
()
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'12345678'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'12345678'
))
person
.
setPassword
(
'12345678'
)
person
.
setPassword
(
'12345678'
)
self
.
stepTic
()
self
.
stepTic
()
# if we try to change now we should fail with any password
# if we try to change now we should fail with any password
self
.
assertEqual
(
-
3
,
person
.
isPasswordValid
(
'87654321'
))
self
.
assertSameSet
([
-
3
],
person
.
analyzePassword
(
'87654321'
))
self
.
assertSameSet
([
-
1
,
-
3
],
person
.
analyzePassword
(
'short'
))
# multiple failures
self
.
assertFalse
(
person
.
isPasswordValid
(
'short'
))
# multiple failures
self
.
assertRaises
(
ValueError
,
person
.
setPassword
,
'87654321'
)
self
.
assertRaises
(
ValueError
,
person
.
setPassword
,
'87654321'
)
preference
.
setPreferredMinPasswordLifetimeDuration
(
0
)
# remove restriction
preference
.
setPreferredMinPasswordLifetimeDuration
(
0
)
# remove restriction
...
@@ -289,38 +313,38 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -289,38 +313,38 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
person
.
setPassword
(
'12345678-new'
)
person
.
setPassword
(
'12345678-new'
)
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
Equal
(
-
4
,
person
.
isPasswordVali
d
(
'12345678-new'
))
# if we try to change now we should fail with this EXACT password
self
.
assert
SameSet
([
-
4
],
person
.
analyzePasswor
d
(
'12345678-new'
))
# if we try to change now we should fail with this EXACT password
self
.
assertRaises
(
ValueError
,
person
.
setPassword
,
'12345678-new'
)
self
.
assertRaises
(
ValueError
,
person
.
setPassword
,
'12345678-new'
)
self
.
assertTrue
(
person
.
isPasswordValid
(
'12345678_'
))
# it's OK with another one not used yet
self
.
assertTrue
(
person
.
isPasswordValid
(
'12345678_'
))
# it's OK with another one not used yet
for
password
in
[
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
]:
for
password
in
[
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
]:
person
.
setPassword
(
password
)
person
.
setPassword
(
password
)
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'12345678-new'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'12345678-new'
))
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'a'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'a'
))
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'b'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'b'
))
# only last 3 (including current one are invalid)
# only last 3 (including current one are invalid)
self
.
assert
Equal
(
-
4
,
person
.
isPasswordVali
d
(
'd'
))
self
.
assert
SameSet
([
-
4
],
person
.
analyzePasswor
d
(
'd'
))
self
.
assert
Equal
(
-
4
,
person
.
isPasswordVali
d
(
'e'
))
self
.
assert
SameSet
([
-
4
],
person
.
analyzePasswor
d
(
'e'
))
self
.
assert
Equal
(
-
4
,
person
.
isPasswordVali
d
(
'f'
))
self
.
assert
SameSet
([
-
4
],
person
.
analyzePasswor
d
(
'f'
))
# if we remove restricted then all password are usable
# if we remove restricted then all password are usable
preference
.
setPreferredNumberOfLastPasswordToCheck
(
None
)
preference
.
setPreferredNumberOfLastPasswordToCheck
(
None
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'd'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'd'
))
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'e'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'e'
))
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'f'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'f'
))
# if we set only last password to check
# if we set only last password to check
preference
.
setPreferredNumberOfLastPasswordToCheck
(
1
)
preference
.
setPreferredNumberOfLastPasswordToCheck
(
1
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'c'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'c'
))
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'd'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'd'
))
self
.
assert
Equal
(
1
,
person
.
isPasswordValid
(
'e'
))
self
.
assert
True
(
person
.
isPasswordValid
(
'e'
))
self
.
assert
Equal
(
-
4
,
person
.
isPasswordVali
d
(
'f'
))
self
.
assert
SameSet
([
-
4
],
person
.
analyzePasswor
d
(
'f'
))
preference
.
setPreferredRegularExpressionGroupList
(
regular_expression_list
)
preference
.
setPreferredRegularExpressionGroupList
(
regular_expression_list
)
preference
.
setPreferredMinPasswordLength
(
7
)
preference
.
setPreferredMinPasswordLength
(
7
)
...
@@ -341,7 +365,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -341,7 +365,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
for
password
in
four_group_password_list
:
for
password
in
four_group_password_list
:
self
.
assertTrue
(
person
.
isPasswordValid
(
password
))
self
.
assertTrue
(
person
.
isPasswordValid
(
password
))
for
password
in
three_group_password_list
+
two_group_password_list
+
one_group_password_list
:
for
password
in
three_group_password_list
+
two_group_password_list
+
one_group_password_list
:
self
.
assert
Equal
(
-
2
,
person
.
isPasswordVali
d
(
password
))
self
.
assert
SameSet
([
-
2
],
person
.
analyzePasswor
d
(
password
))
# min 3 out of all groups
# min 3 out of all groups
preference
.
setPreferredMinRegularExpressionGroupNumber
(
3
)
preference
.
setPreferredMinRegularExpressionGroupNumber
(
3
)
...
@@ -351,7 +375,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -351,7 +375,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
for
password
in
four_group_password_list
+
three_group_password_list
:
for
password
in
four_group_password_list
+
three_group_password_list
:
self
.
assertTrue
(
person
.
isPasswordValid
(
password
))
self
.
assertTrue
(
person
.
isPasswordValid
(
password
))
for
password
in
two_group_password_list
+
one_group_password_list
:
for
password
in
two_group_password_list
+
one_group_password_list
:
self
.
assert
Equal
(
-
2
,
person
.
isPasswordVali
d
(
password
))
self
.
assert
SameSet
([
-
2
],
person
.
analyzePasswor
d
(
password
))
# min 2 out of all groups
# min 2 out of all groups
preference
.
setPreferredMinRegularExpressionGroupNumber
(
2
)
preference
.
setPreferredMinRegularExpressionGroupNumber
(
2
)
...
@@ -360,7 +384,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -360,7 +384,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
for
password
in
four_group_password_list
+
three_group_password_list
+
two_group_password_list
:
for
password
in
four_group_password_list
+
three_group_password_list
+
two_group_password_list
:
self
.
assertTrue
(
person
.
isPasswordValid
(
password
))
self
.
assertTrue
(
person
.
isPasswordValid
(
password
))
for
password
in
one_group_password_list
:
for
password
in
one_group_password_list
:
self
.
assert
Equal
(
-
2
,
person
.
isPasswordVali
d
(
password
))
self
.
assert
SameSet
([
-
2
],
person
.
analyzePasswor
d
(
password
))
# min 1 out of all groups
# min 1 out of all groups
preference
.
setPreferredMinRegularExpressionGroupNumber
(
1
)
preference
.
setPreferredMinRegularExpressionGroupNumber
(
1
)
...
@@ -373,8 +397,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -373,8 +397,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
Equal
(
-
5
,
person
.
isPasswordVali
d
(
'abAB#12_%s'
%
person
.
getFirstName
()))
self
.
assert
SameSet
([
-
5
],
person
.
analyzePasswor
d
(
'abAB#12_%s'
%
person
.
getFirstName
()))
self
.
assert
Equal
(
-
5
,
person
.
isPasswordVali
d
(
'abAB#12_%s'
%
person
.
getLastName
()))
self
.
assert
SameSet
([
-
5
],
person
.
analyzePasswor
d
(
'abAB#12_%s'
%
person
.
getLastName
()))
preference
.
setPrefferedForceUsernameCheckInPassword
(
0
)
preference
.
setPrefferedForceUsernameCheckInPassword
(
0
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
...
@@ -394,8 +418,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -394,8 +418,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
# in this case which is basically used in new account creation only length of password matters
# in this case which is basically used in new account creation only length of password matters
self
.
assert
Equal
(
-
1
,
temp_person
.
Person_isPasswordVali
d
(
'onlyNine1'
))
self
.
assert
SameSet
([
-
1
],
temp_person
.
Person_analyzePasswor
d
(
'onlyNine1'
))
self
.
assert
True
(
temp_person
.
Person_isPasswordVali
d
(
'longEnough1'
))
self
.
assert
SameSet
([],
temp_person
.
Person_analyzePasswor
d
(
'longEnough1'
))
# make sure re check works on temp as well ( i.e. min 3 out of all groups)
# make sure re check works on temp as well ( i.e. min 3 out of all groups)
preference
.
setPreferredRegularExpressionGroupList
(
regular_expression_list
)
preference
.
setPreferredRegularExpressionGroupList
(
regular_expression_list
)
...
@@ -404,22 +428,22 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -404,22 +428,22 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
for
password
in
four_group_password_list
+
three_group_password_list
:
for
password
in
four_group_password_list
+
three_group_password_list
:
self
.
assert
True
(
temp_person
.
Person_isPasswordVali
d
(
password
))
self
.
assert
SameSet
([],
temp_person
.
Person_analyzePasswor
d
(
password
))
for
password
in
two_group_password_list
+
one_group_password_list
:
for
password
in
two_group_password_list
+
one_group_password_list
:
self
.
assert
Equal
(
-
2
,
temp_person
.
Person_isPasswordVali
d
(
password
))
self
.
assert
SameSet
([
-
2
],
temp_person
.
Person_analyzePasswor
d
(
password
))
# make sure peron's check on username works on temp as well (i.e. not contain the full name of the user)
# 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
)
preference
.
setPrefferedForceUsernameCheckInPassword
(
1
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
Equal
(
-
5
,
temp_person
.
Person_isPasswordVali
d
(
'abAB#12_%s'
%
first_name
))
self
.
assert
SameSet
([
-
5
],
temp_person
.
Person_analyzePasswor
d
(
'abAB#12_%s'
%
first_name
))
self
.
assert
Equal
(
-
5
,
temp_person
.
Person_isPasswordVali
d
(
'abAB#12_%s'
%
last_name
))
self
.
assert
SameSet
([
-
5
],
temp_person
.
Person_analyzePasswor
d
(
'abAB#12_%s'
%
last_name
))
preference
.
setPrefferedForceUsernameCheckInPassword
(
0
)
preference
.
setPrefferedForceUsernameCheckInPassword
(
0
)
self
.
_clearCache
()
self
.
_clearCache
()
self
.
stepTic
()
self
.
stepTic
()
self
.
assert
True
(
temp_person
.
Person_isPasswordVali
d
(
'abAB#12_%s'
%
first_name
))
self
.
assert
SameSet
([],
temp_person
.
Person_analyzePasswor
d
(
'abAB#12_%s'
%
first_name
))
self
.
assert
True
(
temp_person
.
Person_isPasswordVali
d
(
'abAB#12_%s'
%
last_name
))
self
.
assert
SameSet
([],
temp_person
.
Person_analyzePasswor
d
(
'abAB#12_%s'
%
last_name
))
# check Base_isPasswordValid is able to work in Anonymous User fashion
# check Base_isPasswordValid is able to work in Anonymous User fashion
# but with already create Person object (i.e. recover password case)
# but with already create Person object (i.e. recover password case)
...
@@ -454,8 +478,9 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -454,8 +478,9 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
self
.
assertTrue
(
portal
.
portal_preferences
.
isAuthenticationPolicyEnabled
())
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
person
=
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
reference
=
'test'
)
reference
=
'test-04'
,
password
=
'used_ALREADY_1234'
)
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
title
=
'Authentication'
,)
title
=
'Authentication'
,)
...
@@ -465,16 +490,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -465,16 +490,8 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
assertFalse
(
person
.
isPasswordExpired
())
self
.
assertFalse
(
person
.
isPasswordExpired
())
self
.
assertFalse
(
request
[
'is_user_account_password_expired'
])
self
.
assertFalse
(
request
[
'is_user_account_password_expired'
])
# set older last password modification date just for test
now
=
DateTime
()
person
.
setLastPasswordModificationDate
(
now
-
2
)
self
.
stepTic
()
self
.
_clearCache
()
self
.
assertTrue
(
person
.
isPasswordExpired
())
self
.
assertTrue
(
request
[
'is_user_account_password_expired'
])
# set longer password validity interval
# set longer password validity interval
person
.
setLastPasswordModificationDate
(
now
)
preference
.
setPreferredMaxPasswordLifetimeDuration
(
4
*
24
)
# password expire in 4 days
preference
.
setPreferredMaxPasswordLifetimeDuration
(
4
*
24
)
# password expire in 4 days
self
.
stepTic
()
self
.
stepTic
()
self
.
_clearCache
()
self
.
_clearCache
()
...
@@ -486,17 +503,16 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -486,17 +503,16 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self
.
stepTic
()
self
.
stepTic
()
self
.
_clearCache
()
self
.
_clearCache
()
self
.
assertFalse
(
person
.
isPasswordExpired
())
self
.
assertFalse
(
person
.
isPasswordExpired
())
self
.
assertTrue
(
request
[
'is_user_account_password_expired_
warning_on
'
])
self
.
assertTrue
(
request
[
'is_user_account_password_expired_
expire_date
'
])
# test early warning password expire notification is detected
# test early warning password expire notification is detected
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
4
*
24
-
24
)
# password expire notification appear 3 days befor time
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
4
*
24
-
24
)
# password expire notification appear 3 days befor time
self
.
stepTic
()
self
.
stepTic
()
self
.
_clearCache
()
self
.
_clearCache
()
self
.
assertFalse
(
person
.
isPasswordExpired
())
self
.
assertFalse
(
person
.
isPasswordExpired
())
#import pdb; pdb.set_trace()
self
.
assertFalse
(
request
[
'is_user_account_password_expired_expire_date'
])
self
.
assertFalse
(
request
[
'is_user_account_password_expired_warning_on'
])
def
test_05_HttpRe
sponse
(
self
):
def
test_05_HttpRe
quest
(
self
):
"""
"""
Check HTTP responses
Check HTTP responses
"""
"""
...
@@ -504,11 +520,66 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
...
@@ -504,11 +520,66 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
request
=
self
.
app
.
REQUEST
request
=
self
.
app
.
REQUEST
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Person'
,
reference
=
'test'
)
reference
=
'test'
)
# XXX: finish
preference
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'System Preference'
,
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'test'
)
title
=
'Authentication'
,)
person
.
setPassword
(
'used_ALREADY_1234'
)
self
.
stepTic
()
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'used_ALREADY_1234'
)
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
'Welcome to ERP5'
in
response
.
getBody
())
self
.
assertFalse
(
person
.
isLoginBlocked
())
# fail request #1
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'bad_test'
)
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form"
))
self
.
assertFalse
(
person
.
isLoginBlocked
())
# fail request #2
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form"
))
self
.
assertFalse
(
person
.
isLoginBlocked
())
# fail request #3
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form"
))
self
.
assertTrue
(
person
.
isLoginBlocked
())
self
.
stepTic
()
# test message that account is blocked
self
.
assertTrue
(
person
.
isLoginBlocked
())
path
=
portal
.
absolute_url_path
()
+
'/logged_in?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'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
.
Person_unblockLogin
()
preference
.
setPreferredMaxPasswordLifetimeDuration
(
0
)
self
.
stepTic
()
self
.
_clearCache
()
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
response
.
getHeader
(
"Location"
).
endswith
(
"login_form?portal_status_message=Password is expired."
))
self
.
assertTrue
(
person
.
isPasswordExpired
())
# test we're redirected to update password due to soon expire
preference
.
setPreferredMaxPasswordLifetimeDuration
(
24
)
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
24
)
self
.
stepTic
()
self
.
_clearCache
()
response
=
self
.
publish
(
path
)
self
.
assertTrue
(
'Your password will expire'
in
response
.
getHeader
(
"Location"
))
self
.
assertTrue
(
'You are advised to change it as soon as possible'
in
response
.
getHeader
(
"Location"
))
# test proper login
preference
.
setPreferredPasswordLifetimeExpireWarningDuration
(
12
)
self
.
stepTic
()
self
.
_clearCache
()
path
=
portal
.
absolute_url_path
()
+
'/view?__ac_name=%s&__ac_password=%s'
%
(
'test'
,
'used_ALREADY_1234'
)
response
=
self
.
publish
(
path
)
response
=
self
.
publish
(
path
)
print
path
self
.
assertTrue
(
'Welcome to ERP5'
in
response
.
getBody
())
print
response
def
test_suite
():
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
=
unittest
.
TestSuite
()
...
...
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