1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from hashlib
import md5
as _md5
21 from indico
.util
.passwords
import PasswordProperty
, BCryptPassword
25 if isinstance(s
, unicode):
27 return _md5(s
).hexdigest()
31 def __init__(self
, password
=None):
32 if password
is not None:
33 self
.password
= password
35 password
= PasswordProperty('_password')
39 def mock_bcrypt(mocker
):
40 def _hashpw(value
, salt
):
41 assert isinstance(value
, str), 'hashpw expects bytes'
42 assert isinstance(salt
, str), 'hashpw expects bytes'
45 bcrypt
= mocker
.patch('indico.util.passwords.bcrypt')
46 bcrypt
.gensalt
.return_value
= 'salt'
47 bcrypt
.hashpw
.side_effect
= _hashpw
51 @pytest.mark
.parametrize('password', (u
'm\xf6p', 'foo'))
52 def test_passwordproperty_set(mock_bcrypt
, password
):
54 test
.password
= password
55 assert mock_bcrypt
.hashpw
.called
56 mock_bcrypt
.hashpw
.assert_called_with(password
.encode('utf-8'), 'salt')
57 assert test
._password
== md5(password
)
60 @pytest.mark
.parametrize('password', ('', None))
61 @pytest.mark
.usefixtures('mock_bcrypt')
62 def test_passwordproperty_set_invalid(password
):
64 with pytest
.raises(ValueError):
65 test
.password
= password
68 @pytest.mark
.usefixtures('mock_bcrypt')
69 def test_passwordproperty_del():
72 assert test
._password
== md5('foo')
74 assert test
._password
is None
77 def test_passwordproperty_get():
79 assert isinstance(test
.password
, BCryptPassword
)
82 @pytest.mark
.parametrize(('password_hash_unicode', 'password'), (
88 @pytest.mark
.usefixtures('mock_bcrypt')
89 def test_bcryptpassword_check(password_hash_unicode
, password
):
90 password_hash
= bytes(md5(password
))
91 if password_hash_unicode
:
92 password_hash
= unicode(password_hash
)
93 pw
= BCryptPassword(password_hash
)
94 assert pw
== unicode(password
)
95 assert pw
== unicode(password
).encode('utf-8')
96 assert pw
!= u
'notthepassword'
97 assert pw
!= 'notthepassword'
100 @pytest.mark
.parametrize(('password_hash', 'password'), (
106 @pytest.mark
.usefixtures('mock_bcrypt')
107 def test_bcryptpassword_check_empty(password_hash
, password
):
109 pw
.hash = password_hash
111 assert pw
!= password