def test_get_logged_in_user_from_session(mocker): mocker.patch('confidant.authnz.settings.USER_EMAIL_SUFFIX', 'example.com') app = create_app() with app.test_request_context('/v1/user/email'): session_data = {'user': {'email': '*****@*****.**'}} mocker.patch('confidant.authnz.userauth.session', session_data) assert authnz.get_logged_in_user() == '*****@*****.**'
def test_require_csrf_token(mocker): mock_fn = mocker.Mock() mock_fn.__name__ = 'mock_fn' mock_fn.return_value = 'unittestval' wrapped = authnz.require_csrf_token(mock_fn) mocker.patch('confidant.authnz.settings.USE_AUTH', False) assert wrapped() == 'unittestval' mocker.patch('confidant.authnz.settings.USE_AUTH', True) app = create_app() with app.app_context(): g_mock = mocker.patch('confidant.authnz.g') g_mock.auth_type = 'kms' assert wrapped() == 'unittestval' g_mock.auth_type = 'google oauth' u_mock = mocker.patch('confidant.authnz.user_mod') u_mock.check_csrf_token = mocker.Mock(return_value=True) assert wrapped() == 'unittestval' g_mock.auth_type = 'google oauth' u_mock = mocker.patch('confidant.authnz.user_mod') u_mock.check_csrf_token = mocker.Mock(return_value=False) with pytest.raises(Unauthorized): wrapped()
def test_get_credential_list(mocker, credential_list): app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.credentials.authnz.get_logged_in_user', return_value='*****@*****.**', ) mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=False, ) ret = app.test_client().get('/v1/credentials', follow_redirects=False) assert ret.status_code == 403 mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=True, ) mocker.patch( 'confidant.models.credential.Credential.data_type_date_index.query', return_value=credential_list, ) ret = app.test_client().get('/v1/credentials', follow_redirects=False) json_data = json.loads(ret.data) assert ret.status_code == 200 assert len(json_data['credentials']) == len(credential_list) assert json_data['next_page'] is None
def test_no_auth(mocker): mocker.patch('confidant.settings.USE_AUTH', False) app = create_app() app.debug = True user_mod = userauth.init_user_auth_class() mocker.patch('confidant.authnz.user_mod', user_mod) ret = app.test_client().get('/v1/user/email') assert ret.status_code == 200
def test_default_acl(mocker): app = create_app() with app.test_request_context('/fake'): # Test for user type is user mocker.patch('confidant.authnz.user_is_user_type', return_value=True) assert rbac.default_acl(resource_type='service') is True # Test for user type is service, but not an allowed resource type mocker.patch( 'confidant.authnz.user_is_user_type', side_effect=[False, True], ) assert rbac.default_acl(resource_type='service', action='update') is False # Test for user type is service, and an allowed resource, with metadata # action, but service name doesn't match mocker.patch( 'confidant.authnz.user_is_user_type', side_effect=[False, True], ) mocker.patch( 'confidant.authnz.user_is_service', return_value=False, ) assert rbac.default_acl(resource_type='service', action='metadata') is False # Test for user type is service, and an allowed resource, with metadata # action mocker.patch( 'confidant.authnz.user_is_user_type', side_effect=[False, True], ) mocker.patch( 'confidant.authnz.user_is_service', return_value=True, ) assert rbac.default_acl(resource_type='service', action='metadata') is True # Test for user type is service, and an allowed resource, with get # action mocker.patch( 'confidant.authnz.user_is_user_type', side_effect=[False, True], ) assert rbac.default_acl(resource_type='service', action='get') is True # Test for user type is service, and an allowed resource, with # disallowed fake action mocker.patch( 'confidant.authnz.user_is_user_type', side_effect=[False, True], ) assert rbac.default_acl(resource_type='service', action='fake') is False # Test for bad user type mocker.patch( 'confidant.authnz.user_is_user_type', side_effect=[False, False], ) assert rbac.default_acl(resource_type='service', action='get') is False
def test_get_logged_in_user(mocker): mocker.patch('confidant.authnz.settings.USER_EMAIL_SUFFIX', 'example.com') app = create_app() with app.test_request_context('/v1/user/email'): with pytest.raises(authnz.UserUnknownError): authnz.get_logged_in_user() g_mock = mocker.patch('confidant.authnz.g') g_mock.username = '******' assert authnz.get_logged_in_user() == 'unittestuser'
def test_service_in_account(mocker): # If we aren't scoping, this should pass assert authnz.service_in_account(None) is True app = create_app() with app.app_context(): g_mock = mocker.patch('confidant.authnz.g') g_mock.account = 'confidant-unitttest' assert authnz.service_in_account('bad-service') is False assert authnz.service_in_account('confidant-unitttest') is True
def test_invalid_kms_auth_token(mocker): mocker.patch('confidant.settings.USE_AUTH', True) app = create_app() app.debug = True auth = base64.b64encode(b'confidant-development:faketoken').decode() ret = app.test_client().get( '/v1/services/confidant-development', headers={'Authorization': 'Basic {0}'.format(auth)}, follow_redirects=False) assert ret.status_code == 403
def test_get_user_info_no_user(mocker): mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.identity.authnz.get_logged_in_user', side_effect=UserUnknownError(), ) app = create_app() ret = app.test_client().get('/v1/user/email', follow_redirects=False) assert ret.status_code == 200 assert ret.json == {'email': None}
def test_get_user_info(mocker): mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.identity.authnz.get_logged_in_user', return_value='*****@*****.**', ) app = create_app() ret = app.test_client().get('/v1/user/email', follow_redirects=False) assert ret.status_code == 200 assert ret.json == {'email': '*****@*****.**'}
def test_get_client_config(mocker): def acl_module_check(resource_type, action): if resource_type == 'credential': if action == 'create': return False elif action == 'list': return True elif resource_type == 'service': if action == 'create': return True elif action == 'list': return False mocker.patch('confidant.routes.identity.acl_module_check', acl_module_check) mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch('confidant.settings.CLIENT_CONFIG', {'test': 'client_config'}) mocker.patch('confidant.settings.KMS_AUTH_MANAGE_GRANTS', False) mocker.patch( 'confidant.settings.SCOPED_AUTH_KEYS', {'sandbox-account': 'sandbox'}, ) mocker.patch('confidant.settings.XSRF_COOKIE_NAME', 'CSRF_TOKEN') mocker.patch('confidant.settings.MAINTENANCE_MODE', True) mocker.patch('confidant.settings.HISTORY_PAGE_LIMIT', 50) expected = { 'defined': {'test': 'client_config'}, 'generated': { 'kms_auth_manage_grants': False, 'aws_accounts': ['sandbox'], 'xsrf_cookie_name': 'CSRF_TOKEN', 'maintenance_mode': True, 'history_page_limit': 50, 'defined_tags': [], 'permissions': { 'credentials': { 'list': True, 'create': False, }, 'blind_credentials': { 'list': True, 'create': True, }, 'services': { 'list': False, 'create': True, }, }, }, } app = create_app() ret = app.test_client().get('/v1/client_config', follow_redirects=False) assert ret.status_code == 200 assert ret.json == expected
def test_auth_with_email_session_bad_prefix(mocker): mocker.patch('confidant.settings.USE_AUTH', True) # USERS_FILE needs to be set to test users file mocker.patch('confidant.settings.USERS_FILE', '') mocker.patch('confidant.settings.USER_EMAIL_SUFFIX', '@example.com') app = create_app() app.debug = True with app.test_client() as c: with c.session_transaction() as session: session['user'] = {'email': '*****@*****.**'} ret = c.get('/v1/user/email', follow_redirects=False) assert ret.status_code == 403
def test_header_auth_will_log_in(mocker, mock_header_auth): app = create_app() with app.test_request_context('/fake'): request_mock = mocker.patch('confidant.authnz.userauth.request') request_mock.headers = { 'X-Confidant-Username': '******', 'X-Confidant-Email': '*****@*****.**', # noqa:E501 } resp = authnz.user_mod.log_in() assert resp.status_code == 302 assert resp.headers['Location'] == '/'
def test_user_is_service(mocker): mocker.patch('confidant.authnz.settings.USE_AUTH', False) assert authnz.user_is_service('anything') is True mocker.patch('confidant.authnz.settings.USE_AUTH', True) app = create_app() with app.app_context(): g_mock = mocker.patch('confidant.authnz.g') g_mock.username = '******' assert authnz.user_is_service('confidant-unitttest') is True g_mock.username = '******' assert authnz.user_is_service('notconfidant-unitttest') is False
def test_auth_with_email_session_in_users(mocker): mocker.patch('confidant.settings.USE_AUTH', True) mocker.patch('confidant.settings.USER_EMAIL_SUFFIX', '') app = create_app() app.debug = True to_patch = ('confidant.authnz.userauth.AbstractUserAuthenticator.' 'allowed_email_whitelist') mock_whitelist = mocker.patch(to_patch, new_callable=mocker.PropertyMock) mock_whitelist.return_value = ['*****@*****.**'] with app.test_client() as c: with c.session_transaction() as session: session['user'] = {'email': '*****@*****.**'} ret = c.get('/v1/user/email', follow_redirects=False) assert ret.status_code == 200
def test_header_auth_will_extract_from_request(mocker, mock_header_auth): app = create_app() with app.test_request_context('/fake'): # No headers given: an error with pytest.raises(authnz.UserUnknownError): authnz.get_logged_in_user() # Both headers given: success request_mock = mocker.patch('confidant.authnz.userauth.request') request_mock.headers = { 'X-Confidant-Username': '******', 'X-Confidant-Email': '*****@*****.**', # noqa:E501 } assert authnz.get_logged_in_user() == '*****@*****.**'
def test_get_ca(mocker): app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.certificates.authnz.get_logged_in_user', return_value='*****@*****.**', ) mocker.patch( 'confidant.routes.certificates.acl_module_check', return_value=False, ) ret = app.test_client().get( '/v1/cas', follow_redirects=False, ) assert ret.status_code == 403 mocker.patch( 'confidant.routes.certificates.acl_module_check', return_value=True, ) mocker.patch('confidant.authnz.get_logged_in_user', return_value='test') ca_object = certificatemanager.CertificateAuthority('development') mocker.patch( ('confidant.routes.certificates.certificatemanager.get_ca'), return_value=ca_object, ) ca_object.get_certificate_authority_certificate = mocker.Mock( return_value={ 'ca': 'development', 'certificate': 'test_certificate', 'certificate_chain': 'test_certificate_chain', 'tags': {'environment': 'development'}, }, ) ret = app.test_client().get('/v1/cas/development', follow_redirects=False) json_data = json.loads(ret.data) assert ret.status_code == 200 assert json_data == { 'ca': 'development', 'certificate': 'test_certificate', 'certificate_chain': 'test_certificate_chain', 'tags': {'environment': 'development'}, }
def test_user_is_user_type(mocker): mocker.patch('confidant.authnz.settings.USE_AUTH', False) assert authnz.user_is_user_type('anything') is True mocker.patch('confidant.authnz.settings.USE_AUTH', True) app = create_app() with app.app_context(): g_mock = mocker.patch('confidant.authnz.g') g_mock.user_type = 'user' assert authnz.user_is_user_type('user') is True g_mock.user_type = 'service' assert authnz.user_is_user_type('service') is True g_mock.user_type = 'user' assert authnz.user_is_user_type('service') is False g_mock.user_type = 'service' assert authnz.user_is_user_type('user') is False
def test__get_kms_auth_data_from_auth(mocker): app = create_app() with app.test_request_context('/fake'): auth_mock = mocker.patch('confidant.authnz.request') expected = { 'username': '******', 'token': 'test-token', } auth_mock.authorization = { 'username': expected['username'], 'password': expected['token'], } auth_mock.headers = None assert authnz._get_kms_auth_data() == expected auth_mock.authorization = { 'username': expected['username'], } with pytest.raises(authnz.AuthenticationError): authnz._get_kms_auth_data()
def test_header_csrf(mocker): mocker.patch('confidant.settings.USE_AUTH', True) mocker.patch('confidant.settings.USER_AUTH_MODULE', 'header') mocker.patch( 'confidant.settings.HEADER_AUTH_USERNAME_HEADER', 'X-Confidant-User', ) mocker.patch( 'confidant.settings.HEADER_AUTH_EMAIL_HEADER', 'X-Confidant-Email', ) mocker.patch( 'confidant.settings.XSRF_COOKIE_NAME', 'XSRF-TOKEN', ) app = create_app() app.debug = True user_mod = userauth.init_user_auth_class() mocker.patch('confidant.authnz.user_mod', user_mod) ret = app.test_client().get( '/v1/user/email', headers={ "X-Confidant-User": "******", "X-Confidant-Email": "*****@*****.**", }, ) assert ret.status_code == 200 def has_xsrf_cookie(headers): cookies = headers.get_all('Set-Cookie') for cookie in cookies: if cookie.startswith('XSRF-TOKEN='): return True return False assert has_xsrf_cookie(ret.headers) is True
def test_get_credential(mocker, credential): app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch('confidant.settings.ENABLE_SAVE_LAST_DECRYPTION_TIME', True) mocker.patch.object(Credential, 'save', return_value=None) mocker.patch( 'confidant.routes.credentials.authnz.get_logged_in_user', return_value='*****@*****.**', ) mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=False, ) ret = app.test_client().get('/v1/credentials/1234', follow_redirects=False) assert ret.status_code == 403 def acl_module_check(resource_type, action, resource_id): if action == 'metadata': if resource_id == '5678': return False else: return True elif action == 'get': if resource_id == '9012': return False else: return True elif action == 'update': if resource_id == '3456': return True else: return False mocker.patch( 'confidant.routes.credentials.acl_module_check', acl_module_check, ) mocker.patch( 'confidant.routes.credentials.Credential.get', return_value=credential, ) mocker.patch( ('confidant.routes.credentials.Credential' '._get_decrypted_credential_pairs'), return_value={'test': 'me'}, ) ret = app.test_client().get('/v1/credentials/1234', follow_redirects=False) json_data = json.loads(ret.data) assert ret.status_code == 200 assert json_data['permissions']['update'] is False credential.data_type = 'service' ret = app.test_client().get('/v1/credentials/1234', follow_redirects=False) assert ret.status_code == 404 credential.data_type = 'credential' credential.id = '5678' ret = app.test_client().get('/v1/credentials/5678', follow_redirects=False) assert ret.status_code == 403 credential.data_type = 'credential' credential.id = '9012' ret = app.test_client().get('/v1/credentials/5678', follow_redirects=False) assert ret.status_code == 403 # Make sure credential is saved when ENABLE_SAVE_LAST_DECRYPTION_TIME=True # and metadata_only=False credential.last_rotation_date = datetime(2020, 1, 1, tzinfo=pytz.UTC) mock_save = mocker.patch.object(Credential, 'save', return_value=None) credential.id = '9012' ret = app.test_client().get('/v1/credentials/3456?metadata_only=false', follow_redirects=False) json_data = json.loads(ret.data) assert ret.status_code == 200 assert json_data['permissions']['update'] is True assert 'next_rotation_date' in json_data assert mock_save.call_count == 2 # Once for credential, once for archive # Make sure credential is NOT saved when # ENABLE_SAVE_LAST_DECRYPTION_TIME=True and metadata_only=True mock_save = mocker.patch.object(Credential, 'save', return_value=None) ret = app.test_client().get('/v1/credentials/3456?metadata_only=true', follow_redirects=False) json_data = json.loads(ret.data) assert ret.status_code == 200 assert json_data['permissions']['update'] is True assert mock_save.call_count == 0 # Archive credential not found # Fail open - still return a 200 mocker.patch('confidant.routes.credentials.Credential.get', side_effect=[credential, DoesNotExist()]) ret = app.test_client().get('/v1/credentials/3456?metadata_only=false', follow_redirects=False) json_data = json.loads(ret.data) assert ret.status_code == 200 mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=DoesNotExist(), ) ret = app.test_client().get( '/v1/credentials/1234', follow_redirects=False, ) assert ret.status_code == 404
def test_get_certificate_from_csr(mocker): ca_object = certificatemanager.CertificateAuthority('development') key = ca_object.generate_key() csr = ca_object.generate_csr(key, 'test.example.com') pem_csr = ca_object.encode_csr(csr) app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) ret = app.test_client().post( '/v1/certificates/development', data=json.dumps({}), content_type='application/json', follow_redirects=False, ) assert ret.status_code == 400 ret = app.test_client().post( '/v1/certificates/development', data=json.dumps({'validity': 7}), content_type='application/json', follow_redirects=False, ) assert ret.status_code == 400 ret = app.test_client().post( '/v1/certificates/development', data=json.dumps({'csr': 'invalid_csr'}), content_type='application/json', follow_redirects=False, ) assert ret.status_code == 400 mocker.patch( 'confidant.routes.certificates.authnz.user_is_user_type', return_value=True, ) mocker.patch( 'confidant.routes.certificates.authnz.user_is_service', return_value=False, ) mocker.patch( 'confidant.routes.certificates.authnz.get_logged_in_user', return_value='badservice', ) ret = app.test_client().post( '/v1/certificates/development', data=json.dumps({ 'csr': pem_csr, 'validity': 7, }), content_type='application/json', follow_redirects=False, ) assert ret.status_code == 403 mocker.patch( 'confidant.routes.certificates.authnz.user_is_user_type', return_value=False, ) mocker.patch( 'confidant.routes.certificates.authnz.get_logged_in_user', return_value='*****@*****.**', ) mocker.patch( 'confidant.routes.certificates.acl_module_check', return_value=False, ) ret = app.test_client().post( '/v1/certificates/development', data=json.dumps({ 'csr': pem_csr, 'validity': 7, }), content_type='application/json', follow_redirects=False, ) assert ret.status_code == 403 mocker.patch( 'confidant.routes.certificates.acl_module_check', return_value=True, ) mocker.patch( ('confidant.routes.certificates.certificatemanager.get_ca'), return_value=ca_object, ) ca_object.issue_certificate = mocker.Mock( return_value='test-certificate-arn', ) ca_object.get_certificate_from_arn = mocker.Mock( return_value={ 'certificate': 'test_certificate', 'certificate_chain': 'test_certificate_chain', }, ) ret = app.test_client().post( '/v1/certificates/development', data=json.dumps({ 'csr': pem_csr, 'validity': 7, }), content_type='application/json', follow_redirects=False, ) json_data = json.loads(ret.data) assert ret.status_code == 200 assert json_data == { 'certificate': 'test_certificate', 'certificate_chain': 'test_certificate_chain', }
def test_auth_redirect(mocker): mocker.patch('confidant.settings.USE_AUTH', True) app = create_app() app.debug = True ret = app.test_client().get('/', follow_redirects=False) assert ret.status_code == 302
def test_no_acl(): app = create_app() with app.test_request_context('/fake'): assert rbac.no_acl(resource_type='service', action='update') is True
def test_default_acl(mocker): mocker.patch('confidant.settings.USE_AUTH', True) app = create_app() with app.test_request_context('/fake'): g_mock = mocker.patch('confidant.authnz.g') # Test for user type is user g_mock.user_type = 'user' assert rbac.default_acl(resource_type='service') is True assert rbac.default_acl(resource_type='certificate') is False # Test for user type is service, but not an allowed resource type g_mock.user_type = 'service' g_mock.username = '******' assert rbac.default_acl( resource_type='service', action='update', resource_id='test-service' ) is False # Test for user type is service, and an allowed resource, with metadata # action, but service name doesn't match g_mock.username = '******' assert rbac.default_acl( resource_type='service', action='metadata', resource_id='test-service', ) is False # Test for user type is service, and an allowed resource, with metadata # action g_mock.username = '******' assert rbac.default_acl( resource_type='service', action='metadata', resource_id='test-service', ) is True # Test for user type is service, and an allowed resource, with get # action assert rbac.default_acl( resource_type='service', action='get', resource_id='test-service', ) is True # Test for user type is service, with certificate resource and get # action, with a CN that doesn't match the name pattern assert rbac.default_acl( resource_type='certificate', action='get', # missing domain name... resource_id='test-service', kwargs={'ca': 'development'}, ) is False # Test for user type is service, with certificate resource and get # action, with a valid CN assert rbac.default_acl( resource_type='certificate', action='get', resource_id='test-service.example.com', kwargs={'ca': 'development'}, ) is True # Test for user type is service, with certificate resource and get # action, with a valid CN, and valid SAN values assert rbac.default_acl( resource_type='certificate', action='get', resource_id='test-service.example.com', kwargs={ 'ca': 'development', 'san': [ 'test-service.internal.example.com', 'test-service.external.example.com', ], }, ) is True # Test for user type is service, with certificate resource and get # action, with an invalid CN assert rbac.default_acl( resource_type='certificate', action='get', resource_id='bad-service.example.com', kwargs={'ca': 'development'}, ) is False # Test for user type is service, with certificate resource and get # action, with a valid CN, but an invalid SAN assert rbac.default_acl( resource_type='certificate', action='get', resource_id='test-service.example.com', kwargs={ 'ca': 'development', 'san': ['bad-service.example.com'], }, ) is False # Test for user type is service, with certificate resource and get # action, with a valid CN, but a mix of valid and invalid SAN values assert rbac.default_acl( resource_type='certificate', action='get', resource_id='test-service.example.com', kwargs={ 'ca': 'development', 'san': [ 'bad-service.example.com', 'test-service.example.com', ], }, ) is False # Test for user type is service, and an allowed resource, with # disallowed fake action assert rbac.default_acl(resource_type='service', action='fake') is False # Test for bad user type g_mock.user_type = 'badtype' assert rbac.default_acl(resource_type='service', action='get') is False
def test_create_credential(mocker, credential): app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.credentials.authnz.get_logged_in_user', return_value='*****@*****.**', ) # Bad ACL check mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=False, ) ret = app.test_client().post('/v1/credentials', ) assert ret.status_code == 403 # Bad request - required fields not present mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=True, ) mocker.patch( 'confidant.routes.credentials.Credential.data_type_date_index.query', return_value=credential, ) mocker.patch( 'confidant.routes.credentials.settings.ENFORCE_DOCUMENTATION', True, ) ret = app.test_client().post( '/v1/credentials', headers={"Content-Type": 'application/json'}, data=json.dumps({'name': 'me'}), ) json_data = json.loads(ret.data) assert ret.status_code == 400 assert 'documentation is a required field' == json_data['error'] # Credential name already exists (ie: query returns a value) mocker.patch( 'confidant.routes.credentials.Credential.data_type_date_index.query', return_value=[credential], ) ret = app.test_client().post( '/v1/credentials', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'name': 'me', 'documentation': 'doc', 'credential_pairs': { 'key': 'value' }, }), ) json_data = json.loads(ret.data) assert ret.status_code == 409 assert 'Name already exists' in json_data['error'] # All good mocker.patch( ('confidant.routes.credentials.Credential' '.data_type_date_index.query'), return_value=[], ) mocker.patch( 'confidant.routes.credentials.keymanager.create_datakey', return_value={ 'plaintext': '123', 'ciphertext': '888' }, ) mock_save = mocker.patch('confidant.routes.credentials.Credential.save') mocker.patch('confidant.routes.credentials.graphite.send_event') mocker.patch('confidant.routes.credentials.webhook.send_event') mocker.patch( ('confidant.routes.credentials.Credential' '._get_decrypted_credential_pairs'), return_value={'test': 'me'}, ) mocker.patch('confidant.routes.credentials.CipherManager.encrypt', return_value={'foo': 'baz'}) ret = app.test_client().post( '/v1/credentials', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'documentation': 'doc', 'credential_pairs': { 'key': 'value' }, 'name': 'shiny new key', 'tags': ['ADMIN_PRIV', 'MY_SPECIAL_TAG'], }), ) json_data = json.loads(ret.data) assert ret.status_code == 200 assert ['ADMIN_PRIV', 'MY_SPECIAL_TAG'] == json_data['tags'] assert 'shiny new key' == json_data['name'] assert mock_save.call_count == 2
def test_update_credential(mocker, credential): credential.last_rotation_date = datetime(2020, 1, 1, tzinfo=pytz.UTC) app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.credentials.authnz.get_logged_in_user', return_value='*****@*****.**', ) # Bad ACL check mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=False, ) ret = app.test_client().put( '/v1/credentials/123', headers={"Content-Type": 'application/json'}, data='{}', ) assert ret.status_code == 403 # Credential not found mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=True, ) mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=DoesNotExist(), ) ret = app.test_client().put( '/v1/credentials/123', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'enabled': 123, }), ) json_data = json.loads(ret.data) assert ret.status_code == 404 assert 'Credential not found.' == json_data['error'] # Bad Request mocker.patch( 'confidant.routes.credentials.Credential.get', return_value=credential, ) mocker.patch( ('confidant.routes.credentials.credentialmanager' '.get_latest_credential_revision'), return_value=12, ) ret = app.test_client().put( '/v1/credentials/123', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'enabled': 123, }), ) json_data = json.loads(ret.data) assert ret.status_code == 400 assert 'Enabled must be a boolean.' == json_data['error'] # Credential conflicts with another service mocker.patch( 'confidant.routes.credentials.keymanager.create_datakey', return_value={ 'plaintext': '123', 'ciphertext': '888' }, ) mocker.patch( ('confidant.routes.credentials.Credential' '._get_decrypted_credential_pairs'), return_value={'test': 'me'}, ) mocker.patch( ('confidant.routes.credentials.servicemanager' '.get_services_for_credential'), return_value=[], ) mocker.patch( ('confidant.routes.credentials.servicemanager' '.pair_key_conflicts_for_services'), return_value={'123': { 'services': ['service1'] }}, ) ret = app.test_client().put( '/v1/credentials/123', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'credential_pairs': { 'foo': 'baz' }, 'enabled': True, }), ) json_data = json.loads(ret.data) assert ret.status_code == 400 assert 'Conflicting key pairs in mapped service.' == json_data['error'] # All good mocker.patch( ('confidant.routes.credentials.servicemanager' '.pair_key_conflicts_for_services'), return_value={}, ) mock_save = mocker.patch('confidant.routes.credentials.Credential.save') mocker.patch('confidant.routes.credentials.graphite.send_event') mocker.patch('confidant.routes.credentials.webhook.send_event') mocker.patch('confidant.routes.credentials.CipherManager.encrypt', return_value={'foo': 'baz'}) ret = app.test_client().put( '/v1/credentials/123', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'enabled': True, 'credential_pairs': { 'key': 'value' }, 'name': 'shiny new name', 'documentation': 'doc', 'tags': ['NEW SPECIAL TAG', 'DB_AUTH'], }), ) json_data = json.loads(ret.data) assert ret.status_code == 200 assert ['NEW SPECIAL TAG', 'DB_AUTH'] == json_data['tags'] assert 'shiny new name' == json_data['name'] assert mock_save.call_count == 2 assert 'last_rotation_date' in json_data assert 'next_rotation_date' in json_data
def test_revise_credential(mocker, credential, archive_credential): app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.credentials.authnz.get_logged_in_user', return_value='*****@*****.**', ) # Bad ACL check mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=False, ) ret = app.test_client().put( '/v1/credentials/123/10', headers={"Content-Type": 'application/json'}, data='{}', ) assert ret.status_code == 403 # Credential not found mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=True, ) mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=DoesNotExist(), ) ret = app.test_client().put( '/v1/credentials/123/10', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'enabled': 123, }), ) json_data = json.loads(ret.data) assert ret.status_code == 404 assert 'Credential not found.' == json_data['error'] # Revert revision not an archive credential mocker.patch( 'confidant.routes.credentials.Credential.get', return_value=credential, ) mocker.patch( ('confidant.routes.credentials.credentialmanager' '.get_latest_credential_revision'), return_value=12, ) ret = app.test_client().put( '/v1/credentials/123/10', headers={"Content-Type": 'application/json'}, data=json.dumps({ 'enabled': 123, }), ) json_data = json.loads(ret.data) assert ret.status_code == 400 assert 'id provided is not a credential.' == json_data['error'] # Revert conflicts with another service mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=[credential, archive_credential], ) mocker.patch( 'confidant.routes.credentials.keymanager.create_datakey', return_value={ 'plaintext': '123', 'ciphertext': '888' }, ) mocker.patch( ('confidant.routes.credentials.Credential' '._get_decrypted_credential_pairs'), return_value={'test': 'me'}, ) mocker.patch( ('confidant.routes.credentials.servicemanager' '.get_services_for_credential'), return_value=[], ) mocker.patch( ('confidant.routes.credentials.servicemanager' '.pair_key_conflicts_for_services'), return_value={'123': { 'services': ['service1'] }}, ) ret = app.test_client().put( '/v1/credentials/123/10', headers={"Content-Type": 'application/json'}, data=json.dumps({}), ) json_data = json.loads(ret.data) assert ret.status_code == 400 assert 'Conflicting key pairs in mapped service.' == json_data['error'] # All good mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=[credential, archive_credential], ) mocker.patch( ('confidant.routes.credentials.servicemanager' '.pair_key_conflicts_for_services'), return_value={}, ) mock_save = mocker.patch('confidant.routes.credentials.Credential.save') mocker.patch('confidant.routes.credentials.graphite.send_event') mocker.patch('confidant.routes.credentials.webhook.send_event') mocker.patch('confidant.routes.credentials.CipherManager.encrypt', return_value={'foo': 'baz'}) ret = app.test_client().put( '/v1/credentials/123/10', headers={"Content-Type": 'application/json'}, data=json.dumps({}), ) json_data = json.loads(ret.data) assert ret.status_code == 200 assert ['OLD TAG'] == json_data['tags'] assert 'Archive credential' == json_data['name'] assert mock_save.call_count == 2
from confidant.app import create_app from confidant.scripts.archive import ArchiveCredentials from confidant.scripts.utils import ManageGrants from confidant.scripts.utils import RevokeGrants from confidant.scripts.utils import CreateDynamoTables from confidant.scripts.bootstrap import GenerateSecretsBootstrap from confidant.scripts.bootstrap import DecryptSecretsBootstrap from confidant.scripts.migrate import ( MigrateBlindCredentialSetAttribute, MigrateServiceSetAttribute, ) from confidant.scripts.migrate_bool import MigrateBooleanAttribute from confidant.scripts.restore import RestoreCredentials app = create_app() manager = Manager(app) # Ensure KMS grants are setup for services manager.add_command("manage_kms_auth_grants", ManageGrants) # Revoke all KMS grants manager.add_command("revoke_all_kms_auth_grants", RevokeGrants) # Generate encrypted blob from a file manager.add_command("generate_secrets_bootstrap", GenerateSecretsBootstrap) # Show the YAML formatted secrets_bootstrap in a decrypted form manager.add_command("decrypt_secrets_bootstrap", DecryptSecretsBootstrap) # Create dynamodb tables
def test_diff_credential(mocker, credential): app = create_app() mocker.patch('confidant.settings.USE_AUTH', False) mocker.patch( 'confidant.routes.credentials.authnz.get_logged_in_user', return_value='*****@*****.**', ) mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=False, ) ret = app.test_client().get( '/v1/credentials/1234/1/2', follow_redirects=False, ) assert ret.status_code == 403 mocker.patch( 'confidant.routes.credentials.acl_module_check', return_value=True, ) mocker.patch( 'confidant.routes.credentials.Credential.get', return_value=credential, ) mocker.patch( ('confidant.routes.credentials.Credential' '._get_decrypted_credential_pairs'), return_value={'test': 'me'}, ) ret = app.test_client().get( '/v1/credentials/1234/1/2', follow_redirects=False, ) assert ret.status_code == 400 credential.data_type = 'archive-credential' ret = app.test_client().get( '/v1/credentials/1234/1/2', follow_redirects=False, ) json_data = json.loads(ret.data) assert ret.status_code == 200 assert json_data == {} mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=DoesNotExist(), ) ret = app.test_client().get( '/v1/credentials/1234/1/2', follow_redirects=False, ) assert ret.status_code == 404 mocker.patch( 'confidant.routes.credentials.Credential.get', side_effect=[credential, DoesNotExist()], ) ret = app.test_client().get( '/v1/credentials/1234/1/2', follow_redirects=False, ) assert ret.status_code == 404