Skip to content

Commit

Permalink
Add server rendering service to enable standalone route rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
eliperelman committed Dec 4, 2019
1 parent a60b557 commit db70d9c
Show file tree
Hide file tree
Showing 72 changed files with 4,757 additions and 1,979 deletions.
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; [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) &gt; [csp](./kibana-plugin-server.httpservicesetup.csp.md)

## HttpServiceSetup.csp property

Config settings related to browser Content Security Policy.

<b>Signature:</b>

```typescript
csp: CspOptions;
```
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface HttpServiceSetup
| [basePath](./kibana-plugin-server.httpservicesetup.basepath.md) | <code>IBasePath</code> | Access or manipulate the Kibana base path See [IBasePath](./kibana-plugin-server.ibasepath.md)<!-- -->. |
| [createCookieSessionStorageFactory](./kibana-plugin-server.httpservicesetup.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) |
| [createRouter](./kibana-plugin-server.httpservicesetup.createrouter.md) | <code>() =&gt; IRouter</code> | Provides ability to declare a handler function for a particular path and HTTP request method. |
| [csp](./kibana-plugin-server.httpservicesetup.csp.md) | <code>CspOptions</code> | Config settings related to browser Content Security Policy. |
| [isTlsEnabled](./kibana-plugin-server.httpservicesetup.istlsenabled.md) | <code>boolean</code> | Flag showing whether a server was configured to use TLS connection. |
| [registerAuth](./kibana-plugin-server.httpservicesetup.registerauth.md) | <code>(handler: AuthenticationHandler) =&gt; void</code> | To define custom authentication and/or authorization mechanism for incoming requests. |
| [registerOnPostAuth](./kibana-plugin-server.httpservicesetup.registeronpostauth.md) | <code>(handler: OnPostAuthHandler) =&gt; void</code> | To define custom logic to perform for incoming requests. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

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

## IRenderingProvider interface

Provides a client for independently rendering HTML

<b>Signature:</b>

```typescript
export interface IRenderingProvider
```

## Methods

| Method | Description |
| --- | --- |
| [render(pluginId, includeUserProvidedConfig)](./kibana-plugin-server.irenderingprovider.render.md) | Generate a KibanaResponse which renders an HTML page bootstrapped with the core bundle or the ID of another specified bundle. Intended as a response body for HTTP route handlers.<!-- -->\* |

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

[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [IRenderingProvider](./kibana-plugin-server.irenderingprovider.md) &gt; [render](./kibana-plugin-server.irenderingprovider.render.md)

## IRenderingProvider.render() method

Generate a KibanaResponse which renders an HTML page bootstrapped with the core bundle or the ID of another specified bundle. Intended as a response body for HTTP route handlers.

\*

<b>Signature:</b>

```typescript
render(pluginId?: string, includeUserProvidedConfig?: boolean): Promise<string>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| pluginId | <code>string</code> | |
| includeUserProvidedConfig | <code>boolean</code> | |

<b>Returns:</b>

`Promise<string>`

## Example


```ts
router.get(
{ path: '/', validate: false },
(context, request, response) =>
response.ok({
headers: {
'content-security-policy': context.core.http.csp.directives,
},
body: await context.core.rendering.render(),
})
);

```

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
```typescript
core: InternalCoreSetup & {
plugins: PluginsServiceSetup;
rendering: RenderingServiceSetup;
};
```
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export interface LegacyServiceSetupDeps

| Property | Type | Description |
| --- | --- | --- |
| [core](./kibana-plugin-server.legacyservicesetupdeps.core.md) | <code>InternalCoreSetup &amp; {</code><br/><code> plugins: PluginsServiceSetup;</code><br/><code> }</code> | |
| [core](./kibana-plugin-server.legacyservicesetupdeps.core.md) | <code>InternalCoreSetup &amp; {</code><br/><code> plugins: PluginsServiceSetup;</code><br/><code> rendering: RenderingServiceSetup;</code><br/><code> }</code> | |
| [plugins](./kibana-plugin-server.legacyservicesetupdeps.plugins.md) | <code>Record&lt;string, unknown&gt;</code> | |

4 changes: 3 additions & 1 deletion docs/development/core/server/kibana-plugin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [IKibanaResponse](./kibana-plugin-server.ikibanaresponse.md) | A response data object, expected to returned as a result of [RequestHandler](./kibana-plugin-server.requesthandler.md) execution |
| [IKibanaSocket](./kibana-plugin-server.ikibanasocket.md) | A tiny abstraction for TCP socket. |
| [IndexSettingsDeprecationInfo](./kibana-plugin-server.indexsettingsdeprecationinfo.md) | |
| [IRenderingProvider](./kibana-plugin-server.irenderingprovider.md) | Provides a client for independently rendering HTML |
| [IRouter](./kibana-plugin-server.irouter.md) | Registers route handlers for specified resource path and method. See [RouteConfig](./kibana-plugin-server.routeconfig.md) and [RequestHandler](./kibana-plugin-server.requesthandler.md) for more information about arguments to route registrations. |
| [IUiSettingsClient](./kibana-plugin-server.iuisettingsclient.md) | Server-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. |
| [KibanaRequestRoute](./kibana-plugin-server.kibanarequestroute.md) | Request specific route information exposed to a handler. |
Expand All @@ -84,7 +85,8 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [PluginManifest](./kibana-plugin-server.pluginmanifest.md) | Describes the set of required and optional properties plugin can define in its mandatory JSON manifest file. |
| [PluginsServiceSetup](./kibana-plugin-server.pluginsservicesetup.md) | |
| [PluginsServiceStart](./kibana-plugin-server.pluginsservicestart.md) | |
| [RequestHandlerContext](./kibana-plugin-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.<!-- -->Provides the following clients: - [savedObjects.client](./kibana-plugin-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [elasticsearch.dataClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request |
| [RenderingServiceSetup](./kibana-plugin-server.renderingservicesetup.md) | |
| [RequestHandlerContext](./kibana-plugin-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.<!-- -->Provides the following clients: - [rendering](./kibana-plugin-server.irenderingprovider.md) - Rendering client which uses the credentials of the incoming request - [savedObjects.client](./kibana-plugin-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [elasticsearch.dataClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request |
| [RouteConfig](./kibana-plugin-server.routeconfig.md) | Route specific configuration. |
| [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) | Additional route options. |
| [RouteConfigOptionsBody](./kibana-plugin-server.routeconfigoptionsbody.md) | Additional body options for a route |
Expand Down
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; [RenderingServiceSetup](./kibana-plugin-server.renderingservicesetup.md) &gt; [getRenderingProvider](./kibana-plugin-server.renderingservicesetup.getrenderingprovider.md)

## RenderingServiceSetup.getRenderingProvider property

Generate a client for independently rendering HTML

<b>Signature:</b>

```typescript
getRenderingProvider: (params: GetRenderingProviderParams) => IRenderingProvider;
```
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; [RenderingServiceSetup](./kibana-plugin-server.renderingservicesetup.md) &gt; [getVarsFor](./kibana-plugin-server.renderingservicesetup.getvarsfor.md)

## RenderingServiceSetup.getVarsFor property

Get the metadata variables for a particular plugin

<b>Signature:</b>

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

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

## RenderingServiceSetup interface


<b>Signature:</b>

```typescript
export interface RenderingServiceSetup
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [getRenderingProvider](./kibana-plugin-server.renderingservicesetup.getrenderingprovider.md) | <code>(params: GetRenderingProviderParams) =&gt; IRenderingProvider</code> | Generate a client for independently rendering HTML |
| [getVarsFor](./kibana-plugin-server.renderingservicesetup.getvarsfor.md) | <code>(id: string) =&gt; Promise&lt;PluginVariables&gt;</code> | Get the metadata variables for a particular plugin |
| [registerVarProvider](./kibana-plugin-server.renderingservicesetup.registervarprovider.md) | <code>(id: string, provider: VarProvider) =&gt; void</code> | Register a function that returns metadata variables to inject for a particular plugin |

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; [RenderingServiceSetup](./kibana-plugin-server.renderingservicesetup.md) &gt; [registerVarProvider](./kibana-plugin-server.renderingservicesetup.registervarprovider.md)

## RenderingServiceSetup.registerVarProvider property

Register a function that returns metadata variables to inject for a particular plugin

<b>Signature:</b>

```typescript
registerVarProvider: (id: string, provider: VarProvider) => void;
```
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

```typescript
core: {
rendering: IRenderingProvider;
savedObjects: {
client: SavedObjectsClientContract;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Plugin specific context passed to a route handler.

Provides the following clients: - [savedObjects.client](./kibana-plugin-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [elasticsearch.dataClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request
Provides the following clients: - [rendering](./kibana-plugin-server.irenderingprovider.md) - Rendering client which uses the credentials of the incoming request - [savedObjects.client](./kibana-plugin-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [elasticsearch.dataClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request

<b>Signature:</b>

Expand All @@ -18,5 +18,5 @@ export interface RequestHandlerContext

| Property | Type | Description |
| --- | --- | --- |
| [core](./kibana-plugin-server.requesthandlercontext.core.md) | <code>{</code><br/><code> savedObjects: {</code><br/><code> client: SavedObjectsClientContract;</code><br/><code> };</code><br/><code> elasticsearch: {</code><br/><code> dataClient: IScopedClusterClient;</code><br/><code> adminClient: IScopedClusterClient;</code><br/><code> };</code><br/><code> uiSettings: {</code><br/><code> client: IUiSettingsClient;</code><br/><code> };</code><br/><code> }</code> | |
| [core](./kibana-plugin-server.requesthandlercontext.core.md) | <code>{</code><br/><code> rendering: IRenderingProvider;</code><br/><code> savedObjects: {</code><br/><code> client: SavedObjectsClientContract;</code><br/><code> };</code><br/><code> elasticsearch: {</code><br/><code> dataClient: IScopedClusterClient;</code><br/><code> adminClient: IScopedClusterClient;</code><br/><code> };</code><br/><code> uiSettings: {</code><br/><code> client: IUiSettingsClient;</code><br/><code> };</code><br/><code> }</code> | |

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"@kbn/ui-framework": "1.0.0",
"@types/json-stable-stringify": "^1.0.32",
"@types/lodash.clonedeep": "^4.5.4",
"@types/prettier": "^1.19.0",
"@types/react-grid-layout": "^0.16.7",
"@types/recompose": "^0.30.5",
"JSONStream": "1.3.5",
Expand Down Expand Up @@ -210,6 +211,7 @@
"oppsy": "^2.0.0",
"pegjs": "0.10.0",
"postcss-loader": "3.0.0",
"prettier": "^1.19.1",
"prop-types": "15.6.0",
"proxy-from-env": "1.0.0",
"pug": "^2.0.3",
Expand Down Expand Up @@ -438,7 +440,6 @@
"pngjs": "^3.4.0",
"postcss": "^7.0.5",
"postcss-url": "^8.0.0",
"prettier": "^1.19.1",
"proxyquire": "1.8.0",
"regenerate": "^1.4.0",
"sass-lint": "^1.12.1",
Expand Down
8 changes: 8 additions & 0 deletions renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,14 @@
'@types/podium',
],
},
{
groupSlug: 'prettier',
groupName: 'prettier related packages',
packageNames: [
'prettier',
'@types/prettier',
],
},
{
groupSlug: '@reach/router',
groupName: '@reach/router related packages',
Expand Down
34 changes: 34 additions & 0 deletions src/core/server/config/config.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { Config } from './config';

type ConfigMock = jest.Mocked<Config>;

const createConfigMock = (): ConfigMock => ({
has: jest.fn(),
get: jest.fn(),
set: jest.fn(),
getFlattenedPaths: jest.fn(),
toRaw: jest.fn(),
});

export const configMock = {
create: createConfigMock,
};
90 changes: 90 additions & 0 deletions src/core/server/http/csp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import {
createCspDirectives,
DEFAULT_CSP_OPTIONS,
DEFAULT_CSP_RULES,
DEFAULT_CSP_STRICT,
DEFAULT_CSP_WARN_LEGACY_BROWSERS,
} from './csp';

// CSP rules aren't strictly additive, so any change can potentially expand or
// restrict the policy in a way we consider a breaking change. For that reason,
// we test the default rules exactly so any change to those rules gets flagged
// for manual review. In otherwords, this test is intentionally fragile to draw
// extra attention if defaults are modified in any way.
//
// A test failure here does not necessarily mean this change cannot be made,
// but any change here should undergo sufficient scrutiny by the Kibana
// security team.
//
// The tests use inline snapshots to make it as easy as possible to identify
// the nature of a change in defaults during a PR review.
test('default CSP rules', () => {
expect(DEFAULT_CSP_RULES).toMatchInlineSnapshot(`
Array [
"script-src 'unsafe-eval' 'self'",
"worker-src blob:",
"child-src blob:",
"style-src 'unsafe-inline' 'self'",
]
`);
expect(DEFAULT_CSP_OPTIONS).toMatchInlineSnapshot(`
Object {
"directives": "script-src 'unsafe-eval' 'self'; worker-src blob:; child-src blob:; style-src 'unsafe-inline' 'self'",
"rules": Array [
"script-src 'unsafe-eval' 'self'",
"worker-src blob:",
"child-src blob:",
"style-src 'unsafe-inline' 'self'",
],
"strict": true,
"warnLegacyBrowsers": true,
}
`);
});

test('CSP strict mode defaults to disabled', () => {
expect(DEFAULT_CSP_STRICT).toBe(true);
});

test('CSP legacy browser warning defaults to enabled', () => {
expect(DEFAULT_CSP_WARN_LEGACY_BROWSERS).toBe(true);
});

test('createCspDirectives() uses defaults to generate CSP header string', () => {
const directives = createCspDirectives();

expect(directives).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self'; worker-src blob:; child-src blob:; style-src 'unsafe-inline' 'self'"`
);
});

test('createCspDirectives() converts an array of rules into a CSP header string', () => {
const directives = createCspDirectives([
`string-src 'self'`,
'worker-src blob:',
'img-src data: blob:',
]);

expect(directives).toMatchInlineSnapshot(
`"string-src 'self'; worker-src blob:; img-src data: blob:"`
);
});
Loading

0 comments on commit db70d9c

Please sign in to comment.