-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ftr] add roleScopedSupertest service for deployment-agnostic tests (#…
…190279) ## Summary Adding new service that acts as a wrapper of `supertestWithoutAuth` service authenticated with role-based API key and enriched with request headers. The proposed change streamlines test design by centralizing the management of API key and internal/common headers, eliminating the need to pass these arguments individually in every API call. This approach reduces code duplication and enhances maintainability Before: ```ts const samlAuth = getService('samlAuth'); const supertestWithoutAuth = getService('supertestWithoutAuth'); const roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin'); const internalHeaders = samlAuth.getInternalRequestHeader(); await supertestWithoutAuth .get('/api/console/api_server') .set(roleAuthc.apiKeyHeader) .set(internalHeaders) .set('kbn-xsrf', 'true') .expect(200); ``` After: ```ts const roleScopedSupertest = getService('roleScopedSupertest'); const supertestWithAdminScope = await roleScopedSupertest.getSupertestWithRoleScope('admin', { withInternalHeaders: true, withCustomHeaders: {'kbn-xsrf': 'true'}, }); await supertestWithAdminScope .get('/api/console/api_server') .expect(200); ``` Use this service to easily test API endpoints with role-specific authorization and custom headers, both in serverless and stateful environments. closes #190228 --------- Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
- Loading branch information
1 parent
a13f8d9
commit 96d3325
Showing
7 changed files
with
165 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
x-pack/test/api_integration/deployment_agnostic/services/role_scoped_supertest.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { | ||
RoleCredentials, | ||
SupertestWithoutAuthProviderType, | ||
SamlAuthProviderType, | ||
} from '@kbn/ftr-common-functional-services'; | ||
import { Test } from 'supertest'; | ||
import { DeploymentAgnosticFtrProviderContext } from '../ftr_provider_context'; | ||
|
||
export interface RequestHeadersOptions { | ||
withInternalHeaders?: boolean; | ||
withCommonHeaders?: boolean; | ||
withCustomHeaders?: Record<string, string>; | ||
} | ||
|
||
export class SupertestWithRoleScope { | ||
private roleAuthc: RoleCredentials | null; | ||
private readonly supertestWithoutAuth: SupertestWithoutAuthProviderType; | ||
private samlAuth: SamlAuthProviderType; | ||
private readonly options: RequestHeadersOptions; | ||
|
||
constructor( | ||
roleAuthc: RoleCredentials, | ||
supertestWithoutAuth: SupertestWithoutAuthProviderType, | ||
samlAuth: SamlAuthProviderType, | ||
options: RequestHeadersOptions | ||
) { | ||
this.roleAuthc = roleAuthc; | ||
this.supertestWithoutAuth = supertestWithoutAuth; | ||
this.samlAuth = samlAuth; | ||
this.options = options; | ||
} | ||
|
||
async destroy() { | ||
if (this.roleAuthc) { | ||
await this.samlAuth.invalidateM2mApiKeyWithRoleScope(this.roleAuthc); | ||
this.roleAuthc = null; | ||
} | ||
} | ||
|
||
private addHeaders(agent: Test): Test { | ||
const { withInternalHeaders, withCommonHeaders, withCustomHeaders } = this.options; | ||
|
||
if (!this.roleAuthc) { | ||
throw new Error('The instance has already been destroyed.'); | ||
} | ||
// set role-based API key by default | ||
agent.set(this.roleAuthc.apiKeyHeader); | ||
|
||
if (withInternalHeaders) { | ||
agent.set(this.samlAuth.getInternalRequestHeader()); | ||
} | ||
|
||
if (withCommonHeaders) { | ||
agent.set(this.samlAuth.getCommonRequestHeader()); | ||
} | ||
|
||
if (withCustomHeaders) { | ||
agent.set(withCustomHeaders); | ||
} | ||
|
||
return agent; | ||
} | ||
|
||
private request(method: 'post' | 'get' | 'put' | 'delete', url: string): Test { | ||
if (!this.roleAuthc) { | ||
throw new Error('Instance has been destroyed and cannot be used for making requests.'); | ||
} | ||
const agent = this.supertestWithoutAuth[method](url); | ||
return this.addHeaders(agent); | ||
} | ||
|
||
post(url: string) { | ||
return this.request('post', url); | ||
} | ||
|
||
get(url: string) { | ||
return this.request('get', url); | ||
} | ||
|
||
put(url: string) { | ||
return this.request('put', url); | ||
} | ||
|
||
delete(url: string) { | ||
return this.request('delete', url); | ||
} | ||
} | ||
|
||
/** | ||
* Provides a customized 'supertest' instance that is authenticated using a role-based API key | ||
* and enriched with the appropriate request headers. This service allows you to perform | ||
* HTTP requests with specific authentication and header configurations, ensuring that | ||
* the requests are scoped to the provided role and environment. | ||
* | ||
* Use this service to easily test API endpoints with role-specific authorization and | ||
* custom headers, both in serverless and stateful environments. | ||
*/ | ||
export function RoleScopedSupertestProvider({ getService }: DeploymentAgnosticFtrProviderContext) { | ||
const supertestWithoutAuth = getService('supertestWithoutAuth'); | ||
const samlAuth = getService('samlAuth'); | ||
|
||
return { | ||
async getSupertestWithRoleScope( | ||
role: string, | ||
options: RequestHeadersOptions = { | ||
withCommonHeaders: false, | ||
withInternalHeaders: false, | ||
} | ||
) { | ||
const roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope(role); | ||
return new SupertestWithRoleScope(roleAuthc, supertestWithoutAuth, samlAuth, options); | ||
}, | ||
}; | ||
} |