Skip to content

Commit

Permalink
Expose serverBasePath fixes elastic#45991 (elastic#45995)
Browse files Browse the repository at this point in the history
* Expose serverBasePath fixes elastic#45991

* Review comments

* Fix basepath mock types

* AppBasePathContract -> IBasePath

* Match basepath test description with assertion

* Fix eslint errors
  • Loading branch information
rudolf committed Sep 30, 2019
1 parent 3398b79 commit 837ee95
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 39 deletions.
13 changes: 13 additions & 0 deletions docs/development/core/server/kibana-plugin-server.basepath.get.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [BasePath](./kibana-plugin-server.basepath.md) &gt; [get](./kibana-plugin-server.basepath.get.md)

## BasePath.get property

returns `basePath` value, specific for an incoming request.

<b>Signature:</b>

```typescript
get: (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest) => string;
```
28 changes: 28 additions & 0 deletions docs/development/core/server/kibana-plugin-server.basepath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [BasePath](./kibana-plugin-server.basepath.md)

## BasePath class

Access or manipulate the Kibana base path

<b>Signature:</b>

```typescript
export declare class BasePath
```

## Properties

| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [get](./kibana-plugin-server.basepath.get.md) | | <code>(request: KibanaRequest&lt;unknown, unknown, unknown&gt; &#124; LegacyRequest) =&gt; string</code> | returns <code>basePath</code> value, specific for an incoming request. |
| [prepend](./kibana-plugin-server.basepath.prepend.md) | | <code>(path: string) =&gt; string</code> | returns a new <code>basePath</code> value, prefixed with passed <code>url</code>. |
| [remove](./kibana-plugin-server.basepath.remove.md) | | <code>(path: string) =&gt; string</code> | returns a new <code>basePath</code> value, cleaned up from passed <code>url</code>. |
| [serverBasePath](./kibana-plugin-server.basepath.serverbasepath.md) | | <code>string</code> | returns the server's basePath<!-- -->See [BasePath.get](./kibana-plugin-server.basepath.get.md) for getting the basePath value for a specific request |
| [set](./kibana-plugin-server.basepath.set.md) | | <code>(request: KibanaRequest&lt;unknown, unknown, unknown&gt; &#124; LegacyRequest, requestSpecificBasePath: string) =&gt; void</code> | sets <code>basePath</code> value, specific for an incoming request. |

## Remarks

The constructor for this class is marked as internal. Third-party code should not call the constructor directly or create subclasses that extend the `BasePath` class.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [BasePath](./kibana-plugin-server.basepath.md) &gt; [prepend](./kibana-plugin-server.basepath.prepend.md)

## BasePath.prepend property

returns a new `basePath` value, prefixed with passed `url`<!-- -->.

<b>Signature:</b>

```typescript
prepend: (path: string) => string;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [BasePath](./kibana-plugin-server.basepath.md) &gt; [remove](./kibana-plugin-server.basepath.remove.md)

## BasePath.remove property

returns a new `basePath` value, cleaned up from passed `url`<!-- -->.

<b>Signature:</b>

```typescript
remove: (path: string) => string;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [BasePath](./kibana-plugin-server.basepath.md) &gt; [serverBasePath](./kibana-plugin-server.basepath.serverbasepath.md)

## BasePath.serverBasePath property

returns the server's basePath

See [BasePath.get](./kibana-plugin-server.basepath.get.md) for getting the basePath value for a specific request

<b>Signature:</b>

```typescript
readonly serverBasePath: string;
```
13 changes: 13 additions & 0 deletions docs/development/core/server/kibana-plugin-server.basepath.set.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [BasePath](./kibana-plugin-server.basepath.md) &gt; [set](./kibana-plugin-server.basepath.set.md)

## BasePath.set property

sets `basePath` value, specific for an incoming request.

<b>Signature:</b>

```typescript
set: (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest, requestSpecificBasePath: string) => void;
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@

## HttpServerSetup.basePath property

[BasePath](./kibana-plugin-server.basepath.md)

<b>Signature:</b>

```typescript
basePath: {
get: (request: KibanaRequest | LegacyRequest) => string;
set: (request: KibanaRequest | LegacyRequest, basePath: string) => void;
prepend: (url: string) => string;
remove: (url: string) => string;
};
basePath: IBasePath;
```
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface HttpServerSetup
| Property | Type | Description |
| --- | --- | --- |
| [auth](./kibana-plugin-server.httpserversetup.auth.md) | <code>{</code><br/><code> get: GetAuthState;</code><br/><code> isAuthenticated: IsAuthenticated;</code><br/><code> getAuthHeaders: GetAuthHeaders;</code><br/><code> }</code> | |
| [basePath](./kibana-plugin-server.httpserversetup.basepath.md) | <code>{</code><br/><code> get: (request: KibanaRequest &#124; LegacyRequest) =&gt; string;</code><br/><code> set: (request: KibanaRequest &#124; LegacyRequest, basePath: string) =&gt; void;</code><br/><code> prepend: (url: string) =&gt; string;</code><br/><code> remove: (url: string) =&gt; string;</code><br/><code> }</code> | |
| [basePath](./kibana-plugin-server.httpserversetup.basepath.md) | <code>IBasePath</code> | [BasePath](./kibana-plugin-server.basepath.md) |
| [createCookieSessionStorageFactory](./kibana-plugin-server.httpserversetup.createcookiesessionstoragefactory.md) | <code>&lt;T&gt;(cookieOptions: SessionStorageCookieOptions&lt;T&gt;) =&gt; Promise&lt;SessionStorageFactory&lt;T&gt;&gt;</code> | Creates cookie based session storage factory [SessionStorageFactory](./kibana-plugin-server.sessionstoragefactory.md) |
| [isTlsEnabled](./kibana-plugin-server.httpserversetup.istlsenabled.md) | <code>boolean</code> | Flag showing whether a server was configured to use TLS connection. |
| [registerAuth](./kibana-plugin-server.httpserversetup.registerauth.md) | <code>(handler: AuthenticationHandler) =&gt; void</code> | To define custom authentication and/or authorization mechanism for incoming requests. A handler should return a state to associate with the incoming request. The state can be retrieved later via http.auth.get(..) Only one AuthenticationHandler can be registered. |
Expand Down
15 changes: 15 additions & 0 deletions docs/development/core/server/kibana-plugin-server.ibasepath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [IBasePath](./kibana-plugin-server.ibasepath.md)

## IBasePath type

Access or manipulate the Kibana base path

[BasePath](./kibana-plugin-server.basepath.md)

<b>Signature:</b>

```typescript
export declare type IBasePath = Pick<BasePath, keyof BasePath>;
```
2 changes: 2 additions & 0 deletions docs/development/core/server/kibana-plugin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->

| Class | Description |
| --- | --- |
| [BasePath](./kibana-plugin-server.basepath.md) | Access or manipulate the Kibana base path |
| [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via <code>asScoped(...)</code>). |
| [ElasticsearchErrorHelpers](./kibana-plugin-server.elasticsearcherrorhelpers.md) | Helpers for working with errors returned from the Elasticsearch service.Since the internal data of errors are subject to change, consumers of the Elasticsearch service should always use these helpers to classify errors instead of checking error internals such as <code>body.error.header[WWW-Authenticate]</code> |
| [KibanaRequest](./kibana-plugin-server.kibanarequest.md) | Kibana specific abstraction for an incoming request. |
Expand Down Expand Up @@ -122,6 +123,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [Headers](./kibana-plugin-server.headers.md) | Http request headers to read. |
| [HttpResponsePayload](./kibana-plugin-server.httpresponsepayload.md) | Data send to the client as a response payload. |
| [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) | |
| [IBasePath](./kibana-plugin-server.ibasepath.md) | Access or manipulate the Kibana base path[BasePath](./kibana-plugin-server.basepath.md) |
| [IContextHandler](./kibana-plugin-server.icontexthandler.md) | A function registered by a plugin to perform some action. |
| [IContextProvider](./kibana-plugin-server.icontextprovider.md) | A function that returns a context value for a specific key of given context type. |
| [IsAuthenticated](./kibana-plugin-server.isauthenticated.md) | Return authentication status for a request. |
Expand Down
12 changes: 12 additions & 0 deletions src/core/server/http/base_path_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ import { KibanaRequest } from './router';
import { httpServerMock } from './http_server.mocks';

describe('BasePath', () => {
describe('serverBasePath', () => {
it('defaults to an empty string', () => {
const basePath = new BasePath();
expect(basePath.serverBasePath).toBe('');
});

it('returns the server base path', () => {
const basePath = new BasePath('/server');
expect(basePath.serverBasePath).toBe('/server');
});
});

describe('#get()', () => {
it('returns base path associated with an incoming Legacy.Request request', () => {
const request = httpServerMock.createRawRequest();
Expand Down
47 changes: 41 additions & 6 deletions src/core/server/http/base_path_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,39 @@ import { ensureRawRequest, KibanaRequest, LegacyRequest } from './router';

import { modifyUrl } from '../../utils';

/**
* Access or manipulate the Kibana base path
*
* @public
*/
export class BasePath {
private readonly basePathCache = new WeakMap<LegacyRequest, string>();

constructor(private readonly serverBasePath?: string) {}
/**
* returns the server's basePath
*
* See {@link BasePath.get} for getting the basePath value for a specific request
*/
public readonly serverBasePath: string;

/** @internal */
constructor(serverBasePath: string = '') {
this.serverBasePath = serverBasePath;
}

/**
* returns `basePath` value, specific for an incoming request.
*/
public get = (request: KibanaRequest | LegacyRequest) => {
const requestScopePath = this.basePathCache.get(ensureRawRequest(request)) || '';
const serverBasePath = this.serverBasePath || '';
return `${serverBasePath}${requestScopePath}`;
return `${this.serverBasePath}${requestScopePath}`;
};

// should work only for KibanaRequest as soon as spaces migrate to NP
/**
* sets `basePath` value, specific for an incoming request.
*
* @privateRemarks should work only for KibanaRequest as soon as spaces migrate to NP
*/
public set = (request: KibanaRequest | LegacyRequest, requestSpecificBasePath: string) => {
const rawRequest = ensureRawRequest(request);

Expand All @@ -43,17 +64,23 @@ export class BasePath {
this.basePathCache.set(rawRequest, requestSpecificBasePath);
};

/**
* returns a new `basePath` value, prefixed with passed `url`.
*/
public prepend = (path: string): string => {
if (!this.serverBasePath) return path;
if (this.serverBasePath === '') return path;
return modifyUrl(path, parts => {
if (!parts.hostname && parts.pathname && parts.pathname.startsWith('/')) {
parts.pathname = `${this.serverBasePath}${parts.pathname}`;
}
});
};

/**
* returns a new `basePath` value, cleaned up from passed `url`.
*/
public remove = (path: string): string => {
if (!this.serverBasePath) {
if (this.serverBasePath === '') {
return path;
}

Expand All @@ -68,3 +95,11 @@ export class BasePath {
return path;
};
}

/**
* Access or manipulate the Kibana base path
*
* {@link BasePath}
* @public
*/
export type IBasePath = Pick<BasePath, keyof BasePath>;
24 changes: 4 additions & 20 deletions src/core/server/http/http_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ import { adoptToHapiAuthFormat, AuthenticationHandler } from './lifecycle/auth';
import { adoptToHapiOnPostAuthFormat, OnPostAuthHandler } from './lifecycle/on_post_auth';
import { adoptToHapiOnPreAuthFormat, OnPreAuthHandler } from './lifecycle/on_pre_auth';

import { KibanaRequest, LegacyRequest, ResponseHeaders, IRouter } from './router';
import { ResponseHeaders, IRouter } from './router';
import {
SessionStorageCookieOptions,
createCookieSessionStorageFactory,
} from './cookie_session_storage';
import { SessionStorageFactory } from './session_storage';
import { AuthStateStorage, GetAuthState, IsAuthenticated } from './auth_state_storage';
import { AuthHeadersStorage, GetAuthHeaders } from './auth_headers_storage';
import { BasePath } from './base_path_service';
import { BasePath, IBasePath } from './base_path_service';

/**
* Kibana HTTP Service provides own abstraction for work with HTTP stack.
Expand Down Expand Up @@ -148,24 +148,8 @@ export interface HttpServerSetup {
* @param handler {@link OnPostAuthHandler} - function to call.
*/
registerOnPostAuth: (handler: OnPostAuthHandler) => void;
basePath: {
/**
* returns `basePath` value, specific for an incoming request.
*/
get: (request: KibanaRequest | LegacyRequest) => string;
/**
* sets `basePath` value, specific for an incoming request.
*/
set: (request: KibanaRequest | LegacyRequest, basePath: string) => void;
/**
* returns a new `basePath` value, prefixed with passed `url`.
*/
prepend: (url: string) => string;
/**
* returns a new `basePath` value, cleaned up from passed `url`.
*/
remove: (url: string) => string;
};
/** {@link BasePath} */
basePath: IBasePath;
auth: {
get: GetAuthState;
isAuthenticated: IsAuthenticated;
Expand Down
1 change: 1 addition & 0 deletions src/core/server/http/http_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type ServiceSetupMockType = jest.Mocked<HttpServiceSetup> & {
};

const createBasePathMock = (): jest.Mocked<HttpServiceSetup['basePath']> => ({
serverBasePath: '/mock-server-basepath',
get: jest.fn(),
set: jest.fn(),
prepend: jest.fn(),
Expand Down
1 change: 1 addition & 0 deletions src/core/server/http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ export { OnPostAuthHandler, OnPostAuthToolkit } from './lifecycle/on_post_auth';
export { SessionStorageFactory, SessionStorage } from './session_storage';
export { SessionStorageCookieOptions } from './cookie_session_storage';
export * from './types';
export { BasePath, IBasePath } from './base_path_service';
2 changes: 2 additions & 0 deletions src/core/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export {
AuthResultParams,
AuthStatus,
AuthToolkit,
BasePath,
IBasePath,
CustomHttpResponseOptions,
GetAuthHeaders,
GetAuthState,
Expand Down
21 changes: 15 additions & 6 deletions src/core/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ export interface AuthToolkit {
authenticated: (data?: AuthResultParams) => AuthResult;
}

// @public
export class BasePath {
// @internal
constructor(serverBasePath?: string);
get: (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest) => string;
prepend: (path: string) => string;
remove: (path: string) => string;
readonly serverBasePath: string;
set: (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest, requestSpecificBasePath: string) => void;
}

// Warning: (ae-forgotten-export) The symbol "BootstrapArgs" needs to be exported by the entry point index.d.ts
//
// @internal (undocumented)
Expand Down Expand Up @@ -230,12 +241,7 @@ export interface HttpServerSetup {
getAuthHeaders: GetAuthHeaders;
};
// (undocumented)
basePath: {
get: (request: KibanaRequest | LegacyRequest) => string;
set: (request: KibanaRequest | LegacyRequest, basePath: string) => void;
prepend: (url: string) => string;
remove: (url: string) => string;
};
basePath: IBasePath;
createCookieSessionStorageFactory: <T>(cookieOptions: SessionStorageCookieOptions<T>) => Promise<SessionStorageFactory<T>>;
isTlsEnabled: boolean;
registerAuth: (handler: AuthenticationHandler) => void;
Expand All @@ -257,6 +263,9 @@ export interface HttpServiceStart {
isListening: (port: number) => boolean;
}

// @public
export type IBasePath = Pick<BasePath, keyof BasePath>;

// @public
export interface IContextContainer<TContext extends {}, THandlerReturn, THandlerParameters extends any[] = []> {
createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandler<TContext, THandlerReturn, THandlerParameters>): (...rest: THandlerParameters) => THandlerReturn extends Promise<any> ? THandlerReturn : Promise<THandlerReturn>;
Expand Down

0 comments on commit 837ee95

Please sign in to comment.