def test_check_auth_invalid_update_mntner_submits_new_object_with_mixed_dummy_hash_real_hash( self, prepare_mocks): mock_dq, mock_dh = prepare_mocks mock_dh.execute_query = lambda query: [{'object_text': SAMPLE_MNTNER}] reference_validator = ReferenceValidator(mock_dh) auth_validator = AuthValidator(mock_dh) # Submit the mntner with dummy password values as would be returned by queries, # but a password attribute that is valid for the current DB object. data = SAMPLE_MNTNER.replace('LEuuhsBJNFV0Q', PASSWORD_HASH_DUMMY_VALUE) result_mntner = parse_change_requests(data + 'password: md5-password', mock_dh, auth_validator, reference_validator)[0] auth_validator.pre_approve([result_mntner]) assert not result_mntner.is_valid() assert result_mntner.error_messages == [ 'Either all password auth hashes in a submitted mntner must be dummy objects, or none.', ]
def test_check_auth_invalid_update_mntner_wrong_password_current_db_object( self, prepare_mocks): mock_dq, mock_dh = prepare_mocks # Make the crypt password invalid in the version from the mock database mock_dh.execute_query = lambda query: [{ 'object_text': SAMPLE_MNTNER.replace('CRYPT-PW', 'FAILED') }] reference_validator = ReferenceValidator(mock_dh) auth_validator = AuthValidator(mock_dh) # This password is valid for the new object, but invalid for the current version in the DB result_mntner = parse_change_requests( SAMPLE_MNTNER + 'password: crypt-password', mock_dh, auth_validator, reference_validator)[0] auth_validator.pre_approve([result_mntner]) assert not result_mntner._check_auth() assert result_mntner.error_messages == [ 'Authorisation for mntner TEST-MNT failed: must by authenticated by one of: TEST-MNT, ' 'OTHER1-MNT, OTHER2-MNT' ] assert result_mntner.notification_targets() == { '*****@*****.**', '*****@*****.**' } assert flatten_mock_calls(mock_dq) == [ ['sources', (['TEST'], ), {}], ['object_classes', (['mntner'], ), {}], ['rpsl_pk', ('TEST-MNT', ), {}], ['sources', (['TEST'], ), {}], ['object_classes', (['mntner'], ), {}], ['rpsl_pks', ({'TEST-MNT', 'OTHER1-MNT', 'OTHER2-MNT'}, ), {}], ['sources', (['TEST'], ), {}], ['object_classes', (['mntner'], ), {}], ['rpsl_pks', ({'OTHER1-MNT', 'OTHER2-MNT'}, ), {}], ]
IRRD_ROOT_PATH = str(Path(__file__).resolve().parents[2]) sys.path.append(IRRD_ROOT_PATH) AS_SET_REFERRING_OTHER_SET = """as-set: AS-TESTREF descr: description members: AS-SETTEST, AS65540 tech-c: PERSON-TEST admin-c: PERSON-TEST notify: [email protected] mnt-by: TEST-MNT changed: 2017-05-19T12:22:08Z source: TEST remarks: remark """ SAMPLE_MNTNER_CLEAN = SAMPLE_MNTNER.replace( 'mnt-by: OTHER1-MNT,OTHER2-MNT\n', '') LARGE_UPDATE = '\n\n'.join([ SAMPLE_AS_BLOCK, SAMPLE_AS_SET, SAMPLE_AUT_NUM, SAMPLE_AUT_NUM.replace('aut-num: as065537', 'aut-num: as65538'), SAMPLE_AUT_NUM.replace('aut-num: as065537', 'aut-num: as65539'), SAMPLE_AUT_NUM.replace('aut-num: as065537', 'aut-num: as65540'), SAMPLE_DOMAIN, SAMPLE_FILTER_SET, SAMPLE_INET_RTR, SAMPLE_INET6NUM, SAMPLE_INETNUM, SAMPLE_KEY_CERT, SAMPLE_MNTNER_CLEAN, SAMPLE_PEERING_SET,
from irrd.storage.database_handler import DatabaseHandler from irrd.utils.rpsl_samples import (SAMPLE_AS_SET, SAMPLE_FILTER_SET, SAMPLE_MNTNER, SAMPLE_MNTNER_CRYPT, SAMPLE_MNTNER_MD5, SAMPLE_PERSON, SAMPLE_ROUTE, SAMPLE_ROUTE6) from irrd.utils.test_utils import flatten_mock_calls from irrd.utils.text import remove_auth_hashes from irrd.storage.queries import RPSLDatabaseSuspendedQuery from irrd.updates.parser_state import UpdateRequestType from ..validators import AuthValidator, RulesValidator VALID_PW = 'override-password' INVALID_PW = 'not-override-password' VALID_PW_HASH = '$1$J6KycItM$MbPaBU6iFSGFV299Rk7Di0' MNTNER_OBJ_CRYPT_PW = SAMPLE_MNTNER.replace('MD5', '') MNTNER_OBJ_MD5_PW = SAMPLE_MNTNER.replace('CRYPT', '') class TestAuthValidator: @pytest.fixture() def prepare_mocks(self, monkeypatch, config_override): mock_dh = Mock() mock_dq = Mock() monkeypatch.setattr('irrd.updates.validators.RPSLDatabaseQuery', lambda: mock_dq) config_override({ 'auth': { 'password_hashers': { 'crypt-pw': 'enabled'