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

Implement Server-Side sessions #68117

Merged
merged 52 commits into from
Aug 18, 2020
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
bfd42f0
Implement Server-Side sessions.
azasypkin Jun 3, 2020
fc0ab5d
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 8, 2020
194b06e
Added functional tests for the OIDC capture URL flow, Authenticator t…
azasypkin Jul 8, 2020
176fe3b
Remove session that belongs to a not configured provider in all cases.
azasypkin Jul 8, 2020
3f85d63
More tests, don't clean session on password change (temporarily).
azasypkin Jul 8, 2020
50a09bb
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 9, 2020
ada2b9f
Add capture-url tests, session cookie, and session management service…
azasypkin Jul 9, 2020
a30e49b
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 9, 2020
f033f72
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 14, 2020
38f15bb
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 15, 2020
959a535
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 15, 2020
9d3273b
Review#1: handle review comments, add more tests.
azasypkin Jul 15, 2020
7133991
Review#1: manually fix Jest snapshots as they are not updated by Jest…
azasypkin Jul 16, 2020
e915c3f
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 16, 2020
21bb805
Add basic docs and session integration tests.
azasypkin Jul 16, 2020
11b3c4e
Fix outdated test file link.
azasypkin Jul 16, 2020
8bd08e5
Fix more outdated test file links.
azasypkin Jul 16, 2020
3fe0d46
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 17, 2020
ccbcec1
More tweaks to the brand new session api integration tests.
azasypkin Jul 17, 2020
04801a1
Wait for the `GREEN` status of session index before running tests.
azasypkin Jul 17, 2020
b6f3987
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 22, 2020
3f1fa9c
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 31, 2020
b91f050
Review#2: handle review feedback.
azasypkin Jul 31, 2020
09acb02
Merge branch 'master' into issue-xxx-sss
azasypkin Jul 31, 2020
38f41cf
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 3, 2020
e98dbd0
Review#2: properly update session index when user is active.
azasypkin Aug 3, 2020
a86884c
Remove duplicated test suite declaration.
azasypkin Aug 3, 2020
6acf005
Review#2: use SID-scoped loggers inside of `Session`.
azasypkin Aug 3, 2020
d518e99
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 4, 2020
a8d46f1
Review#3: generate index name inside of `SessionIndex` and get rid of…
azasypkin Aug 4, 2020
d3c8454
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 10, 2020
bcbd9c2
Sync PR with the latest upstream ESLint rules.
azasypkin Aug 10, 2020
fb47b91
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 11, 2020
b40adf6
Review#4: more comments and logs, use 32 bytes for SID and AAD instea…
azasypkin Aug 11, 2020
9548184
Review#4: properly handle empty sessions in `SessionTimeout` service,…
azasypkin Aug 11, 2020
f03d978
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 11, 2020
2d3ea32
Review#5: allow smaller cleanup timeouts in dev mode (for tests).
azasypkin Aug 11, 2020
8ee6b90
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 12, 2020
21d24ed
Review#5: decrease minimum value for cleanup interval to 10s to make …
azasypkin Aug 12, 2020
efdbef2
Update docs.
azasypkin Aug 12, 2020
92437c0
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 12, 2020
d69116a
Merge branch 'master' into issue-xxx-sss
elasticmachine Aug 12, 2020
ed6944d
Merge branch 'master' into issue-xxx-sss
elasticmachine Aug 13, 2020
ca64e87
Merge branch 'master' into issue-xxx-sss
elasticmachine Aug 13, 2020
4d0ee0d
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 14, 2020
378c239
Review#6: incorporate docs review suggestions.
azasypkin Aug 14, 2020
a4cdb60
tests: make sure we always wait for the green status before trying to…
azasypkin Aug 14, 2020
b178201
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 17, 2020
3ded572
Review#7: handle more docs comments.
azasypkin Aug 17, 2020
5bc9502
Review#8: more doc improvements.
azasypkin Aug 17, 2020
1d27f02
Merge branch 'master' into issue-xxx-sss
azasypkin Aug 17, 2020
8ea6939
Review#8: more docs comments.
azasypkin Aug 17, 2020
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
11 changes: 11 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,17 @@
/x-pack/plugins/security/ @elastic/kibana-security
/x-pack/plugins/security/**/*.scss @elastic/kibana-core-ui
/x-pack/test/api_integration/apis/security/ @elastic/kibana-security
/x-pack/test/encrypted_saved_objects_api_integration/ @elastic/kibana-security
/x-pack/test/functional/apps/security/ @elastic/kibana-security
/x-pack/test/kerberos_api_integration/ @elastic/kibana-security
/x-pack/test/login_selector_api_integration/ @elastic/kibana-security
/x-pack/test/oidc_api_integration/ @elastic/kibana-security
/x-pack/test/pki_api_integration/ @elastic/kibana-security
/x-pack/test/saml_api_integration/ @elastic/kibana-security
/x-pack/test/security_api_integration/ @elastic/kibana-security
/x-pack/test/security_functional/ @elastic/kibana-security
/x-pack/test/spaces_api_integration/ @elastic/kibana-security
/x-pack/test/token_api_integration/ @elastic/kibana-security

# Kibana Localization
/src/dev/i18n/ @elastic/kibana-localization
Expand Down
21 changes: 17 additions & 4 deletions docs/settings/security-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ In addition to <<authentication-provider-settings,the settings that are valid fo
| SAML realm in {es} that provider should use.

| `xpack.security.authc.providers.`
`saml.<provider-name>.maxRedirectURLSize`
| The maximum size of the URL that {kib} is allowed to store during the authentication SAML handshake. For more information, refer to <<security-saml-and-long-urls>>.
`saml.<provider-name>.useRelayStateDeepLink`
| Determines if provider should treat `RelayState` parameter as a deep link in {kib} during Identity Provider initiated login. By default, this setting is set to `false`. The link specified in `RelayState` should be a relative, URL-encoded {kib} URL, e.g. for `/app/dashboards#/list` link `RelayState` parameter would look like this `RelayState=%2Fapp%2Fdashboards%23%2Flist` for .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence ends with "for ." Did you mean to add something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| Determines if provider should treat `RelayState` parameter as a deep link in {kib} during Identity Provider initiated login. By default, this setting is set to `false`. The link specified in `RelayState` should be a relative, URL-encoded {kib} URL, e.g. for `/app/dashboards#/list` link `RelayState` parameter would look like this `RelayState=%2Fapp%2Fdashboards%23%2Flist` for .
| Determines if the provider should treat the `RelayState` parameter as a deep link in {kib} during Identity Provider initiated log in. By default, this setting is set to `false`. The link specified in `RelayState` should be a relative, URL-encoded {kib} URL. For example, the `/app/dashboards#/list` link `RelayState` parameter would look like this `RelayState=%2Fapp%2Fdashboards%23%2Flist` .


|===

Expand Down Expand Up @@ -186,8 +186,7 @@ You can configure the following settings in the `kibana.yml` file.
| Sets the name of the cookie used for the session. The default value is `"sid"`.

| `xpack.security.encryptionKey`
| An arbitrary string of 32 characters or more that is used to encrypt credentials
in a cookie. It is crucial that this key is not exposed to users of {kib}. By
| An arbitrary string of 32 characters or more that is used to encrypt session information. It is crucial that this key is not exposed to users of {kib}. By
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| An arbitrary string of 32 characters or more that is used to encrypt session information. It is crucial that this key is not exposed to users of {kib}. By
| An arbitrary string of 32 characters or more that is used to encrypt session information. Do **not** expose this key to users of {kib}. By

default, a value is automatically generated in memory. If you use that default
behavior, all sessions are invalidated when {kib} restarts.
In addition, high-availability deployments of {kib} will behave unexpectedly
Expand Down Expand Up @@ -237,6 +236,20 @@ string of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70ms', '5s', '3d', '1Y').
[cols="2*<"]
|===

| `xpack.security.session.cleanupInterval`
| Sets the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour. The minimum value is 10 seconds.

|===

[TIP]
============
The format is a
string of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '20m', '24h', '7d', '1w').
============

[cols="2*<"]
|===

| `xpack.security.loginAssistanceMessage`
| Adds a message to the login screen. Useful for displaying information about maintenance windows, links to corporate sign up pages etc.

Expand Down
2 changes: 1 addition & 1 deletion docs/setup/production.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ server.port

Settings that must be the same:
--------
xpack.security.encryptionKey //decrypting session cookies
xpack.security.encryptionKey //decrypting session information
xpack.reporting.encryptionKey //decrypting reports
xpack.encryptedSavedObjects.encryptionKey // decrypting saved objects
--------
Expand Down
20 changes: 0 additions & 20 deletions docs/user/security/authentication/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,6 @@ Basic authentication is supported _only_ if the `basic` authentication provider

To support basic authentication for the applications like `curl` or when the `Authorization: Basic base64(username:password)` HTTP header is included in the request (for example, by reverse proxy), add `Basic` scheme to the list of supported schemes for the <<http-authentication,HTTP authentication>>.

[float]
[[security-saml-and-long-urls]]
===== SAML and long URLs

At the beginning of the SAML handshake, {kib} stores the initial URL in the session cookie, so it can redirect the user back to that URL after successful SAML authentication.
If the URL is long, the session cookie might exceed the maximum size supported by the browser--typically 4KB for all cookies per domain. When this happens, the session cookie is truncated,
or dropped completely, and you might experience sporadic failures during SAML authentication.

To remedy this issue, you can decrease the maximum
size of the URL that {kib} is allowed to store during the SAML handshake. The default value is 2KB.

[source,yaml]
--------------------------------------------------------------------------------
xpack.security.authc.providers:
saml.saml1:
order: 0
realm: saml1
maxRedirectURLSize: 1kb
--------------------------------------------------------------------------------

[[oidc]]
==== OpenID Connect single sign-on

Expand Down
31 changes: 2 additions & 29 deletions docs/user/security/securing-kibana.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -56,35 +56,7 @@ xpack.security.encryptionKey: "something_at_least_32_characters"
For more information, see <<security-settings-kb,Security settings in {kib}>>.
--

. Optional: Set a timeout to expire idle sessions. By default, a session stays
active until the browser is closed. To define a sliding session expiration, set
the `xpack.security.session.idleTimeout` property in the `kibana.yml`
configuration file. The idle timeout is formatted as a duration of
`<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70ms', '5s', '3d', '1Y'). For example, set
the idle timeout to expire idle sessions after 10 minutes:
+
--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.idleTimeout: "10m"
--------------------------------------------------------------------------------
--

. Optional: Change the maximum session duration or "lifespan" -- also known as
the "absolute timeout". By default, a session stays active until the browser is
closed. If an idle timeout is defined, a session can still be extended
indefinitely. To define a maximum session lifespan, set the
`xpack.security.session.lifespan` property in the `kibana.yml` configuration
file. The lifespan is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]`
(e.g. '70ms', '5s', '3d', '1Y'). For example, set the lifespan to expire
sessions after 8 hours:
+
--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.lifespan: "8h"
--------------------------------------------------------------------------------
--
. Optional: <<xpack-security-session-management, Configure {kib} session settings>>.

. Optional: <<configuring-tls,Configure {kib} to encrypt communications>>.

Expand Down Expand Up @@ -146,3 +118,4 @@ include::securing-communications/index.asciidoc[]
include::securing-communications/elasticsearch-mutual-tls.asciidoc[]
include::audit-logging.asciidoc[]
include::access-agreement.asciidoc[]
include::session-management.asciidoc[]
62 changes: 62 additions & 0 deletions docs/user/security/session-management.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
[role="xpack"]
[[xpack-security-session-management]]
=== Session management

When you log in to {kib} it creates a session that is used to authenticate any subsequent request to {kib} made on your behalf. {kib} encrypts any sensitive session information and stores it in a dedicated hidden {es} index. By default, the name of that index is `.kibana_security_session_1` where the prefix depends on the name of the main `.kibana` index.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When you log in to {kib} it creates a session that is used to authenticate any subsequent request to {kib} made on your behalf. {kib} encrypts any sensitive session information and stores it in a dedicated hidden {es} index. By default, the name of that index is `.kibana_security_session_1` where the prefix depends on the name of the main `.kibana` index.
When you log in to {kib} it creates a session that is used to authenticate subsequent requests to {kib}. A session consists of two components: an encrypted cookie that is stored in your browser, and an encrypted document in a dedicated {es} hidden index. By default, the name of that index is `.kibana_security_session_1` where the prefix is derived from {kib}'s primary `.kibana` index.


Additionally, for every new session {kib} creates an encrypted client side cookie that is stored in your browser and sent to {kib} with every request. This way {kib} can associate request with the session information stored in the session index.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Additionally, for every new session {kib} creates an encrypted client side cookie that is stored in your browser and sent to {kib} with every request. This way {kib} can associate request with the session information stored in the session index.

When your session expires, or you log out of {kib} explicitly it will invalidate your cookie and remove session information from the index. In addition to that {kib} performs a regular session index cleanup to remove any expired sessions that weren't invalidated explicitly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When your session expires, or you log out of {kib} explicitly it will invalidate your cookie and remove session information from the index. In addition to that {kib} performs a regular session index cleanup to remove any expired sessions that weren't invalidated explicitly.
When your session expires, or you log out of {kib} explicitly it will invalidate your cookie and remove session information from the index. {kib} also periodically invalidates and removes any expired sessions that weren't invalidated explicitly.


[[session-idle-timeout]]
==== Session idle timeout

You can configure timeout to expire idle sessions. By default, a session stays
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can configure timeout to expire idle sessions. By default, a session stays
You can optionally expire sessions after a period of inactivity. By default, a session stays

active until the browser is closed. To define a sliding session expiration, set
the `xpack.security.session.idleTimeout` property in the `kibana.yml`
configuration file. The idle timeout is formatted as a duration of
`<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70ms', '5s', '3d', '1Y'). For example, set
the idle timeout to expire idle sessions after 10 minutes:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
the idle timeout to expire idle sessions after 10 minutes:
the idle timeout to expire idle sessions after 10 minutes of inactivity:


--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.idleTimeout: "10m"
--------------------------------------------------------------------------------
--

[[session-lifespan]]
==== Session lifespan

You can configure the maximum session duration or "lifespan" -- also known as
the "absolute timeout". By default, a session stays active until the browser is
closed. If an idle timeout is defined, a session can still be extended
indefinitely. To define a maximum session lifespan, set the
`xpack.security.session.lifespan` property in the `kibana.yml` configuration
file. The lifespan is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]`
(e.g. '70ms', '5s', '3d', '1Y'). For example, set the lifespan to expire
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest changing this to match the new description in my top-level comment, if you agree with it.

sessions after 8 hours:

--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.lifespan: "8h"
--------------------------------------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about changing this example to use our planned default of 30 days?

--

[[session-cleanup-interval]]
==== Session cleanup interval

You can configure the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour and cannot be less than 10 seconds. To define another interval, set the `xpack.security.session.cleanupInterval` property in the `kibana.yml` configuration file. The interval is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70000ms', '50s', '3d', '1Y'). For example, schedule session index cleanup to be performed only once a day:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can configure the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour and cannot be less than 10 seconds. To define another interval, set the `xpack.security.session.cleanupInterval` property in the `kibana.yml` configuration file. The interval is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70000ms', '50s', '3d', '1Y'). For example, schedule session index cleanup to be performed only once a day:
You can configure the interval at which {kib} tries to remove expired and invalid sessions from the session index. By default, this value is 1 hour and cannot be less than 10 seconds. To define another interval, set the `xpack.security.session.cleanupInterval` property in the `kibana.yml` configuration file. The interval is formatted as a duration of `<count>[ms|s|m|h|d|w|M|Y]` (e.g. '70000ms', '50s', '3d', '1Y'). For example, schedule the session index cleanup to perform once a day:


--
[source,yaml]
--------------------------------------------------------------------------------
xpack.security.session.cleanupInterval: "1d"
--------------------------------------------------------------------------------
--

[IMPORTANT]
============================================================================
If you specify neither session idle timeout nor lifespan, then {kib} will not automatically remove session information from the index unless you explicitly log out of {kib}. This may lead to an infinitely growing session index. It's one of the reasons why we strongly recommend configuring idle timeout and lifespan settings for the {kib} sessions so that they can be eventually cleaned up even if you don't log out of {kib} explicitly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you specify neither session idle timeout nor lifespan, then {kib} will not automatically remove session information from the index unless you explicitly log out of {kib}. This may lead to an infinitely growing session index. It's one of the reasons why we strongly recommend configuring idle timeout and lifespan settings for the {kib} sessions so that they can be eventually cleaned up even if you don't log out of {kib} explicitly.
If you don't specify a session idle timeout or lifespan, then {kib} will not automatically remove session information from the index unless you explicitly log out. This might lead to an infinitely growing session index. Configure the idle timeout and lifespan settings for the {kib} sessions so that they can be cleaned up even if you don't explicitly log out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you specify neither session idle timeout nor lifespan, then {kib} will not automatically remove session information from the index unless you explicitly log out of {kib}.

If you don't specify a session idle timeout or lifespan, then {kib} will not automatically remove session information from the index unless you explicitly log out.

@gchaps It seems If you don't specify a session idle timeout or lifespan has a different meaning or ..? I wanted to say here that we won't perform cleanup only if both settings are not set, but if any of them is set then it's fine and we'll do the cleanup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh you're right. Ignore my edit then.

============================================================================
Copy link
Contributor

@jportner jportner Aug 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this admonition should not be at the bottom of the page.

Edit: as in, perhaps it should be moved up higher / displayed more prominently.

Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ kibana_vars=(
xpack.security.sessionTimeout
xpack.security.session.idleTimeout
xpack.security.session.lifespan
xpack.security.session.cleanupInterval
xpack.security.loginAssistanceMessage
xpack.security.loginHelp
xpack.spaces.enabled
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/security/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "security"],
"requiredPlugins": ["data", "features", "licensing"],
"requiredPlugins": ["data", "features", "licensing", "taskManager"],
"optionalPlugins": ["home", "management"],
"server": true,
"ui": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { ApplicationSetup, StartServicesAccessor, HttpSetup } from 'src/core/public';
import {
ApplicationSetup,
StartServicesAccessor,
HttpSetup,
FatalErrorsSetup,
} from 'src/core/public';
import { AuthenticatedUser } from '../../common/model';
import { ConfigType } from '../config';
import { PluginStartDependencies } from '../plugin';
Expand All @@ -13,9 +18,11 @@ import { loginApp } from './login';
import { logoutApp } from './logout';
import { loggedOutApp } from './logged_out';
import { overwrittenSessionApp } from './overwritten_session';
import { captureURLApp } from './capture_url';

interface SetupParams {
application: ApplicationSetup;
fatalErrors: FatalErrorsSetup;
config: ConfigType;
http: HttpSetup;
getStartServices: StartServicesAccessor<PluginStartDependencies>;
Expand All @@ -36,6 +43,7 @@ export interface AuthenticationServiceSetup {
export class AuthenticationService {
public setup({
application,
fatalErrors,
config,
getStartServices,
http,
Expand All @@ -48,6 +56,7 @@ export class AuthenticationService {
.apiKeysEnabled;

accessAgreementApp.create({ application, getStartServices });
captureURLApp.create({ application, fatalErrors, http });
loginApp.create({ application, config, getStartServices, http });
logoutApp.create({ application, http });
loggedOutApp.create({ application, getStartServices, http });
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { AppMount, ScopedHistory } from 'src/core/public';
import { captureURLApp } from './capture_url_app';

import { coreMock, scopedHistoryMock } from '../../../../../../src/core/public/mocks';

describe('captureURLApp', () => {
beforeAll(() => {
Object.defineProperty(window, 'location', {
value: { href: 'https://some-host' },
writable: true,
});
});

it('properly registers application', () => {
const coreSetupMock = coreMock.createSetup();

captureURLApp.create(coreSetupMock);

expect(coreSetupMock.http.anonymousPaths.register).toHaveBeenCalledTimes(1);
expect(coreSetupMock.http.anonymousPaths.register).toHaveBeenCalledWith(
'/internal/security/capture-url'
);

expect(coreSetupMock.application.register).toHaveBeenCalledTimes(1);

const [[appRegistration]] = coreSetupMock.application.register.mock.calls;
expect(appRegistration).toEqual({
id: 'security_capture_url',
chromeless: true,
appRoute: '/internal/security/capture-url',
title: 'Capture URL',
mount: expect.any(Function),
});
});

it('properly handles captured URL', async () => {
window.location.href = `https://host.com/mock-base-path/internal/security/capture-url?next=${encodeURIComponent(
'/mock-base-path/app/home'
)}&providerType=saml&providerName=saml1#/?_g=()`;

const coreSetupMock = coreMock.createSetup();
coreSetupMock.http.post.mockResolvedValue({ location: '/mock-base-path/app/home#/?_g=()' });

captureURLApp.create(coreSetupMock);

const [[{ mount }]] = coreSetupMock.application.register.mock.calls;
await (mount as AppMount)({
element: document.createElement('div'),
appBasePath: '',
onAppLeave: jest.fn(),
history: (scopedHistoryMock.create() as unknown) as ScopedHistory,
});

expect(coreSetupMock.http.post).toHaveBeenCalledTimes(1);
expect(coreSetupMock.http.post).toHaveBeenCalledWith('/internal/security/login', {
body: JSON.stringify({
providerType: 'saml',
providerName: 'saml1',
currentURL: `https://host.com/mock-base-path/internal/security/capture-url?next=${encodeURIComponent(
'/mock-base-path/app/home'
)}&providerType=saml&providerName=saml1#/?_g=()`,
}),
});

expect(window.location.href).toBe('/mock-base-path/app/home#/?_g=()');
});
});
Loading