def setUpClass(cls): """Use the ServerManager class to launch a vault server process.""" config_paths = [get_config_file_path('vault-tls.hcl')] if distutils.spawn.find_executable('consul') is None and cls.enable_vault_ha: logging.warning('Unable to run Vault in HA mode, consul binary not found in path.') cls.enable_vault_ha = False if is_enterprise(): # TODO: figure out why this bit isn't working logging.warning('Unable to run Vault in HA mode, enterprise Vault version not currently supported.') cls.enable_vault_ha = False if cls.enable_vault_ha: config_paths = [ get_config_file_path('vault-ha-node1.hcl'), get_config_file_path('vault-ha-node2.hcl'), ] cls.manager = ServerManager( config_paths=config_paths, client=create_client(), use_consul=cls.enable_vault_ha, ) try: cls.manager.start() cls.manager.initialize() cls.manager.unseal() except Exception: cls.manager.stop() raise
def doctest_global_setup(): client = test_utils.create_client() manager = ServerManager( config_paths=[test_utils.get_config_file_path('vault-doctest.hcl')], client=client, ) manager.start() manager.initialize() manager.unseal() mocker = Mocker(real_http=True) mocker.start() auth_method_paths = [ 'ldap/login/{}'.format(MockLdapServer.ldap_user_name), ] for auth_method_path in auth_method_paths: mock_url = 'https://127.0.0.1:8200/v1/auth/{path}'.format( path=auth_method_path) mock_response = { "auth": { "client_token": manager.root_token, "accessor": "0e9e354a-520f-df04-6867-ee81cae3d42d", "policies": ['default'], "lease_duration": 2764800, "renewable": True, }, } mocker.register_uri( method='POST', url=mock_url, json=mock_response, ) client.token = manager.root_token os.environ['VAULT_TOKEN'] = manager.root_token os.environ['REQUESTS_CA_BUNDLE'] = test_utils.get_config_file_path( 'server-cert.pem') os.environ['LDAP_USERNAME'] = MockLdapServer.ldap_user_name os.environ['LDAP_PASSWORD'] = MockLdapServer.ldap_user_password os.environ['AWS_LAMBDA_FUNCTION_NAME'] = 'hvac-lambda' os.environ.setdefault("LDAP_PASSWORD", MockLdapServer.ldap_user_password) if 'secret/' not in client.sys.list_mounted_secrets_engines()['data']: client.sys.enable_secrets_engine( backend_type='kv', path='secret', options=dict(version=2), ) attempts = 0 while attempts < 25 and 'secret/' not in client.sys.list_mounted_secrets_engines( )['data']: attempts += 1 logging.debug( 'Waiting 1 second for KV V2 secrets engine under path {path} to become available...' .format(path='secret', )) sleep(1) return manager
def stop(self): """Stop the vault server process being managed by this class.""" for process_num, process in enumerate(self._processes): logger.debug('Terminating vault server with PID {pid}'.format(pid=process.pid)) if process.poll() is None: process.kill() if os.getenv('HVAC_OUTPUT_VAULT_STDERR', False): stdout_lines, stderr_lines = process.communicate() stderr_filename = 'vault{num}_stderr.log'.format(num=process_num) with open(get_config_file_path(stderr_filename), 'w') as f: logger.debug(stderr_lines.decode()) f.writelines(stderr_lines.decode()) stdout_filename = 'vault{num}_stdout.log'.format(num=process_num) with open(get_config_file_path(stdout_filename), 'w') as f: logger.debug(stdout_lines.decode()) f.writelines(stdout_lines.decode())
def test_create_kubernetes_configuration(self): expected_status_code = 204 test_mount_point = 'k8s' # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() response = self.client.create_kubernetes_configuration( kubernetes_host='127.0.0.1:80', pem_keys=[certificate], mount_point=test_mount_point, ) self.assertEqual( first=expected_status_code, second=response.status_code, ) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def test_auth_ec2_alternate_mount_point_with_no_client_token(self): test_mount_point = 'aws-custom-path' # Turn on the aws-ec2 backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('aws-ec2', mount_point=test_mount_point) # Drop the client's token to replicate a typical end user's use of any auth method. # I.e., its reasonable to expect the method is being called to _retrieve_ a token in the first place. self.client.token = None # Load a mock PKCS7 encoded self-signed certificate to stand in for a real document from the AWS identity service. with open(utils.get_config_file_path('identity_document.p7b')) as fp: pkcs7 = fp.read() # If our custom path is respected, we'll still end up with Vault's inability to decrypt our dummy PKCS7 string. # However this exception indicates we're correctly hitting the expected auth endpoint. with self.assertRaises( exceptions.InternalServerError) as assertRaisesContext: self.client.auth_ec2(pkcs7=pkcs7, mount_point=test_mount_point) expected_exception_message = 'failed to decode the PEM encoded PKCS#7 signature' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset test state. self.client.token = self.manager.root_token self.client.disable_auth_backend(mount_point=test_mount_point)
def test_auth_gcp_alternate_mount_point_with_no_client_token_exception( self): test_mount_point = 'gcp-custom-path' # Turn on the gcp backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('gcp', mount_point=test_mount_point) # Drop the client's token to replicate a typical end user's use of any auth method. # I.e., its reasonable to expect the method is being called to _retrieve_ a token in the first place. self.client.token = None # Load a mock JWT stand in for a real document from GCP. with open(utils.get_config_file_path('example.jwt')) as fp: jwt = fp.read() # When attempting to auth (POST) to an auth backend mounted at a different path than the default, we expect a # generic 'missing client token' response from Vault. with self.assertRaises( exceptions.InvalidRequest) as assertRaisesContext: self.client.auth.gcp.login('example-role', jwt) expected_exception_message = 'missing client token' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset test state. self.client.token = self.manager.root_token self.client.disable_auth_backend(mount_point=test_mount_point)
def test_get_kubernetes_configuration(self): test_host = '127.0.0.1:80' test_mount_point = 'k8s' # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.create_kubernetes_configuration( kubernetes_host=test_host, pem_keys=[certificate], mount_point=test_mount_point, ) # Test that we can retrieve the configuration response = self.client.get_kubernetes_configuration( mount_point=test_mount_point ) self.assertIn( member='data', container=response, ) self.assertEquals( first=test_host, second=response['data'].get('kubernetes_host') ) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def test_create_kubernetes_role(self): test_role_name = 'test_role' test_mount_point = 'k8s' expected_status_code = 204 # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.create_kubernetes_configuration( kubernetes_host='127.0.0.1:80', pem_keys=[certificate], mount_point=test_mount_point, ) # Test that we can createa role response = self.client.create_kubernetes_role( name=test_role_name, bound_service_account_names='*', bound_service_account_namespaces='vault_test', mount_point=test_mount_point, ) self.assertEqual( first=expected_status_code, second=response.status_code, ) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def test_auth_gcp_alternate_mount_point_with_no_client_token_exception(self): test_mount_point = 'gcp-custom-path' # Turn on the gcp backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('gcp', mount_point=test_mount_point) # Drop the client's token to replicate a typical end user's use of any auth method. # I.e., its reasonable to expect the method is being called to _retrieve_ a token in the first place. self.client.token = None # Load a mock JWT stand in for a real document from GCP. with open(utils.get_config_file_path('example.jwt')) as fp: jwt = fp.read() # When attempting to auth (POST) to an auth backend mounted at a different path than the default, we expect a # generic 'missing client token' response from Vault. with self.assertRaises(exceptions.InvalidRequest) as assertRaisesContext: self.client.auth.gcp.login('example-role', jwt) expected_exception_message = 'missing client token' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset test state. self.client.token = self.manager.root_token self.client.disable_auth_backend(mount_point=test_mount_point)
def test_create_kubernetes_role(self): test_role_name = 'test_role' test_mount_point = 'k8s' expected_status_code = 204 # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.create_kubernetes_configuration( kubernetes_host='127.0.0.1:80', pem_keys=[certificate], mount_point=test_mount_point, ) # Test that we can createa role response = self.client.create_kubernetes_role( name=test_role_name, bound_service_account_names='*', bound_service_account_namespaces='vault_test', mount_point=test_mount_point, ) self.assertEqual( first=expected_status_code, second=response.status_code, ) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def test_auth_ec2_alternate_mount_point_with_no_client_token(self): test_mount_point = 'aws-custom-path' # Turn on the aws-ec2 backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('aws-ec2', mount_point=test_mount_point) # Drop the client's token to replicate a typical end user's use of any auth method. # I.e., its reasonable to expect the method is being called to _retrieve_ a token in the first place. self.client.token = None # Load a mock PKCS7 encoded self-signed certificate to stand in for a real document from the AWS identity service. with open(utils.get_config_file_path('identity_document.p7b')) as fp: pkcs7 = fp.read() # If our custom path is respected, we'll still end up with Vault's inability to decrypt our dummy PKCS7 string. # However this exception indicates we're correctly hitting the expected auth endpoint. with self.assertRaises(exceptions.InternalServerError) as assertRaisesContext: self.client.auth_ec2(pkcs7=pkcs7, mount_point=test_mount_point) expected_exception_message = 'failed to decode the PEM encoded PKCS#7 signature' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset test state. self.client.token = self.manager.root_token self.client.disable_auth_backend(mount_point=test_mount_point)
def test_auth_ec2_alternate_mount_point_with_no_client_token_exception(self): test_mount_point = 'aws-custom-path' # Turn on the aws-ec2 backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('aws-ec2', mount_point=test_mount_point) # Drop the client's token to replicate a typical end user's use of any auth method. # I.e., its reasonable to expect the method is being called to _retrieve_ a token in the first place. self.client.token = None # Load a mock PKCS7 encoded self-signed certificate to stand in for a real document from the AWS identity service. with open(utils.get_config_file_path('identity_document.p7b')) as fp: pkcs7 = fp.read() # When attempting to auth (POST) to an auth backend mounted at a different path than the default, we expect a # generic 'missing client token' response from Vault. with self.assertRaises(exceptions.InvalidRequest) as assertRaisesContext: self.client.auth_ec2(pkcs7=pkcs7) expected_exception_message = 'missing client token' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset test state. self.client.token = self.manager.root_token self.client.disable_auth_backend(mount_point=test_mount_point)
def test_auth_ec2_alternate_mount_point_with_no_client_token_exception( self): test_mount_point = 'aws-custom-path' # Turn on the aws-ec2 backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('aws-ec2', mount_point=test_mount_point) # Drop the client's token to replicate a typical end user's use of any auth method. # I.e., its reasonable to expect the method is being called to _retrieve_ a token in the first place. self.client.token = None # Load a mock PKCS7 encoded self-signed certificate to stand in for a real document from the AWS identity service. with open(utils.get_config_file_path('identity_document.p7b')) as fp: pkcs7 = fp.read() # When attempting to auth (POST) to an auth backend mounted at a different path than the default, we expect a # generic 'missing client token' response from Vault. with self.assertRaises( exceptions.InvalidRequest) as assertRaisesContext: self.client.auth_ec2(pkcs7=pkcs7) expected_exception_message = 'missing client token' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset test state. self.client.token = self.manager.root_token self.client.disable_auth_backend(mount_point=test_mount_point)
def test_get_kubernetes_configuration(self): test_host = '127.0.0.1:80' test_mount_point = 'k8s' # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.create_kubernetes_configuration( kubernetes_host=test_host, pem_keys=[certificate], mount_point=test_mount_point, ) # Test that we can retrieve the configuration response = self.client.get_kubernetes_configuration( mount_point=test_mount_point) self.assertIn( member='data', container=response, ) self.assertEquals(first=test_host, second=response['data'].get('kubernetes_host')) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def stop(self): """Stop the vault server process being managed by this class.""" for process_num, process in enumerate(self._processes): process.kill() if os.getenv('HVAC_OUTPUT_VAULT_STDERR', False): _, stderr_lines = process.communicate() stderr_filename = 'vault{num}_stderr.log'.format(num=process_num) with open(get_config_file_path(stderr_filename), 'w') as f: f.writelines(stderr_lines)
def test_auth_kubernetes(self): test_role_name = 'test_role' test_host = '127.0.0.1:80' test_mount_point = 'k8s' # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format( test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.create_kubernetes_configuration( kubernetes_host=test_host, pem_keys=[certificate], mount_point=test_mount_point, ) self.client.create_kubernetes_role( name=test_role_name, bound_service_account_names='*', bound_service_account_namespaces='vault_test', mount_point=test_mount_point, ) # Test that we can authenticate with open(utils.get_config_file_path('example.jwt')) as fp: test_jwt = fp.read() with self.assertRaises( exceptions.InternalServerError) as assertRaisesContext: # we don't actually have a valid JWT to provide, so this method will throw an exception self.client.auth_kubernetes( role=test_role_name, jwt=test_jwt, mount_point=test_mount_point, ) expected_exception_message = 'claim "iss" is invalid' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def setUpClass(cls): """Use the ServerManager class to launch a vault server process.""" config_paths = [get_config_file_path('vault-tls.hcl')] if distutils.spawn.find_executable('consul') is None and cls.enable_vault_ha: logging.warning('Unable to run Vault in HA mode, consul binary not found in path.') cls.enable_vault_ha = False if cls.enable_vault_ha: config_paths = [ get_config_file_path('vault-ha-node1.hcl'), get_config_file_path('vault-ha-node2.hcl'), ] cls.manager = ServerManager( config_paths=config_paths, client=create_client(), use_consul=cls.enable_vault_ha, ) cls.manager.start() cls.manager.initialize() cls.manager.unseal()
def test_tls_auth(self): self.client.enable_auth_backend('cert') with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.write('auth/cert/certs/test', display_name='test', policies='not_root', certificate=certificate) self.client.auth_tls()
def stop(self): """Stop the vault server process being managed by this class.""" for process_num, process in enumerate(self._processes): process.kill() if os.getenv('HVAC_OUTPUT_VAULT_STDERR', False): _, stderr_lines = process.communicate() stderr_filename = 'vault{num}_stderr.log'.format( num=process_num) with open(get_config_file_path(stderr_filename), 'w') as f: f.writelines(stderr_lines)
def test_submit_ca_information(self, label, raises=False, exception_message=''): pem_bundle = '{ca_key}{ca_crt}'.format( ca_key=''.join( open(utils.get_config_file_path('ca-key.pem')).readlines()), ca_crt=''.join( open(utils.get_config_file_path('ca-cert.pem')).readlines()), ) submit_ca_information_response = self.client.secrets.pki.submit_ca_information( pem_bundle=pem_bundle, mount_point=self.TEST_MOUNT_POINT, ) logging.debug('submit_ca_information_response: %s' % submit_ca_information_response) self.assertEqual( first=submit_ca_information_response.status_code, second=204, )
def test_auth_kubernetes(self): test_role_name = 'test_role' test_host = '127.0.0.1:80' test_mount_point = 'k8s' # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.create_kubernetes_configuration( kubernetes_host=test_host, pem_keys=[certificate], mount_point=test_mount_point, ) self.client.create_kubernetes_role( name=test_role_name, bound_service_account_names='*', bound_service_account_namespaces='vault_test', mount_point=test_mount_point, ) # Test that we can authenticate with open(utils.get_config_file_path('example.jwt')) as fp: test_jwt = fp.read() with self.assertRaises(exceptions.InternalServerError) as assertRaisesContext: # we don't actually have a valid JWT to provide, so this method will throw an exception self.client.auth_kubernetes( role=test_role_name, jwt=test_jwt, mount_point=test_mount_point, ) expected_exception_message = 'claim "iss" is invalid' actual_exception_message = str(assertRaisesContext.exception) self.assertEqual(expected_exception_message, actual_exception_message) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def test_tls_auth(self): self.client.enable_auth_backend('cert') with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() self.client.write('auth/cert/certs/test', display_name='test', policies='not_root', certificate=certificate) self.client.auth_tls()
def test_sign_self_issued(self, label, raises=False, exception_message=''): sign_self_issued_response = self.client.secrets.pki.sign_self_issued( certificate=''.join( open(utils.get_config_file_path('ca-cert.pem')).readlines()), mount_point=self.TEST_MOUNT_POINT, ) logging.debug('sign_self_issued_response: %s' % sign_self_issued_response) self.assertEqual( first=sign_self_issued_response.status_code, second=200, )
def setUpClass(cls): """Use the ServerManager class to launch a vault server process.""" config_paths = [get_config_file_path('vault-tls.hcl')] if distutils.spawn.find_executable( 'consul') is None and cls.enable_vault_ha: logging.warning( 'Unable to run Vault in HA mode, consul binary not found in path.' ) cls.enable_vault_ha = False if cls.enable_vault_ha: config_paths = [ get_config_file_path('vault-ha-node1.hcl'), get_config_file_path('vault-ha-node2.hcl'), ] cls.manager = ServerManager( config_paths=config_paths, client=create_client(), use_consul=cls.enable_vault_ha, ) cls.manager.start() cls.manager.initialize() cls.manager.unseal()
def test_sign_verbatim(self, label, raises=False, exception_message=''): name = self.TEST_ROLE sign_verbatim_response = self.client.secrets.pki.sign_verbatim( csr=''.join( open(utils.get_config_file_path( 'server-cert.csr')).readlines()), name=name, mount_point=self.TEST_MOUNT_POINT, ) logging.debug('sign_verbatim_response: %s' % sign_verbatim_response) self.assertEqual( first=sign_verbatim_response.status_code, second=200, )
def test_configure(self, label, issuer): oidc_discovery_url = '{issuer}/v1/identity/oidc'.format(issuer=issuer) self.client.secrets.identity.configure_tokens_backend( issuer=issuer, ) response = self.client.auth.oidc.configure( oidc_discovery_url=oidc_discovery_url, oidc_discovery_ca_pem=''.join(open(utils.get_config_file_path('server-cert.pem')).readlines()), path=self.TEST_OIDC_PATH, ) logging.debug('configure response: %s' % response) self.assertEqual( first=204, second=response.status_code, )
def test_sign_certificate(self, label, raises=False, exception_message=''): name = self.TEST_ROLE common_name = 'another.example.com' sign_certificate_response = self.client.secrets.pki.sign_certificate( name=name, csr=''.join( open(utils.get_config_file_path( 'server-cert.csr')).readlines()), common_name=common_name, mount_point=self.TEST_MOUNT_POINT, ) logging.debug('sign_certificate_response: %s' % sign_certificate_response) self.assertEqual( first=bool(sign_certificate_response), second=True, )
def test_read_config(self, label, issuer): oidc_discovery_url = '{issuer}/v1/identity/oidc'.format(issuer=issuer) self.client.secrets.identity.configure_tokens_backend(issuer=issuer, ) configure_response = self.client.auth.jwt.configure( oidc_discovery_url=oidc_discovery_url, oidc_discovery_ca_pem=''.join( open(utils.get_config_file_path( 'server-cert.pem')).readlines()), path=self.TEST_JWT_PATH, ) logging.debug('configure response: %s' % configure_response) response = self.client.auth.jwt.read_config(path=self.TEST_JWT_PATH, ) logging.debug('read_config response: %s' % response) self.assertEqual( first=oidc_discovery_url, second=response['data']['oidc_discovery_url'], )
def build_dummy_pack_config(self, url="https://localhost:8200"): # based on create_client() in hvac/tests/utils/__init__.py server_cert_path = get_config_file_path("server-cert.pem") token_result = self.client.create_token(lease=self.default_token_lease) token = token_result["auth"]["client_token"] dummy_pack_config = { "url": url, # pack config | relation | hvac.Client() # ------------|----------|-------------- # cert | != | cert # cert+verify | == | verify "cert": server_cert_path, "verify": True, "auth_method": "token", "token": token, "role_id": None, "secret_id": None, } return dummy_pack_config
def test_create_kubernetes_configuration(self): expected_status_code = 204 test_mount_point = 'k8s' # Turn on the kubernetes backend with a custom mount_point path specified. if '{0}/'.format(test_mount_point) in self.client.list_auth_backends()['data']: self.client.disable_auth_backend(test_mount_point) self.client.enable_auth_backend('kubernetes', mount_point=test_mount_point) with open(utils.get_config_file_path('client-cert.pem')) as fp: certificate = fp.read() response = self.client.create_kubernetes_configuration( kubernetes_host='127.0.0.1:80', pem_keys=[certificate], mount_point=test_mount_point, ) self.assertEqual( first=expected_status_code, second=response.status_code, ) # Reset integration test state self.client.disable_auth_backend(mount_point=test_mount_point)
def test_oidc_callback(self, label, role_name, allowed_redirect_uris, user_claim): self.oidc_server = MockOauthProviderServerThread() self.oidc_server.start() oidc_details = create_user_session_and_client( server_url=self.oidc_server.url, oauth_redirect_uri=allowed_redirect_uris[0], ) response = self.client.auth.oidc.configure( oidc_discovery_url=oidc_details['discovery_url'], oidc_response_mode='form_post', oidc_response_types=['code'], oidc_discovery_ca_pem=''.join(open(utils.get_config_file_path('server-cert.pem')).readlines()), oidc_client_id=oidc_details['client_id'], oidc_client_secret=oidc_details['client_secret'], path=self.TEST_OIDC_PATH, ) logging.debug('oidc.configure response: %s' % response) create_role_response = self.client.auth.oidc.create_role( name=role_name, role_type='oidc', allowed_redirect_uris=allowed_redirect_uris, user_claim=user_claim, verbose_oidc_logging=True, path=self.TEST_OIDC_PATH, ) logging.debug('create_role_response: %s' % create_role_response) oidc_authorization_url_response = self.client.auth.oidc.oidc_authorization_url_request( role=role_name, redirect_uri=allowed_redirect_uris[0], path=self.TEST_OIDC_PATH, ) logging.debug('oidc_authorization_url_request response: %s' % oidc_authorization_url_response) auth_url = oidc_authorization_url_response['data']['auth_url'] logging.debug('auth_url: %s' % auth_url) auth_url_qs = urlparse(auth_url).query auth_url_qs_parsed = parse_qs(auth_url_qs) logging.debug('auth_url_qs_parsed: %s' % auth_url_qs_parsed) authorize_response = oidc_details['session'].get( url=auth_url, ) logging.debug('authorize_response: %s' % authorize_response.json()) authorization = authorize_response.json() logging.debug('authorization: %s' % authorization) client_cert_path = utils.get_config_file_path('client-cert.pem') client_key_path = utils.get_config_file_path('client-key.pem') server_cert_path = utils.get_config_file_path('server-cert.pem') response = oidc_details['session'].post( url=auth_url, cert=(client_cert_path, client_key_path), verify=server_cert_path, data=dict(confirm=True), ) oidc_auth_data = response.json() logging.debug('oidc_auth_data: %s' % oidc_auth_data) self.client.token = oidc_auth_data['auth']['client_token'] self.assertIn( member=role_name, container=self.client.lookup_token()['data']['meta']['role'], )
def test_oidc_authorization_url_request(self, label, issuer, role_name, allowed_redirect_uris, user_claim): if '%s/' % self.TEST_APPROLE_PATH not in self.client.sys.list_auth_methods(): self.client.sys.enable_auth_method( method_type='approle', path=self.TEST_APPROLE_PATH, ) id_token_role_name = 'hvac-oidc-test' key_name = 'oidc-test-key' create_or_update_role_response = self.client.secrets.identity.create_or_update_role( name=id_token_role_name, key=key_name, ) logging.debug('create_or_update_role response: %s' % create_or_update_role_response) read_role_response = self.client.secrets.identity.read_role( name=id_token_role_name, ) logging.debug('read_role response: %s' % read_role_response) token_client_id = read_role_response['data']['client_id'] create_named_key_response = self.client.secrets.identity.create_named_key( name=key_name, allowed_client_ids=[ token_client_id, ], ) logging.debug('create_named_key response: %s' % create_named_key_response) # Log in using a dummy approle role so our client token has an associated identity self.login_using_admin_approle_role( role_id=self.TEST_APPROLE_ROLE_ID, path=self.TEST_APPROLE_PATH, ) generate_token_response = self.client.secrets.identity.generate_signed_id_token( name=id_token_role_name, ) logging.debug('generate_token_response: %s' % generate_token_response) oidc_discovery_url = '{issuer}/v1/identity/oidc'.format(issuer=issuer) self.client.secrets.identity.configure_tokens_backend( issuer=issuer, ) response = self.client.auth.oidc.configure( oidc_discovery_url=oidc_discovery_url, oidc_discovery_ca_pem=''.join(open(utils.get_config_file_path('server-cert.pem')).readlines()), oidc_client_id=self.oidc_client_id, oidc_client_secret=generate_token_response['data']['token'], path=self.TEST_OIDC_PATH, ) logging.debug('configure response: %s' % response) create_role_response = self.client.auth.oidc.create_role( name=role_name, allowed_redirect_uris=allowed_redirect_uris, user_claim=user_claim, path=self.TEST_OIDC_PATH, ) logging.debug('create_role_response: %s' % create_role_response) response = self.client.auth.oidc.oidc_authorization_url_request( role=role_name, redirect_uri=allowed_redirect_uris[0], path=self.TEST_OIDC_PATH, ) logging.debug('oidc_authorization_url_request response: %s' % response) self.assertIn( member='?client_id={client_id}'.format(client_id=self.oidc_client_id), container=response['data']['auth_url'], )
def test_jwt_login(self, label, issuer, role_name, allowed_redirect_uris, user_claim): if '%s/' % self.TEST_APPROLE_PATH not in self.client.sys.list_auth_methods( ): self.client.sys.enable_auth_method( method_type='approle', path=self.TEST_APPROLE_PATH, ) id_token_role_name = 'hvac-jwt-test' key_name = 'jwt-test-key' create_named_key_response = self.client.secrets.identity.create_named_key( name=key_name, ) logging.debug('create_named_key response: %s' % create_named_key_response) create_or_update_role_response = self.client.secrets.identity.create_or_update_role( name=id_token_role_name, key=key_name, ) logging.debug('create_or_update_role response: %s' % create_or_update_role_response) read_role_response = self.client.secrets.identity.read_role( name=id_token_role_name, ) logging.debug('read_role response: %s' % read_role_response) token_client_id = read_role_response['data']['client_id'] create_named_key_response = self.client.secrets.identity.create_named_key( name=key_name, allowed_client_ids=[ token_client_id, ], ) logging.debug('create_named_key response: %s' % create_named_key_response) self.client.secrets.identity.configure_tokens_backend( issuer='https://localhost:8200', ) response = self.client.auth.jwt.configure( jwks_url='https://localhost:8200/v1/identity/oidc/.well-known/keys', jwks_ca_pem=''.join( open(utils.get_config_file_path( 'server-cert.pem')).readlines()), path=self.TEST_JWT_PATH, ) logging.debug('configure response: %s' % response) create_role_response = self.client.auth.jwt.create_role( name=role_name, role_type='jwt', allowed_redirect_uris=allowed_redirect_uris, user_claim=user_claim, bound_audiences=[token_client_id], path=self.TEST_JWT_PATH, ) logging.debug('create_role_response: %s' % create_role_response) # Log in using a dummy approle role so our client token has an associated identity self.login_using_admin_approle_role( role_id=self.TEST_APPROLE_ROLE_ID, path=self.TEST_APPROLE_PATH, ) generate_token_response = self.client.secrets.identity.generate_signed_id_token( name=id_token_role_name, ) logging.debug('generate_token_response: %s' % generate_token_response) read_well_known_configurations_response = self.client.secrets.identity.read_well_known_configurations( ) logging.debug('read_well_known_configurations_response: %s' % read_well_known_configurations_response) response = self.client.auth.jwt.jwt_login( role=role_name, jwt=generate_token_response['data']['token'], path=self.TEST_JWT_PATH, ) logging.debug('jwt_login response: %s' % response) self.client.token = response['auth']['client_token'] self.assertIn( member=role_name, container=self.client.lookup_token()['data']['meta']['role'], )
class TestCert(HvacIntegrationTestCase, TestCase): TEST_MOUNT_POINT = 'cert-test' TEST_ROLE_NAME = 'testrole' cert = utils.create_client()._adapter._kwargs.get('cert') with open(utils.get_config_file_path('client-cert.pem')) as fp: TEST_CERTIFICATE = fp.read() def setUp(self): super(TestCert, self).setUp() if '%s/' % self.TEST_MOUNT_POINT not in self.client.list_auth_backends(): self.client.enable_auth_backend( backend_type='cert', mount_point=self.TEST_MOUNT_POINT, ) _ = self.client.auth.cert.create_ca_certificate_role( name=self.TEST_ROLE_NAME, certificate=self.TEST_CERTIFICATE, mount_point=self.TEST_MOUNT_POINT, ) def tearDown(self): super(TestCert, self).tearDown() def test_create_ca_certificate_role(self): response = self.client.auth.cert.create_ca_certificate_role( name='testrole2', certificate=self.TEST_CERTIFICATE, mount_point=self.TEST_MOUNT_POINT, ) self.assertEqual( first=204, second=response.status_code ) def test_read_ca_certificate_role(self): response = self.client.auth.cert.read_ca_certificate_role( name=self.TEST_ROLE_NAME, mount_point=self.TEST_MOUNT_POINT, ) self.assertEqual( first=self.TEST_ROLE_NAME, second=response['data']['display_name'], ) def test_list_certificate_roles(self): response = self.client.auth.cert.list_certificate_roles( mount_point=self.TEST_MOUNT_POINT, ) self.assertEqual( first=response['data']['keys'], second=[self.TEST_ROLE_NAME] ) def test_delete_certificate_role(self): self.client.auth.cert.create_ca_certificate_role( name='testrole2', certificate=self.TEST_CERTIFICATE, mount_point=self.TEST_MOUNT_POINT, ) response = self.client.auth.cert.delete_certificate_role( name='testrole2', mount_point=self.TEST_MOUNT_POINT, ) self.assertEqual( first=204, second=response.status_code ) def test_configure_tls_certificate(self): response = self.client.auth.cert.configure_tls_certificate(mount_point=self.TEST_MOUNT_POINT) self.assertEqual( first=204, second=response.status_code ) def test_auth_tls_deprecation(self): # In order to raise this it is just easier to expect it to fail. with self.assertRaises(OSError): pytest.deprecated_call(Client().auth_tls()) @parameterized.expand([ (TEST_ROLE_NAME, "", cert[0], cert[1], TEST_MOUNT_POINT), ("", "", cert[0], cert[1], TEST_MOUNT_POINT), ("testrole2", "", cert[0], cert[1], TEST_MOUNT_POINT), ("", "", "bad cert", cert[1], TEST_MOUNT_POINT), ("", "bad ca", cert[0], cert[1], TEST_MOUNT_POINT), ("", True, cert[0], cert[1], TEST_MOUNT_POINT), ("", False, " ", " ", TEST_MOUNT_POINT) ]) def test_login(self, name, cacert, cert_pem, key_pem, mount_point): if cacert or "bad" in [cacert, cert_pem, key_pem]: with self.assertRaises(exceptions.ParamValidationError): self.client.auth.cert.login( name=name, cacert=cacert, cert_pem=cert_pem, mount_point=mount_point, ) # elif cacert: # with self.assertRaises(OSError): # self.client.auth.cert.login( # name=name, # cacert=cacert, # cert_pem=cert_pem, # mount_point=mount_point, # ) elif name != "" and name not in self.client.auth.cert.list_certificate_roles( mount_point=self.TEST_MOUNT_POINT, )['data']['keys']: with self.assertRaises(exceptions.InvalidRequest): with self.assertRaises(OSError): self.client.auth.cert.login( name=name, cacert=cacert, cert_pem=cert_pem, mount_point=mount_point, ) elif "/" not in cert_pem: with self.assertRaises(OSError): self.client.auth.cert.login( name=name, cacert=cacert, cert_pem=cert_pem, mount_point=mount_point, ) else: response = self.client.auth.cert.login( name=name, cacert=cacert, cert_pem=cert_pem, mount_point=mount_point, ) if name in [self.TEST_ROLE_NAME, ""] and (cacert, cert_pem, key_pem) == ("", self.cert[0], self.cert[1]): self.assertIsInstance(response, dict)
def get_keys(): with open(get_config_file_path('oidc_private.pem'), 'rb') as fh: signing_key = jwk.JWK.from_pem(fh.read())._public_params() return jsonify({'keys': [ signing_key, ]})
create_save_token_func) from authlib.oauth2.rfc6749.grants import \ AuthorizationCodeGrant as _AuthorizationCodeGrant from authlib.oidc.core import UserInfo from authlib.oidc.core.grants import OpenIDCode as _OpenIDCode from authlib.oidc.core.grants import OpenIDHybridGrant as _OpenIDHybridGrant from authlib.oidc.core.grants import \ OpenIDImplicitGrant as _OpenIDImplicitGrant from werkzeug.security import gen_salt from tests.utils import get_config_file_path from tests.utils.mock_oauth_provider.models import (OAuth2AuthorizationCode, OAuth2Client, OAuth2Token, User, db) JWT_CONFIG = { 'key': ''.join(open(get_config_file_path('oidc_private.pem')).readlines()), 'alg': 'RS256', 'exp': 3600, } def exists_nonce(nonce, req): exists = OAuth2AuthorizationCode.query.filter_by(client_id=req.client_id, nonce=nonce).first() return bool(exists) def generate_user_info(user, scope): return UserInfo(sub=str(user.id), name=user.username)