committed by
Vincenzo Scamporlino
parent
7b86882985
commit
e2571d1761
@@ -66,6 +66,7 @@ type TemplateContext = {
|
||||
entity?: UserEntity;
|
||||
ref?: string;
|
||||
};
|
||||
token?: string;
|
||||
};
|
||||
|
||||
const isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {
|
||||
|
||||
@@ -378,31 +378,7 @@ export async function createRouter(
|
||||
|
||||
const baseUrl = getEntityBaseUrl(template);
|
||||
|
||||
const taskSpec: TaskSpec = {
|
||||
apiVersion: template.apiVersion,
|
||||
steps: template.spec.steps.map((step, index) => ({
|
||||
...step,
|
||||
id: step.id ?? `step-${index + 1}`,
|
||||
name: step.name ?? step.action,
|
||||
})),
|
||||
output: template.spec.output ?? {},
|
||||
parameters: values,
|
||||
user: {
|
||||
entity: userEntity as UserEntity,
|
||||
ref: userEntityRef,
|
||||
},
|
||||
templateInfo: {
|
||||
entityRef: stringifyEntityRef({
|
||||
kind,
|
||||
namespace,
|
||||
name: template.metadata?.name,
|
||||
}),
|
||||
baseUrl,
|
||||
entity: {
|
||||
metadata: template.metadata,
|
||||
},
|
||||
},
|
||||
};
|
||||
const taskSpec = await authorizeTaskSpec(template);
|
||||
|
||||
const result = await taskBroker.dispatch({
|
||||
spec: taskSpec,
|
||||
@@ -651,5 +627,35 @@ export async function createRouter(
|
||||
return template;
|
||||
}
|
||||
|
||||
async function authorizeTaskSpec(template: TemplateEntityV1beta3): TaskSpec {
|
||||
const taskSpec: TaskSpec = {
|
||||
apiVersion: template.apiVersion,
|
||||
steps: template.spec.steps.map((step, index) => ({
|
||||
...step,
|
||||
id: step.id ?? `step-${index + 1}`,
|
||||
name: step.name ?? step.action,
|
||||
})),
|
||||
output: template.spec.output ?? {},
|
||||
parameters: values,
|
||||
user: {
|
||||
entity: userEntity as UserEntity,
|
||||
ref: userEntityRef,
|
||||
},
|
||||
templateInfo: {
|
||||
entityRef: stringifyEntityRef({
|
||||
kind,
|
||||
namespace,
|
||||
name: template.metadata?.name,
|
||||
}),
|
||||
baseUrl,
|
||||
entity: {
|
||||
metadata: template.metadata,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return taskSpec;
|
||||
}
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -15,21 +15,75 @@
|
||||
*/
|
||||
|
||||
import { makeCreatePermissionRule } from '@backstage/plugin-permission-node';
|
||||
import {
|
||||
RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,
|
||||
RESOURCE_TYPE_SCAFFOLDER_ACTION,
|
||||
} from '@backstage/plugin-scaffolder-common/alpha';
|
||||
|
||||
import {
|
||||
TemplateEntityStepV1beta3,
|
||||
TemplateParametersV1beta3,
|
||||
} from '@backstage/plugin-scaffolder-common';
|
||||
import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common/alpha';
|
||||
|
||||
import { z } from 'zod';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
|
||||
export const createScaffolderPermissionRule = makeCreatePermissionRule<
|
||||
export const createTemplatePermissionRule = makeCreatePermissionRule<
|
||||
TemplateEntityStepV1beta3 | TemplateParametersV1beta3,
|
||||
{},
|
||||
typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE
|
||||
>();
|
||||
|
||||
export const hasTag = createScaffolderPermissionRule({
|
||||
export const createActionPermissionRule = makeCreatePermissionRule<
|
||||
{
|
||||
actionId: string;
|
||||
input: JsonObject;
|
||||
template: TemplateEntityStepV1beta3 | TemplateParametersV1beta3;
|
||||
},
|
||||
{},
|
||||
typeof RESOURCE_TYPE_SCAFFOLDER_ACTION
|
||||
>();
|
||||
|
||||
export const hasActionId = createActionPermissionRule({
|
||||
name: 'HAS_ACTION_ID',
|
||||
resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,
|
||||
description: `Match actions with the given actionId`,
|
||||
paramsSchema: z.object({
|
||||
actionId: z.string().describe('Name of the actionId to match on'),
|
||||
}),
|
||||
apply: (resource, { actionId }) => {
|
||||
return resource.actionId === actionId;
|
||||
},
|
||||
toQuery: () => ({}),
|
||||
});
|
||||
|
||||
export const matchesInput = createActionPermissionRule({
|
||||
name: 'MATCHED_INPUT',
|
||||
resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,
|
||||
description: `Matches actionId and the input given`,
|
||||
paramsSchema: z.object({
|
||||
actionId: z.string().describe('Name of the actionId to match on'),
|
||||
|
||||
// Pass in a json schema to validate the input against
|
||||
input: z.jsonSchema({}).describe('Input to match on'),
|
||||
}),
|
||||
apply: (resource, { actionId, input }) => {
|
||||
if (resource.actionId !== actionId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(input)) {
|
||||
if (resource.input[key] !== value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
toQuery: () => ({}),
|
||||
});
|
||||
|
||||
export const hasTag = createTemplatePermissionRule({
|
||||
name: 'HAS_TAG',
|
||||
resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,
|
||||
description: `Match parameters or steps with the given tag`,
|
||||
|
||||
@@ -23,6 +23,25 @@ import { createPermission } from '@backstage/plugin-permission-common';
|
||||
*/
|
||||
export const RESOURCE_TYPE_SCAFFOLDER_TEMPLATE = 'scaffolder-template';
|
||||
|
||||
/**
|
||||
* Permission resource type which corresponds to a scaffolder action.
|
||||
*
|
||||
* @alpha
|
||||
*/
|
||||
export const RESOURCE_TYPE_SCAFFOLDER_ACTION = 'scaffolder-action';
|
||||
|
||||
/**
|
||||
* This permission is used to authorize actions that involve executing
|
||||
* an action from a template.
|
||||
*
|
||||
* @alpha
|
||||
*/
|
||||
export const actionExecutePermission = createPermission({
|
||||
name: 'scaffolder.action.execute',
|
||||
attributes: {},
|
||||
resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,
|
||||
});
|
||||
|
||||
/**
|
||||
* This permission is used to authorize actions that involve reading
|
||||
* one or more parameters from a template.
|
||||
@@ -64,6 +83,7 @@ export const templateStepReadPermission = createPermission({
|
||||
* @alpha
|
||||
*/
|
||||
export const scaffolderPermissions = [
|
||||
actionExecutePermission,
|
||||
templateParameterReadPermission,
|
||||
templateStepReadPermission,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user