authentic/tests/test_validators.py

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