mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
enable security plugin in basic (#35890)
enable security on file dataviz and import (ML plugin) update unit tests add api test coverage for security in basic move audit logging to standard+ license level
This commit is contained in:
parent
015c83158c
commit
510ab8c6b1
33 changed files with 397 additions and 281 deletions
|
@ -26,11 +26,12 @@ import { setupUsers, DEFAULT_SUPERUSER_PASS } from './auth';
|
|||
export async function runElasticsearch({ config, options }) {
|
||||
const { log, esFrom } = options;
|
||||
const license = config.get('esTestCluster.license');
|
||||
const isTrialLicense = config.get('esTestCluster.license') === 'trial';
|
||||
const esArgs = config.get('esTestCluster.serverArgs');
|
||||
const isSecurityEnabled = esArgs.includes('xpack.security.enabled=true');
|
||||
|
||||
const cluster = createEsTestCluster({
|
||||
port: config.get('servers.elasticsearch.port'),
|
||||
password: isTrialLicense
|
||||
password: isSecurityEnabled
|
||||
? DEFAULT_SUPERUSER_PASS
|
||||
: config.get('servers.elasticsearch.password'),
|
||||
license,
|
||||
|
@ -40,11 +41,9 @@ export async function runElasticsearch({ config, options }) {
|
|||
dataArchive: config.get('esTestCluster.dataArchive'),
|
||||
});
|
||||
|
||||
const esArgs = config.get('esTestCluster.serverArgs');
|
||||
|
||||
await cluster.start(esArgs);
|
||||
|
||||
if (isTrialLicense) {
|
||||
if (isSecurityEnabled) {
|
||||
await setupUsers(log, config.get('servers.elasticsearch.port'), [
|
||||
config.get('servers.elasticsearch'),
|
||||
config.get('servers.kibana'),
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import expect from '@kbn/expect';
|
||||
import sinon from 'sinon';
|
||||
import { set } from 'lodash';
|
||||
import { checkLicense, isBasicLicense } from '../check_license';
|
||||
import { checkLicense } from '../check_license';
|
||||
|
||||
describe('check_license', () => {
|
||||
|
||||
|
@ -151,31 +151,3 @@ describe('check_license', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
function mockServerFactory(licenseType = 'basic') {
|
||||
return {
|
||||
plugins: {
|
||||
xpack_main: {
|
||||
info: {
|
||||
license: {
|
||||
getType: () => licenseType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe('isBasicLicense', () => {
|
||||
describe('license information is basic', () => {
|
||||
it('should be true', () => {
|
||||
expect(isBasicLicense(mockServerFactory())).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('license information is gold', () => {
|
||||
it('should be true', () => {
|
||||
expect(isBasicLicense(mockServerFactory('gold'))).to.be(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -68,9 +68,3 @@ export function checkLicense(xpackLicenseInfo) {
|
|||
hasExpired: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function isBasicLicense(server) {
|
||||
const xpackMainPlugin = server.plugins.xpack_main;
|
||||
const xpackInfo = (xpackMainPlugin && xpackMainPlugin.info);
|
||||
return (xpackInfo.license.getType() === 'basic');
|
||||
}
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
|
||||
|
||||
export { checkLicense, isBasicLicense } from './check_license';
|
||||
export { checkLicense } from './check_license';
|
||||
|
|
|
@ -14,7 +14,6 @@ import { polledDataCheckerFactory } from './polled_data_checker';
|
|||
|
||||
import { callWithInternalUserFactory } from '../../client/call_with_internal_user_factory';
|
||||
import { isSecurityDisabled } from '../../lib/security_utils';
|
||||
import { isBasicLicense } from '../../lib/check_license';
|
||||
|
||||
export function estimateBucketSpanFactory(callWithRequest, server) {
|
||||
const callWithInternalUser = callWithInternalUserFactory(server);
|
||||
|
@ -373,7 +372,7 @@ export function estimateBucketSpanFactory(callWithRequest, server) {
|
|||
});
|
||||
}
|
||||
|
||||
if (isBasicLicense(server) || isSecurityDisabled(server)) {
|
||||
if (isSecurityDisabled(server)) {
|
||||
getBucketSpanEstimation();
|
||||
} else {
|
||||
// if security is enabled, check that the user has permission to
|
||||
|
|
|
@ -14,7 +14,6 @@ import { wrapError } from '../client/errors';
|
|||
import Boom from 'boom';
|
||||
|
||||
import { isSecurityDisabled } from '../lib/security_utils';
|
||||
import { isBasicLicense } from '../lib/check_license';
|
||||
|
||||
export function systemRoutes(server, commonRouteConfig) {
|
||||
const callWithInternalUser = callWithInternalUserFactory(server);
|
||||
|
@ -61,11 +60,7 @@ export function systemRoutes(server, commonRouteConfig) {
|
|||
}
|
||||
}
|
||||
|
||||
// isSecurityDisabled will return true if it is a basic license
|
||||
// this will cause the subsequent ml.privilegeCheck to fail.
|
||||
// therefore, check for a basic license first and report that security
|
||||
// is disabled because its not available on basic
|
||||
if (isBasicLicense(server) || isSecurityDisabled(server)) {
|
||||
if (isSecurityDisabled(server)) {
|
||||
// if xpack.security.enabled has been explicitly set to false
|
||||
// return that security is disabled and don't call the privilegeCheck endpoint
|
||||
return {
|
||||
|
@ -95,7 +90,7 @@ export function systemRoutes(server, commonRouteConfig) {
|
|||
return new Promise((resolve, reject) => {
|
||||
// check for basic license first for consistency with other
|
||||
// security disabled checks
|
||||
if (isBasicLicense(server) || isSecurityDisabled(server)) {
|
||||
if (isSecurityDisabled(server)) {
|
||||
getNodeCount()
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
|
|
|
@ -130,7 +130,7 @@ export const security = (kibana) => new kibana.Plugin({
|
|||
}
|
||||
});
|
||||
|
||||
const auditLogger = new SecurityAuditLogger(server.config(), new AuditLogger(server, 'security'));
|
||||
const auditLogger = new SecurityAuditLogger(new AuditLogger(server, 'security', server.config(), xpackInfo));
|
||||
|
||||
const { savedObjects } = server;
|
||||
savedObjects.setScopedSavedObjectsClientFactory(({
|
||||
|
|
|
@ -34,8 +34,6 @@ describe('lib/auth_redirect', function () {
|
|||
.isAvailable.returns(true);
|
||||
server.plugins.xpack_main.info
|
||||
.feature.returns({ isEnabled: sinon.stub().returns(true) });
|
||||
server.plugins.xpack_main.info
|
||||
.license.isOneOf.returns(false);
|
||||
|
||||
authenticate = authenticateFactory(server);
|
||||
});
|
||||
|
@ -128,12 +126,4 @@ describe('lib/auth_redirect', function () {
|
|||
sinon.assert.notCalled(h.redirect);
|
||||
});
|
||||
|
||||
it('replies with no credentials when license is basic', async () => {
|
||||
server.plugins.xpack_main.info.license.isOneOf.returns(true);
|
||||
|
||||
await authenticate(request, h);
|
||||
|
||||
sinon.assert.calledWith(h.authenticated, { credentials: {} });
|
||||
sinon.assert.notCalled(h.redirect);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -58,21 +58,21 @@ describe('check_license', function () {
|
|||
});
|
||||
|
||||
|
||||
it('should not show login page or other security elements if license is basic.', () => {
|
||||
it('should show login page and other security elements if license is basic and security is enabled.', () => {
|
||||
mockXPackInfo.license.isOneOf.withArgs(['basic']).returns(true);
|
||||
mockXPackInfo.license.isOneOf.withArgs(['platinum', 'trial']).returns(false);
|
||||
mockXPackInfo.feature.withArgs('security').returns({
|
||||
isEnabled: () => { return true; }
|
||||
});
|
||||
|
||||
const licenseCheckResults = checkLicense(mockXPackInfo);
|
||||
expect(licenseCheckResults).to.be.eql({
|
||||
showLogin: false,
|
||||
allowLogin: false,
|
||||
showLinks: false,
|
||||
showLogin: true,
|
||||
allowLogin: true,
|
||||
showLinks: true,
|
||||
allowRoleDocumentLevelSecurity: false,
|
||||
allowRoleFieldLevelSecurity: false,
|
||||
allowRbac: false,
|
||||
linksMessage: 'Your Basic license does not support Security. Please upgrade your license.'
|
||||
allowRbac: true
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -5,16 +5,11 @@
|
|||
*/
|
||||
|
||||
export class SecurityAuditLogger {
|
||||
constructor(config, auditLogger) {
|
||||
this._enabled = config.get('xpack.security.audit.enabled');
|
||||
constructor(auditLogger) {
|
||||
this._auditLogger = auditLogger;
|
||||
}
|
||||
|
||||
savedObjectsAuthorizationFailure(username, action, types, missing, args) {
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._auditLogger.log(
|
||||
'saved_objects_authorization_failure',
|
||||
`${username} unauthorized to ${action} ${types.join(',')}, missing ${missing.join(',')}`,
|
||||
|
@ -29,10 +24,6 @@ export class SecurityAuditLogger {
|
|||
}
|
||||
|
||||
savedObjectsAuthorizationSuccess(username, action, types, args) {
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._auditLogger.log(
|
||||
'saved_objects_authorization_success',
|
||||
`${username} authorized to ${action} ${types.join(',')}`,
|
||||
|
|
|
@ -5,19 +5,6 @@
|
|||
*/
|
||||
import { SecurityAuditLogger } from './audit_logger';
|
||||
|
||||
|
||||
const createMockConfig = (settings) => {
|
||||
const mockConfig = {
|
||||
get: jest.fn()
|
||||
};
|
||||
|
||||
mockConfig.get.mockImplementation(key => {
|
||||
return settings[key];
|
||||
});
|
||||
|
||||
return mockConfig;
|
||||
};
|
||||
|
||||
const createMockAuditLogger = () => {
|
||||
return {
|
||||
log: jest.fn()
|
||||
|
@ -25,24 +12,10 @@ const createMockAuditLogger = () => {
|
|||
};
|
||||
|
||||
describe(`#savedObjectsAuthorizationFailure`, () => {
|
||||
test(`doesn't log anything when xpack.security.audit.enabled is false`, () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.audit.enabled': false
|
||||
});
|
||||
|
||||
test('logs via auditLogger', () => {
|
||||
const auditLogger = createMockAuditLogger();
|
||||
|
||||
const securityAuditLogger = new SecurityAuditLogger(config, auditLogger);
|
||||
securityAuditLogger.savedObjectsAuthorizationFailure();
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('logs via auditLogger when xpack.security.audit.enabled is true', () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.audit.enabled': true
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
const securityAuditLogger = new SecurityAuditLogger(config, auditLogger);
|
||||
const securityAuditLogger = new SecurityAuditLogger(auditLogger);
|
||||
const username = 'foo-user';
|
||||
const action = 'foo-action';
|
||||
const types = [ 'foo-type-1', 'foo-type-2' ];
|
||||
|
@ -69,24 +42,9 @@ describe(`#savedObjectsAuthorizationFailure`, () => {
|
|||
});
|
||||
|
||||
describe(`#savedObjectsAuthorizationSuccess`, () => {
|
||||
test(`doesn't log anything when xpack.security.audit.enabled is false`, () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.audit.enabled': false
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
|
||||
const securityAuditLogger = new SecurityAuditLogger(config, auditLogger);
|
||||
securityAuditLogger.savedObjectsAuthorizationSuccess();
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('logs via auditLogger when xpack.security.audit.enabled is true', () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.audit.enabled': true
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
const securityAuditLogger = new SecurityAuditLogger(config, auditLogger);
|
||||
const securityAuditLogger = new SecurityAuditLogger(auditLogger);
|
||||
const username = 'foo-user';
|
||||
const action = 'foo-action';
|
||||
const types = [ 'foo-type-1', 'foo-type-2' ];
|
||||
|
|
|
@ -16,11 +16,10 @@ import { wrapError } from './errors';
|
|||
*/
|
||||
export function authenticateFactory(server) {
|
||||
return async function authenticate(request, h) {
|
||||
// If security is disabled or license is basic, continue with no user credentials
|
||||
// If security is disabled continue with no user credentials
|
||||
// and delete the client cookie as well.
|
||||
const xpackInfo = server.plugins.xpack_main.info;
|
||||
if (xpackInfo.isAvailable()
|
||||
&& (!xpackInfo.feature('security').isEnabled() || xpackInfo.license.isOneOf('basic'))) {
|
||||
if (xpackInfo.isAvailable() && !xpackInfo.feature('security').isEnabled()) {
|
||||
return h.authenticated({ credentials: {} });
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,8 @@ export function checkLicense(xPackInfo) {
|
|||
};
|
||||
}
|
||||
|
||||
const isLicenseBasic = xPackInfo.license.isOneOf(['basic']);
|
||||
const isEnabledInES = xPackInfo.feature('security').isEnabled();
|
||||
if (!isEnabledInES || isLicenseBasic) {
|
||||
if (!isEnabledInES) {
|
||||
return {
|
||||
showLogin: false,
|
||||
allowLogin: false,
|
||||
|
@ -47,11 +46,8 @@ export function checkLicense(xPackInfo) {
|
|||
allowRoleDocumentLevelSecurity: false,
|
||||
allowRoleFieldLevelSecurity: false,
|
||||
allowRbac: false,
|
||||
linksMessage: isLicenseBasic
|
||||
? 'Your Basic license does not support Security. Please upgrade your license.'
|
||||
: 'Access is denied because Security is disabled in Elasticsearch.'
|
||||
linksMessage: 'Access is denied because Security is disabled in Elasticsearch.'
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const isLicensePlatinumOrTrial = xPackInfo.license.isOneOf(['platinum', 'trial']);
|
||||
|
|
|
@ -110,7 +110,9 @@ export const spaces = (kibana: any) =>
|
|||
|
||||
const config = server.config();
|
||||
|
||||
const spacesAuditLogger = new SpacesAuditLogger(config, new AuditLogger(server, 'spaces'));
|
||||
const spacesAuditLogger = new SpacesAuditLogger(
|
||||
new AuditLogger(server, 'spaces', config, xpackMainPlugin.info)
|
||||
);
|
||||
|
||||
server.expose('spacesClient', {
|
||||
getScopedClient: (request: any) => {
|
||||
|
|
|
@ -5,22 +5,6 @@
|
|||
*/
|
||||
import { SpacesAuditLogger } from './audit_logger';
|
||||
|
||||
const createMockConfig = (settings: { [key: string]: any } = {}) => {
|
||||
const mockConfig = {
|
||||
get: jest.fn(),
|
||||
};
|
||||
|
||||
mockConfig.get.mockImplementation(key => {
|
||||
if (!settings.hasOwnProperty(key)) {
|
||||
throw new Error('Undefined key, mock schema error');
|
||||
}
|
||||
|
||||
return settings[key];
|
||||
});
|
||||
|
||||
return mockConfig;
|
||||
};
|
||||
|
||||
const createMockAuditLogger = () => {
|
||||
return {
|
||||
log: jest.fn(),
|
||||
|
@ -28,38 +12,9 @@ const createMockAuditLogger = () => {
|
|||
};
|
||||
|
||||
describe(`#savedObjectsAuthorizationFailure`, () => {
|
||||
test(`doesn't log anything when xpack.security.enabled is false`, () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': false,
|
||||
});
|
||||
test('logs auth failure with spaceIds via auditLogger', () => {
|
||||
const auditLogger = createMockAuditLogger();
|
||||
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
securityAuditLogger.spacesAuthorizationFailure('foo-user', 'foo-action');
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test(`doesn't log anything when xpack.security.audit.enabled is false`, () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': false,
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
securityAuditLogger.spacesAuthorizationFailure('foo-user', 'foo-action');
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('logs with spaceIds via auditLogger when xpack.security.audit.enabled is true', () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': true,
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
const securityAuditLogger = new SpacesAuditLogger(auditLogger);
|
||||
const username = 'foo-user';
|
||||
const action = 'foo-action';
|
||||
const spaceIds = ['foo-space-1', 'foo-space-2'];
|
||||
|
@ -77,13 +32,9 @@ describe(`#savedObjectsAuthorizationFailure`, () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('logs without spaceIds via auditLogger when xpack.security.audit.enabled is true', () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': true,
|
||||
});
|
||||
test('logs auth failure without spaceIds via auditLogger', () => {
|
||||
const auditLogger = createMockAuditLogger();
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
const securityAuditLogger = new SpacesAuditLogger(auditLogger);
|
||||
const username = 'foo-user';
|
||||
const action = 'foo-action';
|
||||
|
||||
|
@ -101,38 +52,9 @@ describe(`#savedObjectsAuthorizationFailure`, () => {
|
|||
});
|
||||
|
||||
describe(`#savedObjectsAuthorizationSuccess`, () => {
|
||||
test(`doesn't log anything when xpack.security.enabled is false`, () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': false,
|
||||
});
|
||||
test('logs auth success with spaceIds via auditLogger', () => {
|
||||
const auditLogger = createMockAuditLogger();
|
||||
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
securityAuditLogger.spacesAuthorizationSuccess('foo-user', 'foo-action');
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test(`doesn't log anything when xpack.security.audit.enabled is false`, () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': false,
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
securityAuditLogger.spacesAuthorizationSuccess('foo-user', 'foo-action');
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('logs with spaceIds via auditLogger when xpack.security.audit.enabled is true', () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': true,
|
||||
});
|
||||
const auditLogger = createMockAuditLogger();
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
const securityAuditLogger = new SpacesAuditLogger(auditLogger);
|
||||
const username = 'foo-user';
|
||||
const action = 'foo-action';
|
||||
const spaceIds = ['foo-space-1', 'foo-space-2'];
|
||||
|
@ -150,13 +72,9 @@ describe(`#savedObjectsAuthorizationSuccess`, () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('logs without spaceIds via auditLogger when xpack.security.audit.enabled is true', () => {
|
||||
const config = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': true,
|
||||
});
|
||||
test('logs auth success without spaceIds via auditLogger', () => {
|
||||
const auditLogger = createMockAuditLogger();
|
||||
const securityAuditLogger = new SpacesAuditLogger(config, auditLogger);
|
||||
const securityAuditLogger = new SpacesAuditLogger(auditLogger);
|
||||
const username = 'foo-user';
|
||||
const action = 'foo-action';
|
||||
|
||||
|
|
|
@ -5,19 +5,12 @@
|
|||
*/
|
||||
|
||||
export class SpacesAuditLogger {
|
||||
private readonly enabled: boolean;
|
||||
private readonly auditLogger: any;
|
||||
|
||||
constructor(config: any, auditLogger: any) {
|
||||
this.enabled =
|
||||
config.get('xpack.security.enabled') && config.get('xpack.security.audit.enabled');
|
||||
constructor(auditLogger: any) {
|
||||
this.auditLogger = auditLogger;
|
||||
}
|
||||
public spacesAuthorizationFailure(username: string, action: string, spaceIds?: string[]) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.auditLogger.log(
|
||||
'spaces_authorization_failure',
|
||||
`${username} unauthorized to ${action}${spaceIds ? ' ' + spaceIds.join(',') : ''} spaces`,
|
||||
|
@ -30,10 +23,6 @@ export class SpacesAuditLogger {
|
|||
}
|
||||
|
||||
public spacesAuthorizationSuccess(username: string, action: string, spaceIds?: string[]) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.auditLogger.log(
|
||||
'spaces_authorization_success',
|
||||
`${username} authorized to ${action}${spaceIds ? ' ' + spaceIds.join(',') : ''} spaces`,
|
||||
|
|
|
@ -26,11 +26,6 @@ export async function replaceInjectedVars(originalInjectedVars, request, server)
|
|||
return originalInjectedVars;
|
||||
}
|
||||
|
||||
// authentication is not a thing you can do
|
||||
if (xpackInfo.license.isOneOf('basic')) {
|
||||
return await withXpackInfo();
|
||||
}
|
||||
|
||||
// request is not authenticated
|
||||
if (!await server.plugins.security.isAuthenticated(request)) {
|
||||
return originalInjectedVars;
|
||||
|
|
|
@ -9,14 +9,18 @@ require('@kbn/test').runTestsCli([
|
|||
require.resolve('../test/reporting/configs/chromium_api.js'),
|
||||
require.resolve('../test/reporting/configs/chromium_functional.js'),
|
||||
require.resolve('../test/functional/config.js'),
|
||||
require.resolve('../test/api_integration/config_security_basic.js'),
|
||||
require.resolve('../test/api_integration/config.js'),
|
||||
require.resolve('../test/plugin_api_integration/config.js'),
|
||||
require.resolve('../test/saml_api_integration/config.js'),
|
||||
require.resolve('../test/token_api_integration/config.js'),
|
||||
require.resolve('../test/spaces_api_integration/spaces_only/config'),
|
||||
require.resolve('../test/spaces_api_integration/security_and_spaces/config'),
|
||||
require.resolve('../test/saved_object_api_integration/security_and_spaces/config'),
|
||||
require.resolve('../test/saved_object_api_integration/security_only/config'),
|
||||
require.resolve('../test/spaces_api_integration/security_and_spaces/config_trial'),
|
||||
require.resolve('../test/spaces_api_integration/security_and_spaces/config_basic'),
|
||||
require.resolve('../test/saved_object_api_integration/security_and_spaces/config_trial'),
|
||||
require.resolve('../test/saved_object_api_integration/security_and_spaces/config_basic'),
|
||||
require.resolve('../test/saved_object_api_integration/security_only/config_trial'),
|
||||
require.resolve('../test/saved_object_api_integration/security_only/config_basic'),
|
||||
require.resolve('../test/saved_object_api_integration/spaces_only/config'),
|
||||
require.resolve('../test/upgrade_assistant_integration/config'),
|
||||
]);
|
||||
|
|
|
@ -3,17 +3,113 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const LICENSE_TYPE_BASIC = 'basic';
|
||||
export const LICENSE_TYPE_STANDARD = 'standard';
|
||||
export const LICENSE_TYPE_GOLD = 'gold';
|
||||
export const LICENSE_TYPE_PLATINUM = 'platinum';
|
||||
export const LICENSE_TYPE_TRIAL = 'trial';
|
||||
|
||||
export const LICENSE_STATUS_UNAVAILABLE = 'UNAVAILABLE';
|
||||
export const LICENSE_STATUS_INVALID = 'INVALID';
|
||||
export const LICENSE_STATUS_EXPIRED = 'EXPIRED';
|
||||
export const LICENSE_STATUS_VALID = 'VALID';
|
||||
|
||||
// These are ordered from least featureful to most featureful, so we can assume that someone holding
|
||||
// a license at a particular index cannot access any features unlocked by the licenses that follow it.
|
||||
const RANKED_LICENSE_TYPES = [
|
||||
LICENSE_TYPE_BASIC,
|
||||
LICENSE_TYPE_STANDARD,
|
||||
LICENSE_TYPE_GOLD,
|
||||
LICENSE_TYPE_PLATINUM,
|
||||
LICENSE_TYPE_TRIAL,
|
||||
];
|
||||
|
||||
const FEATURE = {
|
||||
ID: 'audit_logging'
|
||||
};
|
||||
|
||||
export class AuditLogger {
|
||||
constructor(server, pluginId) {
|
||||
constructor(server, pluginId, config, xPackInfo) {
|
||||
this._server = server;
|
||||
this._pluginId = pluginId;
|
||||
this._enabled = config.get('xpack.security.enabled') && config.get('xpack.security.audit.enabled');
|
||||
this._licensed = false;
|
||||
this._checkLicense = (xPackInfo) => {
|
||||
this._licensed = checkLicense(FEATURE.ID, LICENSE_TYPE_STANDARD, xPackInfo).status === LICENSE_STATUS_VALID;
|
||||
};
|
||||
xPackInfo.feature(`${FEATURE.ID}-${pluginId}`).registerLicenseCheckResultsGenerator(this._checkLicense);
|
||||
this._checkLicense(xPackInfo);
|
||||
}
|
||||
|
||||
log(eventType, message, data = {}) {
|
||||
if(!this._licensed || !this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._server.logWithMetadata(['info', 'audit', this._pluginId, eventType], message, {
|
||||
...data,
|
||||
eventType,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function checkLicense(pluginName, minimumLicenseRequired, xpackLicenseInfo) {
|
||||
if(!RANKED_LICENSE_TYPES.includes(minimumLicenseRequired)) {
|
||||
throw new Error(`Invalid license type supplied to checkLicense: ${minimumLicenseRequired}`);
|
||||
}
|
||||
|
||||
// If, for some reason, we cannot get the license information
|
||||
// from Elasticsearch, assume worst case and disable
|
||||
if (!xpackLicenseInfo || !xpackLicenseInfo.isAvailable()) {
|
||||
return {
|
||||
status: LICENSE_STATUS_UNAVAILABLE,
|
||||
message: i18n.translate(
|
||||
'xpack.server.checkLicense.errorUnavailableMessage',
|
||||
{
|
||||
defaultMessage: 'You cannot use {pluginName} because license information is not available at this time.',
|
||||
values: { pluginName },
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const { license } = xpackLicenseInfo;
|
||||
const isLicenseModeValid = license.isOneOf([...RANKED_LICENSE_TYPES].splice(RANKED_LICENSE_TYPES.indexOf(minimumLicenseRequired)));
|
||||
const isLicenseActive = license.isActive();
|
||||
const licenseType = license.getType();
|
||||
|
||||
// License is not valid
|
||||
if (!isLicenseModeValid) {
|
||||
return {
|
||||
status: LICENSE_STATUS_INVALID,
|
||||
message: i18n.translate(
|
||||
'xpack.server.checkLicense.errorUnsupportedMessage',
|
||||
{
|
||||
defaultMessage: 'Your {licenseType} license does not support {pluginName}. Please upgrade your license.',
|
||||
values: { licenseType, pluginName },
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// License is valid but not active
|
||||
if (!isLicenseActive) {
|
||||
return {
|
||||
status: LICENSE_STATUS_EXPIRED,
|
||||
message: i18n.translate(
|
||||
'xpack.server.checkLicense.errorExpiredMessage',
|
||||
{
|
||||
defaultMessage: 'You cannot use {pluginName} because your {licenseType} license has expired',
|
||||
values: { licenseType, pluginName },
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// License is valid and active
|
||||
return {
|
||||
status: LICENSE_STATUS_VALID,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,14 +3,42 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { AuditLogger } from './audit_logger';
|
||||
import { AuditLogger, LICENSE_TYPE_STANDARD, LICENSE_TYPE_BASIC, LICENSE_TYPE_GOLD } from './audit_logger';
|
||||
|
||||
const createMockConfig = (settings) => {
|
||||
const mockConfig = {
|
||||
get: jest.fn()
|
||||
};
|
||||
|
||||
mockConfig.get.mockImplementation(key => {
|
||||
return settings[key];
|
||||
});
|
||||
|
||||
return mockConfig;
|
||||
};
|
||||
|
||||
const mockLicenseInfo = {
|
||||
isAvailable: () => true,
|
||||
feature: () => { return { registerLicenseCheckResultsGenerator: () => { return; } };},
|
||||
license: {
|
||||
isActive: () => true,
|
||||
isOneOf: () => true,
|
||||
getType: () => LICENSE_TYPE_STANDARD
|
||||
}
|
||||
};
|
||||
|
||||
const mockConfig = createMockConfig({
|
||||
'xpack.security.enabled': true,
|
||||
'xpack.security.audit.enabled': true,
|
||||
});
|
||||
|
||||
test(`calls server.log with 'info', audit', pluginId and eventType as tags`, () => {
|
||||
const mockServer = {
|
||||
logWithMetadata: jest.fn()
|
||||
};
|
||||
|
||||
const pluginId = 'foo';
|
||||
const auditLogger = new AuditLogger(mockServer, pluginId);
|
||||
const auditLogger = new AuditLogger(mockServer, pluginId, mockConfig, mockLicenseInfo);
|
||||
|
||||
const eventType = 'bar';
|
||||
auditLogger.log(eventType, '');
|
||||
|
@ -18,13 +46,11 @@ test(`calls server.log with 'info', audit', pluginId and eventType as tags`, ()
|
|||
expect(mockServer.logWithMetadata).toHaveBeenCalledWith(['info', 'audit', pluginId, eventType], expect.anything(), expect.anything());
|
||||
});
|
||||
|
||||
|
||||
test(`calls server.log with message`, () => {
|
||||
const mockServer = {
|
||||
logWithMetadata: jest.fn()
|
||||
};
|
||||
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo');
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo', mockConfig, mockLicenseInfo);
|
||||
|
||||
const message = 'summary of what happened';
|
||||
auditLogger.log('bar', message);
|
||||
|
@ -37,7 +63,7 @@ test(`calls server.log with metadata `, () => {
|
|||
logWithMetadata: jest.fn()
|
||||
};
|
||||
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo');
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo', mockConfig, mockLicenseInfo);
|
||||
|
||||
const data = {
|
||||
foo: 'yup',
|
||||
|
@ -52,3 +78,88 @@ test(`calls server.log with metadata `, () => {
|
|||
baz: data.baz,
|
||||
});
|
||||
});
|
||||
|
||||
test(`does not call server.log for license level < Standard`, () => {
|
||||
const mockServer = {
|
||||
logWithMetadata: jest.fn()
|
||||
};
|
||||
const mockLicenseInfo = {
|
||||
isAvailable: () => true,
|
||||
feature: () => { return { registerLicenseCheckResultsGenerator: () => { return; } };},
|
||||
license: {
|
||||
isActive: () => true,
|
||||
isOneOf: () => false,
|
||||
getType: () => LICENSE_TYPE_BASIC
|
||||
}
|
||||
};
|
||||
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo', mockConfig, mockLicenseInfo);
|
||||
auditLogger.log('bar', 'what happened');
|
||||
expect(mockServer.logWithMetadata).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test(`does not call server.log if security is not enabled`, () => {
|
||||
const mockServer = {
|
||||
logWithMetadata: jest.fn()
|
||||
};
|
||||
|
||||
const mockConfig = createMockConfig({
|
||||
'xpack.security.enabled': false,
|
||||
'xpack.security.audit.enabled': true,
|
||||
});
|
||||
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo', mockConfig, mockLicenseInfo);
|
||||
auditLogger.log('bar', 'what happened');
|
||||
expect(mockServer.logWithMetadata).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test(`does not call server.log if security audit logging is not enabled`, () => {
|
||||
const mockServer = {
|
||||
logWithMetadata: jest.fn()
|
||||
};
|
||||
|
||||
const mockConfig = createMockConfig({
|
||||
'xpack.security.enabled': true
|
||||
});
|
||||
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo', mockConfig, mockLicenseInfo);
|
||||
auditLogger.log('bar', 'what happened');
|
||||
expect(mockServer.logWithMetadata).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test(`calls server.log after basic -> gold upgrade`, () => {
|
||||
const mockServer = {
|
||||
logWithMetadata: jest.fn()
|
||||
};
|
||||
|
||||
const endLicenseInfo = {
|
||||
isAvailable: () => true,
|
||||
license: {
|
||||
isActive: () => true,
|
||||
isOneOf: () => true,
|
||||
getType: () => LICENSE_TYPE_GOLD
|
||||
}
|
||||
};
|
||||
|
||||
let licenseCheckResultsGenerator;
|
||||
|
||||
const startLicenseInfo = {
|
||||
isAvailable: () => true,
|
||||
feature: () => { return { registerLicenseCheckResultsGenerator: (fn) => { licenseCheckResultsGenerator = fn; } };},
|
||||
license: {
|
||||
isActive: () => true,
|
||||
isOneOf: () => false,
|
||||
getType: () => LICENSE_TYPE_BASIC
|
||||
}
|
||||
};
|
||||
|
||||
const auditLogger = new AuditLogger(mockServer, 'foo', mockConfig, startLicenseInfo);
|
||||
auditLogger.log('bar', 'what happened');
|
||||
expect(mockServer.logWithMetadata).toHaveBeenCalledTimes(0);
|
||||
|
||||
//change basic to gold
|
||||
licenseCheckResultsGenerator(endLicenseInfo);
|
||||
auditLogger.log('bar', 'what happened');
|
||||
expect(mockServer.logWithMetadata).toHaveBeenCalledTimes(1);
|
||||
|
||||
});
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
*/
|
||||
|
||||
export default function ({ loadTestFile }) {
|
||||
describe('security', () => {
|
||||
describe('security', function () {
|
||||
this.tags('ciGroup6');
|
||||
|
||||
loadTestFile(require.resolve('./basic_login'));
|
||||
loadTestFile(require.resolve('./roles'));
|
||||
});
|
||||
|
|
|
@ -9,6 +9,8 @@ import expect from '@kbn/expect';
|
|||
export default function ({ getService }) {
|
||||
const es = getService('es');
|
||||
const supertest = getService('supertest');
|
||||
const config = getService('config');
|
||||
const basic = config.get('esTestCluster.license') === 'basic';
|
||||
|
||||
describe('Roles', () => {
|
||||
describe('Create Role', () => {
|
||||
|
@ -30,13 +32,8 @@ export default function ({ getService }) {
|
|||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*']
|
||||
},
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
run_as: ['watcher_user'],
|
||||
|
@ -57,11 +54,6 @@ export default function ({ getService }) {
|
|||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
allow_restricted_indices: false,
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*']
|
||||
},
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
|
@ -81,6 +73,33 @@ export default function ({ getService }) {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
it(`should ${basic ? 'not' : ''} create a role with kibana and FLS/DLS elasticsearch
|
||||
privileges on ${basic ? 'basic' : 'trial'} licenses`, async () => {
|
||||
await supertest.put('/api/security/role/role_with_privileges_dls_fls')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*']
|
||||
},
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
run_as: ['watcher_user'],
|
||||
},
|
||||
})
|
||||
.expect(basic ? 403 : 204);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update Role', () => {
|
||||
|
@ -93,11 +112,6 @@ export default function ({ getService }) {
|
|||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
field_security: {
|
||||
grant: ['request.*'],
|
||||
except: ['response.*']
|
||||
},
|
||||
query: `{ "match": { "host.name": "localhost" } }`,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
|
@ -129,13 +143,8 @@ export default function ({ getService }) {
|
|||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*']
|
||||
},
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
allow_restricted_indices: true,
|
||||
},
|
||||
],
|
||||
|
@ -157,11 +166,6 @@ export default function ({ getService }) {
|
|||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
allow_restricted_indices: true,
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*']
|
||||
},
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
|
@ -186,20 +190,75 @@ export default function ({ getService }) {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
it(`should ${basic ? 'not' : ''} update a role adding DLS and TLS priviledges
|
||||
when using ${basic ? 'basic' : 'trial'} license`, async () => {
|
||||
|
||||
await es.shield.putRole({
|
||||
name: 'role_to_update_with_dls_fls',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
run_as: ['reporting_user'],
|
||||
}
|
||||
});
|
||||
|
||||
await supertest.put('/api/security/role/role_to_update_with_dls_fls')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.send({
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*']
|
||||
},
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read'],
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
run_as: ['watcher_user'],
|
||||
},
|
||||
})
|
||||
.expect(basic ? 403 : 204);
|
||||
|
||||
const role = await es.shield.getRole({ name: 'role_to_update_with_dls_fls' });
|
||||
|
||||
expect(role.role_to_update_with_dls_fls.cluster).to.eql(basic ? ['monitor'] : ['manage']);
|
||||
expect(role.role_to_update_with_dls_fls.run_as).to.eql(basic ? ['reporting_user'] : ['watcher_user']);
|
||||
expect(role.role_to_update_with_dls_fls.indices[0].names).to.eql(basic ? ['beats-*'] : ['logstash-*']);
|
||||
expect(role.role_to_update_with_dls_fls.indices[0].query).to.eql(basic ? undefined : `{ "match": { "geo.src": "CN" } }`);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete Role', () => {
|
||||
it('should delete the three roles we created', async () => {
|
||||
it('should delete the roles we created', async () => {
|
||||
|
||||
await supertest.delete('/api/security/role/empty_role').set('kbn-xsrf', 'xxx').expect(204);
|
||||
await supertest.delete('/api/security/role/role_with_privileges').set('kbn-xsrf', 'xxx').expect(204);
|
||||
await supertest.delete('/api/security/role/role_with_privileges_dls_fls').set('kbn-xsrf', 'xxx').expect(basic ? 404 : 204);
|
||||
await supertest.delete('/api/security/role/role_to_update').set('kbn-xsrf', 'xxx').expect(204);
|
||||
await supertest.delete('/api/security/role/role_to_update_with_dls_fls').set('kbn-xsrf', 'xxx').expect(204);
|
||||
|
||||
const emptyRole = await es.shield.getRole({ name: 'empty_role', ignore: [404] });
|
||||
expect(emptyRole).to.eql({});
|
||||
const roleWithPrivileges = await es.shield.getRole({ name: 'role_with_privileges', ignore: [404] });
|
||||
expect(roleWithPrivileges).to.eql({});
|
||||
const roleWithPriviledgesDlsFls = await es.shield.getRole({ name: 'role_with_privileges_dls_fls', ignore: [404] });
|
||||
expect(roleWithPriviledgesDlsFls).to.eql({});
|
||||
const roleToUpdate = await es.shield.getRole({ name: 'role_to_update', ignore: [404] });
|
||||
expect(roleToUpdate).to.eql({});
|
||||
const roleToUpdateWithDlsFls = await es.shield.getRole({ name: 'role_to_update_with_dls_fls', ignore: [404] });
|
||||
expect(roleToUpdateWithDlsFls).to.eql({});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
17
x-pack/test/api_integration/config_security_basic.js
Normal file
17
x-pack/test/api_integration/config_security_basic.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 { default as createTestConfig } from './config';
|
||||
|
||||
export default async function ({ readConfigFile }) {
|
||||
//security APIs should function the same under a basic or trial license
|
||||
return createTestConfig({ readConfigFile }).then(config => {
|
||||
config.esTestCluster.license = 'basic';
|
||||
config.esTestCluster.serverArgs = ['xpack.license.self_generated.type=basic', 'xpack.security.enabled=true'];
|
||||
config.testFiles = [require.resolve('./apis/security')];
|
||||
return config;
|
||||
});
|
||||
}
|
|
@ -54,7 +54,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions)
|
|||
license,
|
||||
serverArgs: [
|
||||
`xpack.license.self_generated.type=${license}`,
|
||||
`xpack.security.enabled=${!disabledPlugins.includes('security') && license === 'trial'}`,
|
||||
`xpack.security.enabled=${!disabledPlugins.includes('security')}`,
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../common/config';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default createTestConfig('security_and_spaces', { license: 'basic' });
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../common/config';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default createTestConfig('security_only', { disabledPlugins: ['spaces'], license: 'basic' });
|
|
@ -7,4 +7,4 @@
|
|||
import { createTestConfig } from '../common/config';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default createTestConfig('spaces_only', { license: 'basic' });
|
||||
export default createTestConfig('spaces_only', { disabledPlugins: ['security'], license: 'basic' });
|
||||
|
|
|
@ -54,7 +54,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions)
|
|||
license,
|
||||
serverArgs: [
|
||||
`xpack.license.self_generated.type=${license}`,
|
||||
`xpack.security.enabled=${!disabledPlugins.includes('security') && license === 'trial'}`,
|
||||
`xpack.security.enabled=${!disabledPlugins.includes('security')}`,
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../common/config';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default createTestConfig('security_and_spaces', { license: 'basic' });
|
|
@ -6,4 +6,4 @@
|
|||
import { createTestConfig } from '../common/config';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default createTestConfig('spaces_only', { license: 'basic' });
|
||||
export default createTestConfig('spaces_only', { disabledPlugins: ['security'], license: 'basic' });
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue