Fix day filter
[cds-indico.git] / indico / util / passwords_test.py
blob7fe70076c26e0566c0b9894660d2fa2a330ab5e7
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
19 import pytest
21 from indico.util.passwords import PasswordProperty, BCryptPassword
24 def md5(s):
25 if isinstance(s, unicode):
26 s = s.encode('utf-8')
27 return _md5(s).hexdigest()
30 class Foo(object):
31 def __init__(self, password=None):
32 if password is not None:
33 self.password = password
35 password = PasswordProperty('_password')
38 @pytest.fixture
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'
43 return md5(value)
45 bcrypt = mocker.patch('indico.util.passwords.bcrypt')
46 bcrypt.gensalt.return_value = 'salt'
47 bcrypt.hashpw.side_effect = _hashpw
48 return bcrypt
51 @pytest.mark.parametrize('password', (u'm\xf6p', 'foo'))
52 def test_passwordproperty_set(mock_bcrypt, password):
53 test = Foo()
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):
63 test = Foo()
64 with pytest.raises(ValueError):
65 test.password = password
68 @pytest.mark.usefixtures('mock_bcrypt')
69 def test_passwordproperty_del():
70 test = Foo()
71 test.password = 'foo'
72 assert test._password == md5('foo')
73 del test.password
74 assert test._password is None
77 def test_passwordproperty_get():
78 test = Foo()
79 assert isinstance(test.password, BCryptPassword)
82 @pytest.mark.parametrize(('password_hash_unicode', 'password'), (
83 (False, 'moep'),
84 (True, 'moep'),
85 (False, u'm\xf6p'),
86 (True, u'm\xf6p')
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'), (
101 (md5(''), ''),
102 ('', ''),
103 ('', 'foo'),
104 ('foo', '')
106 @pytest.mark.usefixtures('mock_bcrypt')
107 def test_bcryptpassword_check_empty(password_hash, password):
108 pw = Foo().password
109 pw.hash = password_hash
110 assert pw != 'xxx'
111 assert pw != password