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
c194772a
Commit
c194772a
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_credential: migrate to ERP5 Login authentication.
parent
cd9feb3c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
125 additions
and
52 deletions
+125
-52
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/CredentialRecovery_sendPasswordResetLink.py
...p5_credential/CredentialRecovery_sendPasswordResetLink.py
+1
-1
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/CredentialRecovery_sendUsernameRecoveryMessage.py
...dential/CredentialRecovery_sendUsernameRecoveryMessage.py
+5
-4
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/CredentialRequest_createUser.py
...tal_skins/erp5_credential/CredentialRequest_createUser.py
+23
-12
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/Credential_updatePersonPassword.py
..._skins/erp5_credential/Credential_updatePersonPassword.py
+26
-1
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/ERP5Site_newCredentialRecovery.py
...l_skins/erp5_credential/ERP5Site_newCredentialRecovery.py
+11
-9
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/ERP5Site_newCredentialRequest.py
...al_skins/erp5_credential/ERP5Site_newCredentialRequest.py
+2
-1
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/ERP5Site_newPersonCredentialUpdate.py
...ins/erp5_credential/ERP5Site_newPersonCredentialUpdate.py
+9
-3
product/ERP5/tests/testERP5Credential.py
product/ERP5/tests/testERP5Credential.py
+48
-21
No files found.
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/CredentialRecovery_sendPasswordResetLink.py
View file @
c194772a
...
...
@@ -4,7 +4,7 @@ send the password reset link by mail
portal
=
context
.
getPortalObject
()
person
=
context
.
getDestinationDecisionValue
(
portal_type
=
"Person"
)
reference
=
person
.
getReference
()
reference
=
context
.
getReference
()
if
context
.
hasDocumentReference
():
message_reference
=
context
.
getDocumentReference
()
else
:
...
...
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/CredentialRecovery_sendUsernameRecoveryMessage.py
View file @
c194772a
...
...
@@ -4,13 +4,14 @@ send the username mail
portal
=
context
.
getPortalObject
()
person_list
=
context
.
getDestinationDecisionValueList
(
portal_type
=
"Person"
)
usernames
=
[]
login_list
=
[]
for
person
in
person_list
:
usernames
.
append
(
"%s"
%
person
.
getReference
())
for
login
in
person
.
objectValues
(
portal_type
=
'ERP5 Login'
):
if
login
.
getValidationState
()
==
'validated'
:
login_list
.
append
(
login
)
usernames
=
" "
.
join
(
usernames
)
usernames
=
' '
.
join
(
login
.
getReference
()
for
login
in
login_list
)
reference_list
=
[
x
.
getReference
()
for
x
in
person_list
]
if
context
.
hasDocumentReference
():
message_reference
=
context
.
getDocumentReference
()
else
:
...
...
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/CredentialRequest_createUser.py
View file @
c194772a
...
...
@@ -12,27 +12,35 @@ portal = context.getPortalObject()
portal_preferences
=
context
.
portal_preferences
person
=
context
.
getDestinationDecisionValue
(
portal_type
=
"Person"
)
login_list
=
[
x
for
x
in
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)
\
if
x
.
getValidationState
()
==
'validated'
]
if
len
(
login_list
):
login
=
login_list
[
0
]
else
:
login
=
person
.
newContent
(
portal_type
=
'ERP5 Login'
)
# Create user of the person only if not exist
user_id
=
person
.
Person_getUserId
()
if
user_id
and
perso
n
.
hasPassword
():
if
user_id
and
logi
n
.
hasPassword
():
return
user_id
,
None
# Set login
login
=
context
.
getReference
()
if
not
perso
n
.
hasReference
():
if
not
login
:
reference
=
context
.
getReference
()
if
not
logi
n
.
hasReference
():
if
not
reference
:
raise
ValueError
,
"Impossible to create an account without login"
person
.
setReference
(
login
)
login
.
setReference
(
reference
)
if
not
person
.
hasReference
():
person
.
setReference
(
reference
)
else
:
login
=
person
.
getReference
()
reference
=
person
.
getReference
()
password
=
None
# Set password if no password on the
perso
n
if
not
person
.
get
Password
():
# Set password if no password on the
Logi
n
if
not
login
.
has
Password
():
if
context
.
getPassword
():
#User has fill a password
password
=
context
.
getPassword
()
perso
n
.
setEncodedPassword
(
password
)
logi
n
.
setEncodedPassword
(
password
)
else
:
if
not
portal_preferences
.
isPreferredSystemGeneratePassword
():
# user will set it trough a credential recovery process
...
...
@@ -40,24 +48,27 @@ if not person.getPassword():
module
=
portal
.
getDefaultModule
(
portal_type
=
'Credential Recovery'
)
credential_recovery
=
module
.
newContent
(
portal_type
=
"Credential Recovery"
,
reference
=
login
,
reference
=
reference
,
destination_decision
=
person
.
getRelativeUrl
(),
language
=
portal
.
Localizer
.
get_selected_language
())
credential_recovery
.
submit
()
else
:
# system should generate a password
password
=
context
.
Person_generatePassword
(
alpha
=
5
,
numeric
=
3
)
perso
n
.
setPassword
(
password
)
logi
n
.
setPassword
(
password
)
# create a global account
if
context
.
ERP5Site_isSingleSignOnEnable
():
#The master manage encoded password and clear password
person
.
Person_createNewGlobalUserAccount
(
password
=
password
)
person
.
Person_validateGlobalUserAccount
()
if
login
.
getValidationState
()
==
'draft'
:
login
.
validate
()
else
:
#Person has an already an account
if
context
.
ERP5Site_isSingleSignOnEnable
():
#Check assignment for the current instance
person
.
Person_validateGlobalUserAccount
()
return
login
,
password
return
reference
,
password
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/Credential_updatePersonPassword.py
View file @
c194772a
...
...
@@ -4,5 +4,30 @@ Clear 'erp5_content_short' cache too."""
person
=
context
.
getDestinationDecisionValue
(
portal_type
=
"Person"
)
if
context
.
getPassword
():
person
.
setEncodedPassword
(
context
.
getPassword
())
login_list
=
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)
if
login_list
:
reference
=
context
.
getReference
()
login_list
=
[
login
for
login
in
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)
\
if
login
.
getValidationState
()
==
'validated'
]
if
reference
:
for
login
in
login_list
:
if
login
.
getReference
()
==
reference
:
break
else
:
raise
RuntimeError
,
'Person %s does not have a validated Login with reference %r'
%
\
(
person
.
getRelativeUrl
(),
reference
)
else
:
# BBB when login reference is not set in Credential Update document.
if
login_list
:
user_id
=
person
.
Person_getUserId
()
login
=
sorted
(
login_list
,
key
=
lambda
x
:
x
.
getReference
()
==
user_id
,
reverse
=
True
)[
0
]
else
:
raise
RuntimeError
,
'Person %s does not have a validated Login with reference %r'
%
\
(
person
.
getRelativeUrl
(),
reference
)
else
:
# BBB
login
=
person
login
.
setEncodedPassword
(
context
.
getPassword
())
context
.
portal_caches
.
clearCache
((
'erp5_content_short'
,))
return
login
.
getReference
()
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/ERP5Site_newCredentialRecovery.py
View file @
c194772a
...
...
@@ -40,18 +40,20 @@ if default_email_text is not None:
else
:
# Case for recovery of password
if
person_list
is
None
:
person_module
=
portal
.
getDefaultModule
(
'Person'
)
result
=
person_module
.
searchFolder
(
reference
=
{
'query'
:
reference
,
'key'
:
'ExactMatch'
})
if
len
(
result
)
!=
1
:
user_list
=
context
.
acl_users
.
searchUsers
(
login
=
reference
,
login_portal_type
=
'ERP5 Login'
,
exact_match
=
True
,
)
if
len
(
user_list
)
!=
1
:
portal_status_message
=
portal
.
Base_translateString
(
"Can't find corresponding person, it's not possible to recover your credentials."
)
if
web_site
is
not
None
:
return
web_site
.
Base_redirect
(
''
,
keep_items
=
dict
(
portal_status_message
=
portal_status_message
))
return
portal
.
Base_redirect
(
''
,
keep_items
=
dict
(
portal_status_message
=
portal_status_message
))
person_list
=
[
result
[
0
].
getObject
(),]
person
=
portal
.
restrictedTraverse
(
user_list
[
0
][
'path'
])
else
:
person
=
person_list
[
0
]
# Check the response
person
=
person_list
[
0
]
question_free_text
=
person
.
getDefaultCredentialQuestionQuestionFreeText
()
question_title
=
person
.
getDefaultCredentialQuestionQuestionTitle
()
question_answer
=
person
.
getDefaultCredentialQuestionAnswer
()
...
...
@@ -64,13 +66,13 @@ else:
if
(
question_title
or
question_free_text
)
and
(
answer
==
question_answer
):
createCredentialRecovery
(
reference
=
reference
,
default_credential_question_answer
=
default_credential_question_answer
,
destination_decision_value
_list
=
person_list
,
destination_decision_value
=
person
,
document_reference
=
document_reference
,
language
=
portal
.
Localizer
.
get_selected_language
())
elif
(
question_free_text
is
None
and
question_answer
is
None
)
or
\
not
portal_preferences
.
isPreferredAskCredentialQuestion
():
createCredentialRecovery
(
reference
=
reference
,
destination_decision_value
_list
=
person_list
,
destination_decision_value
=
person
,
document_reference
=
document_reference
,
language
=
portal
.
Localizer
.
get_selected_language
())
else
:
...
...
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/ERP5Site_newCredentialRequest.py
View file @
c194772a
...
...
@@ -45,7 +45,8 @@ credential_request.reindexObject(activate_kw=dict(tag='Person_setReference_%s' %
if
not
context
.
portal_membership
.
isAnonymousUser
():
person
=
context
.
ERP5Site_getAuthenticatedMemberPersonValue
()
destination_decision
=
[]
if
person
.
getReference
()
==
reference
:
if
reference
in
[
x
.
getReference
()
for
x
in
person
.
objectValues
(
portal_type
=
'ERP5 Login'
)
if
x
.
getValidationState
()
==
'validated'
]:
destination_decision
.
append
(
person
.
getRelativeUrl
())
if
person
.
getDefaultCareerSubordinationTitle
()
==
corporate_name
:
destination_decision
.
append
(
person
.
getDefaultCareerSubordination
())
...
...
bt5/erp5_credential/SkinTemplateItem/portal_skins/erp5_credential/ERP5Site_newPersonCredentialUpdate.py
View file @
c194772a
"""Create a credential update in relation with the person object of current user"""
portal
=
context
.
getPortalObject
()
person
=
portal
.
ERP5Site_getAuthenticatedMemberPersonValue
()
user
=
portal
.
portal_membership
.
getAuthenticatedMember
()
person
=
user
.
getUserValue
()
login
=
user
.
getLoginValue
()
if
person
is
None
:
portal_status_message
=
"Can't find corresponding person, it's not possible to update your credentials."
elif
login
is
None
:
portal_status_message
=
"Can't find corresponding login, it's not possible to update your credentials."
else
:
# create the credential update
module
=
portal
.
getDefaultModule
(
portal_type
=
'Credential Update'
)
credential_update
=
module
.
newContent
(
portal_type
=
"Credential Update"
,
reference
=
login
.
getReference
(),
first_name
=
first_name
,
last_name
=
last_name
,
gender
=
gender
,
...
...
@@ -44,10 +49,11 @@ else:
# within same transaction and update client side credentials cookie
username
=
person
.
getReference
()
if
password
and
username
==
str
(
portal
.
portal_membership
.
getAuthenticatedMember
()):
credential_update
.
accept
()
# The password is updated synchronously and the the rest of the credential Update is done later
login_reference
=
credential_update
.
Credential_updatePersonPassword
()
portal
.
cookie_authentication
.
credentialsChanged
(
person
.
Person_getUserId
(),
usernam
e
,
login_referenc
e
,
password
,
)
portal_status_message
=
"Password changed."
...
...
product/ERP5/tests/testERP5Credential.py
View file @
c194772a
...
...
@@ -322,7 +322,6 @@ class TestERP5Credential(ERP5TypeTestCase):
from
Products.PluggableAuthService.interfaces.plugins
import
\
IAuthenticationPlugin
uf
=
self
.
getUserFolder
()
self
.
assertNotEquals
(
uf
.
getUserById
(
login
,
None
),
None
)
for
plugin_name
,
plugin
in
uf
.
_getOb
(
'plugins'
).
listPlugins
(
IAuthenticationPlugin
):
if
plugin
.
authenticateCredentials
(
...
...
@@ -430,6 +429,7 @@ class TestERP5Credential(ERP5TypeTestCase):
credential_update
=
credential_update_module
.
newContent
(
\
first_name
=
'Homie'
,
last_name
=
'Simpsons'
,
# add a 's' to the end of the last_name
reference
=
'homie'
,
password
=
'new_password'
,
default_email_text
=
'homie.simpsons@fox.com'
,
destination_decision
=
homie
.
getRelativeUrl
())
...
...
@@ -548,14 +548,21 @@ class TestERP5Credential(ERP5TypeTestCase):
person_module
=
portal
.
getDefaultModule
(
'Person'
)
person
=
person_module
.
newContent
(
title
=
'Barney'
,
reference
=
'barney'
,
password
=
'secret'
,
start_date
=
DateTime
(
'1970/01/01'
),
default_email_text
=
'barney@duff.com'
)
# create an assignment
assignment
=
person
.
newContent
(
portal_type
=
'Assignment'
,
function
=
'member'
)
assignment
.
open
()
# create a login
login
=
person
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
person
.
getReference
()
+
'-login'
,
password
=
'secret'
,
)
login
.
validate
()
sequence
.
edit
(
person_reference
=
person
.
getReference
(),
login_reference
=
login
.
getReference
(),
default_email_text
=
person
.
getDefaultEmailText
())
def
stepCreateSameEmailPersonList
(
self
,
sequence
=
None
,
sequence_list
=
None
,
...
...
@@ -572,12 +579,18 @@ class TestERP5Credential(ERP5TypeTestCase):
person_module
=
portal
.
getDefaultModule
(
'Person'
)
person
=
person_module
.
newContent
(
title
=
reference
,
reference
=
reference
,
password
=
'secret'
,
default_email_text
=
default_email_text
)
# create an assignment
assignment
=
person
.
newContent
(
portal_type
=
'Assignment'
,
function
=
'member'
)
assignment
.
open
()
# create a login
login
=
person
.
newContent
(
portal_type
=
'ERP5 Login'
,
reference
=
person
.
getReference
()
+
'-login'
,
password
=
'secret'
,
)
login
.
validate
()
person_list
.
append
(
person
)
sequence
.
edit
(
person_list
=
person_list
,
...
...
@@ -590,11 +603,12 @@ class TestERP5Credential(ERP5TypeTestCase):
'''
portal
=
self
.
getPortalObject
()
person_reference
=
sequence
[
"person_reference"
]
login_reference
=
sequence
[
"login_reference"
]
person
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"Person"
,
reference
=
person_reference
)
sequence
.
edit
(
barney
=
person
)
# check barney can log in the system
self
.
_assertUserExists
(
'barney'
,
'secret'
)
self
.
_assertUserExists
(
'barney
-login
'
,
'secret'
)
self
.
login
(
'barney'
)
from
AccessControl
import
getSecurityManager
self
.
assertEqual
(
getSecurityManager
().
getUser
().
getIdOrUserName
(),
person
.
Person_getUserId
())
...
...
@@ -607,7 +621,7 @@ class TestERP5Credential(ERP5TypeTestCase):
# associate it with barney
credential_recovery
.
setDestinationDecisionValue
(
person
)
credential_recovery
.
setReference
(
person
.
getReference
()
)
credential_recovery
.
setReference
(
login_reference
)
sequence
.
edit
(
credential_recovery
=
credential_recovery
)
def
stepCreateCredentialRecoveryForUsername
(
self
,
sequence
=
None
,
sequence_list
=
None
,
...
...
@@ -635,8 +649,8 @@ class TestERP5Credential(ERP5TypeTestCase):
def
stepRequestCredentialRecoveryWithERP5Site_newCredentialRecovery
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
person_reference
=
sequence
[
"perso
n_reference"
]
self
.
portal
.
ERP5Site_newCredentialRecovery
(
reference
=
perso
n_reference
)
login_reference
=
sequence
[
"logi
n_reference"
]
self
.
portal
.
ERP5Site_newCredentialRecovery
(
reference
=
logi
n_reference
)
def
stepRequestCredentialRecoveryWithERP5Site_newCredentialRecoveryByEmail
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
...
...
@@ -656,9 +670,9 @@ class TestERP5Credential(ERP5TypeTestCase):
def
stepCreateCredentialRecoveryWithSensitiveAnswer
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
person_reference
=
sequence
[
"perso
n_reference"
]
login_reference
=
sequence
[
"logi
n_reference"
]
result
=
self
.
portal
.
ERP5Site_newCredentialRecovery
(
reference
=
perso
n_reference
,
reference
=
logi
n_reference
,
default_credential_question_question
=
'credential/library_card_number'
,
default_credential_question_answer
=
'ABCDeF'
,
)
...
...
@@ -667,7 +681,7 @@ class TestERP5Credential(ERP5TypeTestCase):
self
.
tic
()
self
.
login
()
result_list
=
self
.
portal
.
portal_catalog
(
portal_type
=
'Credential Recovery'
,
reference
=
perso
n_reference
)
portal_type
=
'Credential Recovery'
,
reference
=
logi
n_reference
)
self
.
assertEqual
(
1
,
len
(
result_list
))
credential_recovery
=
result_list
[
0
]
sequence
.
edit
(
credential_recovery
=
credential_recovery
)
...
...
@@ -681,9 +695,9 @@ class TestERP5Credential(ERP5TypeTestCase):
def
stepCheckCredentialRecoveryCreation
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
person_reference
=
sequence
[
"perso
n_reference"
]
login_reference
=
sequence
[
"logi
n_reference"
]
result_list
=
self
.
portal
.
portal_catalog
(
portal_type
=
'Credential Recovery'
,
reference
=
perso
n_reference
)
portal_type
=
'Credential Recovery'
,
reference
=
logi
n_reference
)
self
.
assertEqual
(
1
,
len
(
result_list
))
credential_recovery
=
result_list
[
0
]
person
=
credential_recovery
.
getDestinationDecisionValue
()
...
...
@@ -775,8 +789,8 @@ class TestERP5Credential(ERP5TypeTestCase):
self
.
assertTrue
(
'reset_key'
in
parameters
)
key
=
parameters
[
'reset_key'
][
0
]
# before changing, check that the user exists with 'secret' password
self
.
_assertUserExists
(
'barney'
,
'secret'
)
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"barney"
,
self
.
_assertUserExists
(
'barney
-login
'
,
'secret'
)
self
.
portal
.
portal_password
.
changeUserPassword
(
user_login
=
"barney
-login
"
,
password
=
"new_password"
,
password_confirm
=
"new_password"
,
password_key
=
key
)
...
...
@@ -784,10 +798,10 @@ class TestERP5Credential(ERP5TypeTestCase):
# reset the cache
self
.
portal
.
portal_caches
.
clearAllCache
()
# check we cannot login anymore with the previous password 'secret'
self
.
_assertUserDoesNotExists
(
'barney'
,
'secret'
)
self
.
_assertUserDoesNotExists
(
'barney
-login
'
,
'secret'
)
# check we can now login with the new password 'new_password'
self
.
_assertUserExists
(
'barney'
,
'new_password'
)
self
.
_assertUserExists
(
'barney
-login
'
,
'new_password'
)
def
_createCredentialRequest
(
self
,
first_name
=
"Barney"
,
last_name
=
"Simpson"
,
...
...
@@ -833,13 +847,13 @@ class TestERP5Credential(ERP5TypeTestCase):
def
stepSetAssigneeRoleToCurrentPersonInCredentialUpdateModule
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
user
,
=
self
.
portal
.
acl_users
.
searchUsers
(
login
=
sequence
[
'
perso
n_reference'
],
exact_match
=
True
)
user
,
=
self
.
portal
.
acl_users
.
searchUsers
(
login
=
sequence
[
'
logi
n_reference'
],
exact_match
=
True
)
self
.
portal
.
credential_update_module
.
manage_setLocalRoles
(
user
[
'id'
],
[
'Assignor'
,])
def
stepSetAssigneeRoleToCurrentPersonInCredentialRecoveryModule
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
user
,
=
self
.
portal
.
acl_users
.
searchUsers
(
login
=
sequence
[
'
perso
n_reference'
],
exact_match
=
True
)
user
,
=
self
.
portal
.
acl_users
.
searchUsers
(
login
=
sequence
[
'
logi
n_reference'
],
exact_match
=
True
)
self
.
portal
.
credential_recovery_module
.
manage_setLocalRoles
(
user
[
'id'
],
[
'Assignor'
,])
...
...
@@ -1233,10 +1247,16 @@ class TestERP5Credential(ERP5TypeTestCase):
reference = self.id()
person = self.portal.person_module.newContent(portal_type='Person',
reference=reference,
password='secret',
role='internal')
assignment = person.newContent(portal_type='Assignment', function='manager')
assignment.open()
# create a login
login = person.newContent(
portal_type='ERP5 Login',
reference=person.getReference() + '-login',
password='secret',
)
login.validate()
self.commit()
credential_update = self.portal.credential_update_module.newContent(
portal_type='Credential Update',
...
...
@@ -1254,13 +1274,20 @@ class TestERP5Credential(ERP5TypeTestCase):
person_module = self.portal.getDefaultModule('Person')
person = person_module.newContent(title='Barney',
reference='barney',
password='secret',
default_email_text='barney@duff.com')
# create an assignment
assignment = person.newContent(portal_type='Assignment',
function='member')
assignment.open()
sequence.edit(person_reference=person.getReference())
# create a login
login = person.newContent(
portal_type='ERP5 Login',
reference=person.getReference() + '-login',
password='secret',
)
login.validate()
sequence.edit(person_reference=person.getReference(),
login_reference=login.getReference())
def test_checkCredentialQuestionIsNotCaseSensitive(self):
'''
...
...
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