Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] Expose serverBasePath fixes #45991 (#45995) #46966

Merged
merged 1 commit into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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