Skip to content

Commit

Permalink
added more acceptance tests around alert deletion, enabling, find and…
Browse files Browse the repository at this point in the history
… get with auth
  • Loading branch information
gmmorris committed Jun 8, 2020
1 parent 2b84902 commit e15946c
Show file tree
Hide file tree
Showing 25 changed files with 950 additions and 108 deletions.
8 changes: 2 additions & 6 deletions examples/alerting_example/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ export class AlertingExamplePlugin implements Plugin<void, void, AlertingExample
privileges: {
all: {
alerting: {
globally: {
all: [alwaysFiringAlert.id, peopleInSpaceAlert.id],
},
all: [alwaysFiringAlert.id, peopleInSpaceAlert.id],
},
savedObject: {
all: [],
Expand All @@ -54,9 +52,7 @@ export class AlertingExamplePlugin implements Plugin<void, void, AlertingExample
},
read: {
alerting: {
globally: {
read: [alwaysFiringAlert.id, peopleInSpaceAlert.id],
},
read: [alwaysFiringAlert.id, peopleInSpaceAlert.id],
},
savedObject: {
all: [],
Expand Down
38 changes: 25 additions & 13 deletions x-pack/plugins/alerts/server/alerts_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import Boom from 'boom';
import { omit, isEqual, pluck } from 'lodash';
import { omit, isEqual, pluck, mapValues } from 'lodash';
import { i18n } from '@kbn/i18n';
import {
Logger,
Expand Down Expand Up @@ -670,29 +670,41 @@ export class AlertsClient {
const { authorization } = this;
if (authorization) {
const alertType = this.alertTypeRegistry.get(alertTypeId);
const requiredPrivilegedScopes =
const requiredPrivilegesByScope = {
consumer: authorization.actions.alerting.get(alertTypeId, consumer, operation),
producer: authorization.actions.alerting.get(alertTypeId, alertType.producer, operation),
};

const checkPrivileges = authorization.checkPrivilegesDynamicallyWithRequest(this.request);
const { hasAllRequested, privileges } = await checkPrivileges(
consumer === AlertsFeatureId || consumer === alertType.producer
? [
// skip consumer privilege checks under `alerts` as all alert types can
// be created under `alerts` if you have producer level privileges
alertType.producer,
requiredPrivilegesByScope.producer,
]
: [
// check for access at consumer level
consumer,
requiredPrivilegesByScope.consumer,
// check for access at producer level
alertType.producer,
];

const checkPrivileges = authorization.checkPrivilegesDynamicallyWithRequest(this.request);
const { hasAllRequested } = await checkPrivileges(
requiredPrivilegedScopes.map((scope) =>
authorization.actions.alerting.get(alertTypeId, scope, operation)
)
requiredPrivilegesByScope.producer,
]
);

if (!hasAllRequested) {
const authorizedPrivileges = pluck(
privileges.filter((privilege) => privilege.authorized),
'privilege'
);
const unauthorizedScopes = mapValues(
requiredPrivilegesByScope,
(privilege) => !authorizedPrivileges.includes(privilege)
);

throw Boom.forbidden(
`Unauthorized to ${operation} a "${alertTypeId}" alert for "${consumer}"`
`Unauthorized to ${operation} a "${alertTypeId}" alert ${
unauthorizedScopes.consumer ? `for "${consumer}"` : `by "${alertType.producer}"`
}`
);
}
}
Expand Down
4 changes: 0 additions & 4 deletions x-pack/plugins/features/server/feature_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ const privilegeSchema = Joi.object({
alerting: Joi.object({
all: Joi.array().items(Joi.string()),
read: Joi.array().items(Joi.string()),
globally: Joi.object({
all: Joi.array().items(Joi.string()),
read: Joi.array().items(Joi.string()),
}),
}),
savedObject: Joi.object({
all: Joi.array().items(Joi.string()).required(),
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion x-pack/plugins/security/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export {
export { AuditLogger } from './audit';
export { SecurityPluginSetup };
export { AuthenticatedUser } from '../common/model';
export { Actions, CheckPrivilegesResponse } from './authorization';
export { Actions } from './authorization';

export const config: PluginConfigDescriptor<TypeOf<typeof ConfigSchema>> = {
schema: ConfigSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@ export class FixturePlugin implements Plugin<void, void, FixtureSetupDeps, Fixtu
read: [],
},
alerting: {
all: [
'test.restricted-noop',
'test.unrestricted-noop',
'test.fake-built-in',
'test.noop',
],
all: ['test.restricted-noop', 'test.unrestricted-noop', 'test.noop'],
},
ui: [],
},
Expand All @@ -51,7 +46,7 @@ export class FixturePlugin implements Plugin<void, void, FixtureSetupDeps, Fixtu
read: ['alert'],
},
alerting: {
read: ['test.restricted-noop', 'test.unrestricted-noop', 'test.fake-built-in'],
read: ['test.restricted-noop', 'test.unrestricted-noop'],
},
ui: [],
},
Expand Down
10 changes: 9 additions & 1 deletion x-pack/test/alerting_api_integration/common/lib/alert_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,22 @@ export class AlertUtils {
}
}

export function getUnauthorizedErrorMessage(
export function getConsumerUnauthorizedErrorMessage(
operation: string,
alertType: string,
consumer: string
) {
return `Unauthorized to ${operation} a "${alertType}" alert for "${consumer}"`;
}

export function getProducerUnauthorizedErrorMessage(
operation: string,
alertType: string,
producer: string
) {
return `Unauthorized to ${operation} a "${alertType}" alert by "${producer}"`;
}

function getDefaultAlwaysFiringAlertData(reference: string, actionId: string) {
const messageTemplate = `
alertId: {{alertId}},
Expand Down
6 changes: 5 additions & 1 deletion x-pack/test/alerting_api_integration/common/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export { ObjectRemover } from './object_remover';
export { getUrlPrefix } from './space_test_utils';
export { ES_TEST_INDEX_NAME, ESTestIndexTool } from './es_test_index_tool';
export { getTestAlertData } from './get_test_alert_data';
export { AlertUtils, getUnauthorizedErrorMessage } from './alert_utils';
export {
AlertUtils,
getConsumerUnauthorizedErrorMessage,
getProducerUnauthorizedErrorMessage,
} from './alert_utils';
export { TaskManagerUtils } from './task_manager_utils';
export * from './test_assertions';
export { checkAAD } from './check_aad';
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ const Space1All: User = {
alerts: ['all'],
actions: ['all'],
alertsFixture: ['all'],
alertsRestrictedFixture: ['read'],
},
spaces: ['space1'],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
getTestAlertData,
ObjectRemover,
AlertUtils,
getUnauthorizedErrorMessage,
getConsumerUnauthorizedErrorMessage,
TaskManagerUtils,
} from '../../../common/lib';

Expand Down Expand Up @@ -87,7 +87,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -186,7 +186,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -378,7 +378,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -467,7 +467,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.authorization',
'alertsFixture'
Expand Down Expand Up @@ -586,7 +586,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -675,7 +675,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -746,7 +746,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -801,7 +801,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -848,7 +848,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -898,7 +898,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down Expand Up @@ -948,7 +948,7 @@ instanceStateValue: true
expect(response.statusCode).to.eql(403);
expect(response.body).to.eql({
error: 'Forbidden',
message: getUnauthorizedErrorMessage(
message: getConsumerUnauthorizedErrorMessage(
'create',
'test.always-firing',
'alertsFixture'
Expand Down
Loading

0 comments on commit e15946c

Please sign in to comment.