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

GAP: Security disables UI capabilities #25809

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
60380d9
Restructure user profile for granular app privs (#23750)
legrego Nov 5, 2018
80068c0
Fixing saved object capability checking
kobelb Oct 31, 2018
6e15ff2
Beginning to restructure actions to be used for all action building
kobelb Nov 1, 2018
f160ea9
Using actions to build ui capabilities
kobelb Nov 2, 2018
7a54a7b
dropping /read from client-side userprovide ui capabilities
kobelb Nov 2, 2018
610dc3a
Adding some actions
kobelb Nov 2, 2018
993a0c1
Using different syntax which will hopefully help with allowing apps to
kobelb Nov 5, 2018
acc1909
Exposing all saved object operations in the capabilities
kobelb Nov 5, 2018
5ac2e00
Using actions in security's onPostAuth
kobelb Nov 5, 2018
a52cf82
Only loading the default index pattern when it's required
kobelb Nov 5, 2018
f4ec14a
Only using the navlinks for the "ui capabilities"
kobelb Nov 5, 2018
c21e66b
Redirecting from the discover application if the user can't access
kobelb Nov 5, 2018
e0e8bbb
Redirecting from dashboard if they're hidden
kobelb Nov 6, 2018
12e7f1b
Features register their privileges now
kobelb Nov 7, 2018
334b59d
Introducing a FeaturesPrivilegesBuilder
kobelb Nov 7, 2018
fbc2c6f
REmoving app from the feature definition
kobelb Nov 9, 2018
379e721
Adding navlink specific ations
kobelb Nov 12, 2018
a13077a
Beginning to break out the serializer
kobelb Nov 12, 2018
0a0df84
Exposing privileges from the authorization service
kobelb Nov 12, 2018
1900fb4
Restructuring the privilege/resource serialization to support features
kobelb Nov 12, 2018
ecac891
Adding actions unit tests
kobelb Nov 12, 2018
8510a40
Adding features privileges builders tests
kobelb Nov 13, 2018
770f993
Adding PrivilegeSerializer tests
kobelb Nov 13, 2018
224c981
Renaming missed usages
kobelb Nov 13, 2018
4c49549
Adding tests for the privileges serializer
kobelb Nov 13, 2018
4158b59
Adding privileges tests
kobelb Nov 13, 2018
d73758b
Adding registerPrivilegesWithCluster tests
kobelb Nov 13, 2018
0ca6a29
Better tests
kobelb Nov 13, 2018
e3bed14
Restructure user profile for granular app privs (#23750)
legrego Nov 5, 2018
e93a08f
Fixing authorization service tests
kobelb Nov 13, 2018
c9d3e90
Adding ResourceSerializer tests
kobelb Nov 13, 2018
94a855b
Fixing Privileges tests
kobelb Nov 13, 2018
34a3b95
Some PUT role tests
kobelb Nov 14, 2018
a9d19c1
Fixing read ui/api actions
kobelb Nov 14, 2018
956b755
Introducing uiCapabilities, removing config providers & user profile …
legrego Nov 14, 2018
89bf79a
Merge remote-tracking branch 'upstream/granular-app-privileges' into …
kobelb Nov 14, 2018
90d884a
Exposing features from xpackMainPlugin
kobelb Nov 14, 2018
5275ac3
Adding navlink:* to the "reserved privileges"
kobelb Nov 14, 2018
223c4c0
navlink -> navLink | nav_linknavlink -> navLink | nav_linknavlink ->
kobelb Nov 14, 2018
1c92d42
Automatically determining navlink based ui capabilities
kobelb Nov 14, 2018
8f6a0b1
Backing out changes that got left behind
kobelb Nov 14, 2018
dd0e312
Using ui actions for navlinks
kobelb Nov 14, 2018
27f51ed
Adding TODOs
kobelb Nov 14, 2018
52ead4e
Ui -> UI
kobelb Nov 14, 2018
9d4bb8d
Deleting unused file
kobelb Nov 14, 2018
7c2db49
Removing api: [] as it's not necessary anymore
kobelb Nov 14, 2018
e381bd3
Fixing graph saved object privileges
kobelb Nov 14, 2018
3a509d5
Privileges are now async
kobelb Nov 14, 2018
fc80ce7
Pushing the asycnchronicity to the privileges "service"
kobelb Nov 15, 2018
a67fa22
Adding TODO
kobelb Nov 15, 2018
96430b0
Providing initial value for reduce
kobelb Nov 15, 2018
6b762fd
adds uiCapabilities to test_entry_template
legrego Nov 15, 2018
a4da2eb
Adding config to APM/ML feature privileges
kobelb Nov 15, 2018
ef40f71
Merge pull request #8 from legrego/pr/25347
kobelb Nov 15, 2018
52303d5
Commenting out obviously failing test so we can get CI greeenn
kobelb Nov 15, 2018
78eb191
Merge remote-tracking branch 'origin/gap/actions-restructure' into ga…
kobelb Nov 15, 2018
0b06d83
Fixing browser tests
kobelb Nov 15, 2018
bfa2410
First, very crappy implementation
kobelb Nov 15, 2018
28161fd
Adding tests for disabling ui capabilities
kobelb Nov 15, 2018
428c6aa
All being set to false no longer requires a clone
kobelb Nov 15, 2018
5e3a452
Using _.mapValues makes this a lot more readable
kobelb Nov 15, 2018
6cb6a93
Checking those privileges dynamically
kobelb Nov 16, 2018
d3c1d51
Fixing some broken stuff when i introduced checkPrivilegesDynamically
kobelb Nov 16, 2018
2411fa0
Adding conditional plugin tests
kobelb Nov 16, 2018
58936ea
Renaming conditional plugin to optional plugin
kobelb Nov 16, 2018
b706b93
Fixing type errors
kobelb Nov 16, 2018
c54108e
GAP - Actions Restructured and Extensible (#25347)
kobelb Nov 16, 2018
c65089c
Merge remote-tracking branch 'upstream/granular-app-privileges' into …
kobelb Nov 16, 2018
8989d65
Restructure user profile for granular app privs (#23750)
legrego Nov 5, 2018
503893d
Introducing uiCapabilities, removing config providers & user profile …
legrego Nov 14, 2018
c197dcf
GAP - Actions Restructured and Extensible (#25347)
kobelb Nov 16, 2018
92621e2
Update x-pack/plugins/security/server/lib/authorization/disable_ui_ca…
legrego Nov 16, 2018
d3db6ca
Update x-pack/plugins/security/server/lib/authorization/check_privile…
legrego Nov 16, 2018
446aea0
Disabling all ui capabilities if route is anonymous
kobelb Nov 19, 2018
804d413
More typescript
kobelb Nov 19, 2018
818afe5
Even more typescript
kobelb Nov 19, 2018
b8fb164
Updating snapshot
kobelb Nov 19, 2018
77bc2cd
Merge remote-tracking branch 'upstream/granular-app-privileges' into …
kobelb Nov 19, 2018
6da6dc4
Less any
kobelb Nov 19, 2018
5d4e1d2
More safer
kobelb Nov 19, 2018
6bba665
Another one
kobelb Nov 19, 2018
cf04d17
Restructure user profile for granular app privs (#23750)
legrego Nov 5, 2018
aae0858
Introducing uiCapabilities, removing config providers & user profile …
legrego Nov 14, 2018
c4f7e7d
GAP - Actions Restructured and Extensible (#25347)
kobelb Nov 16, 2018
60a2e70
update snapshot
legrego Nov 26, 2018
a624025
Merge branch 'granular-app-privileges' into pr/25809
legrego Nov 27, 2018
87682b2
Merge pull request #11 from legrego/fix-conflicts-25809
kobelb Nov 27, 2018
685c6c2
Update x-pack/plugins/security/server/lib/authorization/check_privile…
legrego Nov 27, 2018
c1f29e7
Update x-pack/plugins/security/server/lib/authorization/check_privile…
legrego Nov 27, 2018
8351171
Merge remote-tracking branch 'upstream/master' into granular-app-priv…
kobelb Nov 27, 2018
a0ea832
Merge remote-tracking branch 'upstream/granular-app-privileges' into …
kobelb Nov 27, 2018
d3e65cc
Fixing type errors
kobelb Nov 27, 2018
25fae69
Only disabling navLinks if a feature is registered for them
kobelb Nov 29, 2018
e179452
Merge remote-tracking branch 'upstream/granular-app-privileges' into …
kobelb Nov 29, 2018
37d10a5
Adding non i18n'ed tooltip
kobelb Nov 29, 2018
8d60812
Making metadata and tooltip optional
kobelb Nov 29, 2018
71c1261
Merge branch 'granular-app-privileges' into gap/disable-ui-capabilities
kobelb Dec 3, 2018
b35c7cd
i18n'ing tooltips
kobelb Dec 3, 2018
a45afbd
Responding to peer review comments
kobelb Dec 3, 2018
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
6 changes: 6 additions & 0 deletions x-pack/plugins/ml/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { resolve } from 'path';
import Boom from 'boom';
import { i18n } from '@kbn/i18n';
import { checkLicense } from './server/lib/check_license';
import { mirrorPluginStatus } from '../../server/lib/mirror_plugin_status';
import { jobRoutes } from './server/routes/anomaly_detectors';
Expand Down Expand Up @@ -70,6 +71,11 @@ export const ml = (kibana) => {
navLinkId: 'ml',
privileges: {
all: {
metadata: {
tooltip: i18n.translate('xpack.ml.privileges.tooltip', {
defaultMessage: 'The machine_learning_user or machine_learning_admin role should be assigned to grant access'
})
},
app: ['ml'],
savedObject: {
all: [],
Expand Down
6 changes: 6 additions & 0 deletions x-pack/plugins/monitoring/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';
import { LOGGING_TAG, KIBANA_MONITORING_LOGGING_TAG } from './common/constants';
import { requireUIRoutes } from './server/routes';
import { instantiateClient } from './server/es_client/instantiate_client';
Expand Down Expand Up @@ -61,6 +62,11 @@ export const init = (monitoringPlugin, server) => {
navLinkId: 'monitoring',
privileges: {
all: {
metadata: {
tooltip: i18n.translate('xpack.monitoring.privileges.tooltip', {
defaultMessage: 'The monitoring_user role should be assigned to grant access'
})
},
app: ['monitoring'],
savedObject: {
all: [],
Expand Down
36 changes: 25 additions & 11 deletions x-pack/plugins/security/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import { checkLicense } from './server/lib/check_license';
import { initAuthenticator } from './server/lib/authentication/authenticator';
import { SecurityAuditLogger } from './server/lib/audit_logger';
import { AuditLogger } from '../../server/lib/audit_logger';
import { createAuthorizationService, registerPrivilegesWithCluster } from './server/lib/authorization';
import { createAuthorizationService, disableUICapabilitesFactory, registerPrivilegesWithCluster } from './server/lib/authorization';
import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize';
import { SecureSavedObjectsClientWrapper } from './server/lib/saved_objects_client/secure_saved_objects_client_wrapper';
import { deepFreeze } from './server/lib/deep_freeze';
import { createOptionalPlugin } from './server/lib/optional_plugin';

export const security = (kibana) => new kibana.Plugin({
id: 'security',
Expand Down Expand Up @@ -88,6 +89,21 @@ export const security = (kibana) => new kibana.Plugin({
sessionTimeout: config.get('xpack.security.sessionTimeout'),
enableSpaceAwarePrivileges: config.get('xpack.spaces.enabled'),
};
},
replaceInjectedVars: async function (originalInjectedVars, request, server) {
const disableUICapabilites = disableUICapabilitesFactory(server, request);
// if we're an anonymous route, we disable all ui capabilities
if (request.route.settings.auth === false) {
return {
...originalInjectedVars,
uiCapabilities: disableUICapabilites.all(originalInjectedVars.uiCapabilities)
};
}

return {
...originalInjectedVars,
uiCapabilities: await disableUICapabilites.usingPrivileges(originalInjectedVars.uiCapabilities)
};
}
},

Expand Down Expand Up @@ -117,8 +133,10 @@ export const security = (kibana) => new kibana.Plugin({

const { savedObjects } = server;

const spaces = createOptionalPlugin(config, 'xpack.spaces', server.plugins, 'spaces');

// exposes server.plugins.security.authorization
const authorization = createAuthorizationService(server, xpackInfoFeature, savedObjects.types, xpackMainPlugin);
const authorization = createAuthorizationService(server, xpackInfoFeature, savedObjects.types, xpackMainPlugin, spaces);
server.expose('authorization', deepFreeze(authorization));

watchStatusAndLicenseToInitialize(xpackMainPlugin, plugin, async (license) => {
Expand Down Expand Up @@ -147,17 +165,15 @@ export const security = (kibana) => new kibana.Plugin({

savedObjects.addScopedSavedObjectsClientWrapperFactory(Number.MIN_VALUE, ({ client, request }) => {
if (authorization.mode.useRbacForRequest(request)) {
const { spaces } = server.plugins;

return new SecureSavedObjectsClientWrapper({
actions: authorization.actions,
auditLogger,
baseClient: client,
checkPrivilegesWithRequest: authorization.checkPrivilegesWithRequest,
checkPrivilegesDynamicallyWithRequest: authorization.checkPrivilegesDynamicallyWithRequest,
errors: savedObjects.SavedObjectsClient.errors,
request,
savedObjectTypes: savedObjects.types,
spaces,
});
}

Expand Down Expand Up @@ -193,16 +209,15 @@ export const security = (kibana) => new kibana.Plugin({
server.ext('onPostAuth', async function (req, h) {
const path = req.path;

const { actions, checkPrivilegesWithRequest } = server.plugins.security.authorization;
const checkPrivileges = checkPrivilegesWithRequest(req);
const { actions, checkPrivilegesDynamicallyWithRequest } = server.plugins.security.authorization;
const checkPrivileges = checkPrivilegesDynamicallyWithRequest(req);

// Enforce app restrictions
if (path.startsWith('/app/')) {
const appId = path.split('/', 3)[2];
const appAction = actions.app.get(appId);

// TODO: Check this at the specific space
const checkPrivilegesResponse = await checkPrivileges.globally(appAction);
const checkPrivilegesResponse = await checkPrivileges(appAction);
if (!checkPrivilegesResponse.hasAllRequested) {
return Boom.notFound();
}
Expand All @@ -218,8 +233,7 @@ export const security = (kibana) => new kibana.Plugin({
const feature = path.split('/', 3)[2];
const apiActions = actionTags.map(tag => actions.api.get(`${feature}/${tag.split(':', 2)[1]}`));

// TODO: Check this at the specific space
const checkPrivilegesResponse = await checkPrivileges.globally(apiActions);
const checkPrivilegesResponse = await checkPrivileges(apiActions);
if (!checkPrivilegesResponse.hasAllRequested) {
return Boom.notFound();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`throws error when invoked before it's available 1`] = `"Plugin accessed before it's available"`;

exports[`throws error when invoked before it's available 2`] = `"Plugin accessed before it's available"`;

exports[`throws error when invoked before it's available 3`] = `"Plugin accessed before it's available"`;

exports[`throws error when invoked when it's not enabled 1`] = `"Plugin isn't enabled, check isEnabled before using"`;

exports[`throws error when invoked when it's not enabled 2`] = `"Plugin isn't enabled, check isEnabled before using"`;

exports[`throws error when invoked when it's not enabled 3`] = `"Plugin isn't enabled, check isEnabled before using"`;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`#atSpace throws error when checking for login and user has login but doesn't have version 1`] = `[Error: Multiple versions of Kibana are running against the same Elasticsearch cluster, unable to authorize user.]`;

exports[`#atSpace with a malformed Elasticsearch response throws a validation error when an extra privilege is present in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "space:space_1" fails because ["saved_object:bar-type/get" is not allowed]]]]`;

exports[`#atSpace with a malformed Elasticsearch response throws a validation error when privileges are missing in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "space:space_1" fails because [child "saved_object:foo-type/get" fails because ["saved_object:foo-type/get" is required]]]]]`;

exports[`#atSpaces throws error when Elasticsearch returns malformed response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "space:space_1" fails because [child "mock-action:version" fails because ["mock-action:version" is required]]]]]`;

exports[`#atSpaces throws error when checking for login and user has login but doesn't have version 1`] = `[Error: Multiple versions of Kibana are running against the same Elasticsearch cluster, unable to authorize user.]`;

exports[`#atSpaces with a malformed Elasticsearch response throws a validation error when an a space is missing in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "space:space_2" fails because ["space:space_2" is required]]]]`;

exports[`#atSpaces with a malformed Elasticsearch response throws a validation error when an extra privilege is present in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "space:space_2" fails because ["space:space_2" is required]]]]`;

exports[`#atSpaces with a malformed Elasticsearch response throws a validation error when an extra space is present in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because ["space:space_3" is not allowed]]]`;

exports[`#atSpaces with a malformed Elasticsearch response throws a validation error when privileges are missing in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "space:space_2" fails because ["space:space_2" is required]]]]`;

exports[`#globally throws error when Elasticsearch returns malformed response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "*" fails because [child "mock-action:version" fails because ["mock-action:version" is required]]]]]`;

exports[`#globally throws error when checking for login and user has login but doesn't have version 1`] = `[Error: Multiple versions of Kibana are running against the same Elasticsearch cluster, unable to authorize user.]`;

exports[`#globally with a malformed Elasticsearch response throws a validation error when an extra privilege is present in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "*" fails because ["saved_object:bar-type/get" is not allowed]]]]`;

exports[`#globally with a malformed Elasticsearch response throws a validation error when privileges are missing in the response 1`] = `[Error: Invalid response received from Elasticsearch has_privilege endpoint. ValidationError: child "application" fails because [child "kibana-our_application" fails because [child "*" fails because [child "saved_object:foo-type/get" fails because ["saved_object:foo-type/get" is required]]]]]`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`usingPrivileges checkPrivileges errors otherwise it throws the error 1`] = `"something else entirely"`;
Loading