116 lines
3.8 KiB
Python
116 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# authentic2 - versatile identity manager
|
|
# Copyright (C) 2010-2019 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import smtplib
|
|
|
|
import mock
|
|
import pytest
|
|
|
|
from django.core.exceptions import ValidationError
|
|
|
|
from authentic2.validators import validate_password, EmailValidator
|
|
|
|
|
|
def test_validate_password():
|
|
with pytest.raises(ValidationError):
|
|
validate_password('aaaaaZZZZZZ')
|
|
with pytest.raises(ValidationError):
|
|
validate_password('00000aaaaaa')
|
|
with pytest.raises(ValidationError):
|
|
validate_password('00000ZZZZZZ')
|
|
validate_password('000aaaaZZZZ')
|
|
|
|
|
|
def test_digits_password_policy(settings):
|
|
settings.A2_PASSWORD_POLICY_REGEX = '^[0-9]{8}$'
|
|
settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG = 'pasbon'
|
|
settings.A2_PASSWORD_POLICY_MIN_LENGTH = 0
|
|
settings.A2_PASSWORD_POLICY_MIN_CLASSES = 0
|
|
|
|
with pytest.raises(ValidationError):
|
|
validate_password('aaa')
|
|
validate_password('12345678')
|
|
|
|
|
|
@pytest.mark.parametrize('email', ['nok', '@nok.com', 'foo@bar\x00',
|
|
'foo&@bar', '|a@nok.com', 'a/../b@nok.com',
|
|
'a%b@nok.com', 'a!b@nok.com', 'a#b@nok.com',
|
|
'a&b@nok.com', 'a?b@nok.com'])
|
|
def test_email_validator_nok(email):
|
|
with pytest.raises(ValidationError):
|
|
EmailValidator()(email)
|
|
|
|
|
|
@pytest.mark.parametrize('email', ['ok@ok.com', 'a|b@ok.com', 'a/..b@ok.com'])
|
|
def test_email_validator_ok(email):
|
|
EmailValidator()('ok@ok.com')
|
|
|
|
|
|
def test_email_validator_domain(settings):
|
|
settings.A2_VALIDATE_EMAIL_DOMAIN = True
|
|
with mock.patch('authentic2.validators.EmailValidator.query_mxs', return_value=[]) as query_mxs:
|
|
with pytest.raises(ValidationError):
|
|
EmailValidator()('ok@ok.com')
|
|
assert query_mxs.call_count == 1
|
|
with mock.patch('authentic2.validators.EmailValidator.query_mxs', return_value=['ok']) as query_mxs:
|
|
EmailValidator()('ok@ok.com')
|
|
assert query_mxs.call_count == 1
|
|
|
|
|
|
@pytest.fixture
|
|
def smtp():
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *args):
|
|
return None
|
|
|
|
smtp = mock.Mock()
|
|
smtp.helo.return_value = 250, None
|
|
smtp.__enter__ = __enter__
|
|
smtp.__exit__ = __exit__
|
|
with mock.patch('smtplib.SMTP', return_value=smtp):
|
|
yield smtp
|
|
|
|
|
|
def test_email_validator_rcpt_check(settings, smtp):
|
|
settings.A2_VALIDATE_EMAIL_DOMAIN = True
|
|
settings.A2_VALIDATE_EMAIL = True
|
|
|
|
validator = EmailValidator(rcpt_check=True)
|
|
|
|
with mock.patch('authentic2.validators.EmailValidator.query_mxs', return_value=['ok']):
|
|
smtp.rcpt.return_value = 100, None
|
|
validator('ok@ok.com')
|
|
|
|
smtp.rcpt.return_value = 500, None
|
|
with pytest.raises(ValidationError):
|
|
validator('ok@ok.com')
|
|
|
|
smtp.rcpt.return_value = 100, None
|
|
smtp.rcpt.side_effect = smtplib.SMTPServerDisconnected
|
|
validator('ok@ok.com')
|
|
|
|
smtp.rcpt.return_value = 100, None
|
|
smtp.connect.side_effect = smtplib.SMTPConnectError(1,2)
|
|
validator('ok@ok.com')
|
|
|
|
assert smtp.connect.call_count == 4
|
|
assert smtp.rcpt.call_count == 3
|