Require gold license for ECS audit logging (#85537)
* Require gold license for ECS audit logging * Fix unit test * Add suggestions from code review
This commit is contained in:
parent
a34cd20498
commit
051bbf073e
|
@ -43,6 +43,12 @@ export interface SecurityLicenseFeatures {
|
|||
*/
|
||||
readonly allowAuditLogging: boolean;
|
||||
|
||||
/**
|
||||
* Indicates whether we allow logging of legacy audit events.
|
||||
* @deprecated
|
||||
*/
|
||||
readonly allowLegacyAuditLogging: boolean;
|
||||
|
||||
/**
|
||||
* Indicates whether we allow users to define document level security in roles.
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,7 @@ describe('license features', function () {
|
|||
allowRbac: false,
|
||||
allowSubFeaturePrivileges: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -48,6 +49,7 @@ describe('license features', function () {
|
|||
allowRbac: false,
|
||||
allowSubFeaturePrivileges: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -69,6 +71,7 @@ describe('license features', function () {
|
|||
Object {
|
||||
"allowAccessAgreement": false,
|
||||
"allowAuditLogging": false,
|
||||
"allowLegacyAuditLogging": false,
|
||||
"allowLogin": false,
|
||||
"allowRbac": false,
|
||||
"allowRoleDocumentLevelSecurity": false,
|
||||
|
@ -90,6 +93,7 @@ describe('license features', function () {
|
|||
Object {
|
||||
"allowAccessAgreement": true,
|
||||
"allowAuditLogging": true,
|
||||
"allowLegacyAuditLogging": true,
|
||||
"allowLogin": true,
|
||||
"allowRbac": true,
|
||||
"allowRoleDocumentLevelSecurity": true,
|
||||
|
@ -128,6 +132,7 @@ describe('license features', function () {
|
|||
allowRbac: true,
|
||||
allowSubFeaturePrivileges: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
});
|
||||
expect(getFeatureSpy).toHaveBeenCalledTimes(1);
|
||||
expect(getFeatureSpy).toHaveBeenCalledWith('security');
|
||||
|
@ -153,10 +158,36 @@ describe('license features', function () {
|
|||
allowRbac: false,
|
||||
allowSubFeaturePrivileges: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow role mappings, access agreement and sub-feature privileges, but not DLS/FLS if license = gold', () => {
|
||||
it('should allow all basic features for standard license', () => {
|
||||
const mockRawLicense = licenseMock.createLicense({
|
||||
license: { mode: 'standard', type: 'standard' },
|
||||
features: { security: { isEnabled: true, isAvailable: true } },
|
||||
});
|
||||
|
||||
const serviceSetup = new SecurityLicenseService().setup({
|
||||
license$: of(mockRawLicense),
|
||||
});
|
||||
expect(serviceSetup.license.isLicenseAvailable()).toEqual(true);
|
||||
expect(serviceSetup.license.getFeatures()).toEqual({
|
||||
showLogin: true,
|
||||
allowLogin: true,
|
||||
showLinks: true,
|
||||
showRoleMappingsManagement: false,
|
||||
allowAccessAgreement: false,
|
||||
allowRoleDocumentLevelSecurity: false,
|
||||
allowRoleFieldLevelSecurity: false,
|
||||
allowRbac: true,
|
||||
allowSubFeaturePrivileges: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow role mappings, access agreement, sub-feature privileges and audit logging, but not DLS/FLS if license = gold', () => {
|
||||
const mockRawLicense = licenseMock.createLicense({
|
||||
license: { mode: 'gold', type: 'gold' },
|
||||
features: { security: { isEnabled: true, isAvailable: true } },
|
||||
|
@ -177,6 +208,7 @@ describe('license features', function () {
|
|||
allowRbac: true,
|
||||
allowSubFeaturePrivileges: true,
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -201,30 +233,7 @@ describe('license features', function () {
|
|||
allowRbac: true,
|
||||
allowSubFeaturePrivileges: true,
|
||||
allowAuditLogging: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow all basic features + audit logging for standard license', () => {
|
||||
const mockRawLicense = licenseMock.createLicense({
|
||||
license: { mode: 'standard', type: 'standard' },
|
||||
features: { security: { isEnabled: true, isAvailable: true } },
|
||||
});
|
||||
|
||||
const serviceSetup = new SecurityLicenseService().setup({
|
||||
license$: of(mockRawLicense),
|
||||
});
|
||||
expect(serviceSetup.license.isLicenseAvailable()).toEqual(true);
|
||||
expect(serviceSetup.license.getFeatures()).toEqual({
|
||||
showLogin: true,
|
||||
allowLogin: true,
|
||||
showLinks: true,
|
||||
showRoleMappingsManagement: false,
|
||||
allowAccessAgreement: false,
|
||||
allowRoleDocumentLevelSecurity: false,
|
||||
allowRoleFieldLevelSecurity: false,
|
||||
allowRbac: true,
|
||||
allowSubFeaturePrivileges: false,
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -79,6 +79,7 @@ export class SecurityLicenseService {
|
|||
showRoleMappingsManagement: false,
|
||||
allowAccessAgreement: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
allowRoleDocumentLevelSecurity: false,
|
||||
allowRoleFieldLevelSecurity: false,
|
||||
allowRbac: false,
|
||||
|
@ -98,6 +99,7 @@ export class SecurityLicenseService {
|
|||
showRoleMappingsManagement: false,
|
||||
allowAccessAgreement: false,
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
allowRoleDocumentLevelSecurity: false,
|
||||
allowRoleFieldLevelSecurity: false,
|
||||
allowRbac: false,
|
||||
|
@ -114,7 +116,8 @@ export class SecurityLicenseService {
|
|||
showLinks: true,
|
||||
showRoleMappingsManagement: isLicenseGoldOrBetter,
|
||||
allowAccessAgreement: isLicenseGoldOrBetter,
|
||||
allowAuditLogging: isLicenseStandardOrBetter,
|
||||
allowAuditLogging: isLicenseGoldOrBetter,
|
||||
allowLegacyAuditLogging: isLicenseStandardOrBetter,
|
||||
allowSubFeaturePrivileges: isLicenseGoldOrBetter,
|
||||
// Only platinum and trial licenses are compliant with field- and document-level security.
|
||||
allowRoleDocumentLevelSecurity: isLicensePlatinumOrBetter,
|
||||
|
|
|
@ -358,7 +358,7 @@ describe('#getLogger', () => {
|
|||
|
||||
const licenseWithFeatures = licenseMock.create();
|
||||
licenseWithFeatures.features$ = new BehaviorSubject({
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
} as SecurityLicenseFeatures).asObservable();
|
||||
|
||||
const auditService = new AuditService(logger).setup({
|
||||
|
@ -388,7 +388,7 @@ describe('#getLogger', () => {
|
|||
|
||||
const licenseWithFeatures = licenseMock.create();
|
||||
licenseWithFeatures.features$ = new BehaviorSubject({
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
} as SecurityLicenseFeatures).asObservable();
|
||||
|
||||
const auditService = new AuditService(logger).setup({
|
||||
|
@ -426,7 +426,7 @@ describe('#getLogger', () => {
|
|||
|
||||
const licenseWithFeatures = licenseMock.create();
|
||||
licenseWithFeatures.features$ = new BehaviorSubject({
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
} as SecurityLicenseFeatures).asObservable();
|
||||
|
||||
const auditService = new AuditService(logger).setup({
|
||||
|
@ -452,7 +452,7 @@ describe('#getLogger', () => {
|
|||
|
||||
const licenseWithFeatures = licenseMock.create();
|
||||
licenseWithFeatures.features$ = new BehaviorSubject({
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
} as SecurityLicenseFeatures).asObservable();
|
||||
|
||||
const auditService = new AuditService(logger).setup({
|
||||
|
@ -481,7 +481,7 @@ describe('#getLogger', () => {
|
|||
const licenseWithFeatures = licenseMock.create();
|
||||
|
||||
const features$ = new BehaviorSubject({
|
||||
allowAuditLogging: false,
|
||||
allowLegacyAuditLogging: false,
|
||||
} as SecurityLicenseFeatures);
|
||||
|
||||
licenseWithFeatures.features$ = features$.asObservable();
|
||||
|
@ -505,7 +505,7 @@ describe('#getLogger', () => {
|
|||
|
||||
// perform license upgrade
|
||||
features$.next({
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
} as SecurityLicenseFeatures);
|
||||
|
||||
auditLogger.log(eventType, message);
|
||||
|
|
|
@ -70,7 +70,7 @@ export class AuditService {
|
|||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
private allowAuditLogging = false;
|
||||
private allowLegacyAuditLogging = false;
|
||||
|
||||
private ecsLogger: Logger;
|
||||
|
||||
|
@ -87,9 +87,11 @@ export class AuditService {
|
|||
getSpaceId,
|
||||
}: AuditServiceSetupParams): AuditServiceSetup {
|
||||
if (config.enabled && !config.appender) {
|
||||
this.licenseFeaturesSubscription = license.features$.subscribe(({ allowAuditLogging }) => {
|
||||
this.allowAuditLogging = allowAuditLogging;
|
||||
});
|
||||
this.licenseFeaturesSubscription = license.features$.subscribe(
|
||||
({ allowLegacyAuditLogging }) => {
|
||||
this.allowLegacyAuditLogging = allowLegacyAuditLogging;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Configure logging during setup and when license changes
|
||||
|
@ -169,7 +171,7 @@ export class AuditService {
|
|||
const getLogger = (id?: string): LegacyAuditLogger => {
|
||||
return {
|
||||
log: (eventType: string, message: string, data?: Record<string, any>) => {
|
||||
if (!this.allowAuditLogging) {
|
||||
if (!this.allowLegacyAuditLogging) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -173,6 +173,7 @@ describe('Login view routes', () => {
|
|||
showRoleMappingsManagement: true,
|
||||
allowSubFeaturePrivileges: true,
|
||||
allowAuditLogging: true,
|
||||
allowLegacyAuditLogging: true,
|
||||
showLogin: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ describe('Security UsageCollector', () => {
|
|||
license.getFeatures.mockReturnValue({
|
||||
allowAccessAgreement,
|
||||
allowAuditLogging,
|
||||
allowLegacyAuditLogging: allowAuditLogging,
|
||||
allowRbac,
|
||||
} as SecurityLicenseFeatures);
|
||||
return license;
|
||||
|
|
|
@ -75,7 +75,12 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
|
|||
},
|
||||
},
|
||||
fetch: () => {
|
||||
const { allowRbac, allowAccessAgreement, allowAuditLogging } = license.getFeatures();
|
||||
const {
|
||||
allowRbac,
|
||||
allowAccessAgreement,
|
||||
allowAuditLogging,
|
||||
allowLegacyAuditLogging,
|
||||
} = license.getFeatures();
|
||||
if (!allowRbac) {
|
||||
return {
|
||||
auditLoggingEnabled: false,
|
||||
|
@ -87,7 +92,10 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
|
|||
};
|
||||
}
|
||||
|
||||
const auditLoggingEnabled = allowAuditLogging && config.audit.enabled;
|
||||
const legacyAuditLoggingEnabled = allowLegacyAuditLogging && config.audit.enabled;
|
||||
const auditLoggingEnabled =
|
||||
allowAuditLogging && config.audit.enabled && config.audit.appender != null;
|
||||
|
||||
const loginSelectorEnabled = config.authc.selector.enabled;
|
||||
const authProviderCount = config.authc.sortedProviders.length;
|
||||
const enabledAuthProviders = [
|
||||
|
@ -107,7 +115,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
|
|||
);
|
||||
|
||||
return {
|
||||
auditLoggingEnabled,
|
||||
auditLoggingEnabled: legacyAuditLoggingEnabled || auditLoggingEnabled,
|
||||
loginSelectorEnabled,
|
||||
accessAgreementEnabled,
|
||||
authProviderCount,
|
||||
|
|
Loading…
Reference in a new issue