Skip to content

Commit

Permalink
[core] get headers from fakeRequest in secondary user client (elastic…
Browse files Browse the repository at this point in the history
…#192394)

## Summary

Closes elastic#192004

Calling `client.asSecondaryAuthUser` from a client scoped to a fake
request instantiated with `getKibanaFakeRequest` returns the following
error:
`Error: asSecondaryAuthUser called from a client scoped to a request
without 'authorization' header.`.

This is because we use the same branch when dealing with a real or fake
request and expect the headers to be cached. There are existing tests to
verify a fake request works but these requests are raw objects not
created through `getKibanaFakeRequest`

### Testing
This snippet does not throw
```
const fakeRequest = getFakeKibanaRequest({ id: apiKey.id, api_key: apiKey.apiKey });
const esClient = server.core.elasticsearch.client.asScoped(fakeRequest).asSecondaryAuthUser;
```

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
klacabane and kibanamachine authored Sep 13, 2024
1 parent f6c8a2e commit 0987f70
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,43 @@ describe('ClusterClient', () => {
);
});

it('uses the authorization header from the request when using a `KibanaFakeRequest`', () => {
const config = createConfig({
requestHeadersWhitelist: ['authorization', 'foo'],
});
authHeaders.get.mockReturnValue({
[AUTHORIZATION_HEADER]: 'will_not_be_used',
});

const clusterClient = new ClusterClient({
config,
logger,
type: 'custom-type',
authHeaders,
agentFactoryProvider,
kibanaVersion,
});

const request = httpServerMock.createFakeKibanaRequest({
headers: {
authorization: 'fake_request_auth',
},
});

const scopedClusterClient = clusterClient.asScoped(request);
// trigger client instantiation via getter
client = scopedClusterClient.asSecondaryAuthUser;

expect(internalClient.child).toHaveBeenCalledTimes(1);
expect(internalClient.child).toHaveBeenCalledWith(
expect.objectContaining({
headers: expect.objectContaining({
[ES_SECONDARY_AUTH_HEADER]: request.headers.authorization,
}),
})
);
});

it('throws when used with a `FakeRequest` without authorization header', () => {
const config = createConfig({
requestHeadersWhitelist: ['authorization', 'foo'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,10 @@ export class ClusterClient implements ICustomClusterClient {
}

private getSecondaryAuthHeaders(request: ScopeableRequest): Headers {
const headerSource = isRealRequest(request)
? this.authHeaders?.get(request) ?? {}
: request.headers;
const headerSource =
isRealRequest(request) && !request.isFakeRequest
? this.authHeaders?.get(request) ?? {}
: request.headers;
const authorizationHeader = Object.entries(headerSource).find(([key, value]) => {
return key.toLowerCase() === AUTHORIZATION_HEADER && value !== undefined;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,19 @@ function createKibanaRequestMock<P = any, Q = any, B = any>({
);
}

function createFakeKibanaRequestMock({
headers = { accept: 'something/html' },
}: {
headers?: Record<string, string>;
}): KibanaRequest {
const fakeRequest = {
headers,
path: '/',
};

return CoreKibanaRequest.from(fakeRequest);
}

const createResponseFactoryMock = (): jest.Mocked<KibanaResponseFactory> => ({
ok: jest.fn(),
created: jest.fn(),
Expand All @@ -140,5 +153,6 @@ const createResponseFactoryMock = (): jest.Mocked<KibanaResponseFactory> => ({
export const mockRouter = {
create: createRouterMock,
createKibanaRequest: createKibanaRequestMock,
createFakeKibanaRequest: createFakeKibanaRequestMock,
createResponseFactory: createResponseFactoryMock,
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const createToolkitMock = (): ToolkitMock => {

export const httpServerMock = {
createKibanaRequest: mockRouter.createKibanaRequest,
createFakeKibanaRequest: mockRouter.createFakeKibanaRequest,
createRawRequest: hapiMocks.createRequest,
createResponseFactory: mockRouter.createResponseFactory,
createLifecycleResponseFactory: createLifecycleResponseFactoryMock,
Expand Down

0 comments on commit 0987f70

Please sign in to comment.