示例#1
0
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() == '*****@*****.**'
示例#2
0
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()
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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'
示例#7
0
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
示例#8
0
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
示例#9
0
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}
示例#10
0
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': '*****@*****.**'}
示例#11
0
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
示例#12
0
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
示例#13
0
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'] == '/'
示例#14
0
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
示例#15
0
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
示例#16
0
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() == '*****@*****.**'
示例#17
0
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'},
    }
示例#18
0
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
示例#19
0
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()
示例#20
0
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
示例#21
0
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
示例#22
0
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',
    }
示例#23
0
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
示例#24
0
def test_no_acl():
    app = create_app()
    with app.test_request_context('/fake'):
        assert rbac.no_acl(resource_type='service', action='update') is True
示例#25
0
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
示例#26
0
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
示例#27
0
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
示例#28
0
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
示例#29
0
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
示例#30
0
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