permission: batch apply conditions payload
Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
@@ -34,9 +34,16 @@ const responseSchema = z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
result: z
|
||||
.literal(AuthorizeResult.ALLOW)
|
||||
.or(z.literal(AuthorizeResult.DENY)),
|
||||
result: z.union([
|
||||
z.literal(AuthorizeResult.ALLOW),
|
||||
z.literal(AuthorizeResult.DENY),
|
||||
z.array(
|
||||
z.union([
|
||||
z.literal(AuthorizeResult.ALLOW),
|
||||
z.literal(AuthorizeResult.DENY),
|
||||
]),
|
||||
),
|
||||
]),
|
||||
}),
|
||||
),
|
||||
});
|
||||
@@ -45,6 +52,9 @@ export type ResourcePolicyDecision = ConditionalPolicyDecision & {
|
||||
resourceRef: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class PermissionIntegrationClient {
|
||||
private readonly discovery: DiscoveryService;
|
||||
private readonly auth: AuthService;
|
||||
@@ -74,14 +84,7 @@ export class PermissionIntegrationClient {
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
items: decisions.map(
|
||||
({ id, resourceRef, resourceType, conditions }) => ({
|
||||
id,
|
||||
resourceRef,
|
||||
resourceType,
|
||||
conditions,
|
||||
}),
|
||||
),
|
||||
items: decisions,
|
||||
}),
|
||||
headers: {
|
||||
...(token ? { authorization: `Bearer ${token}` } : {}),
|
||||
|
||||
@@ -165,11 +165,7 @@ describe('createRouter', () => {
|
||||
mockApplyConditions.mockResolvedValueOnce([
|
||||
{
|
||||
id: '123',
|
||||
result: AuthorizeResult.ALLOW,
|
||||
},
|
||||
{
|
||||
id: '123',
|
||||
result: AuthorizeResult.DENY,
|
||||
result: [AuthorizeResult.ALLOW, AuthorizeResult.DENY],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -198,6 +194,21 @@ describe('createRouter', () => {
|
||||
],
|
||||
});
|
||||
|
||||
expect(mockApplyConditions).toHaveBeenCalledWith(
|
||||
'test-plugin',
|
||||
expect.any(Object),
|
||||
[
|
||||
{
|
||||
conditions: { params: ['abc'], rule: 'test-rule' },
|
||||
id: '123',
|
||||
pluginId: 'test-plugin',
|
||||
resourceRefs: ['resource:1', 'resource:2'],
|
||||
resourceType: 'test-resource-1',
|
||||
result: 'CONDITIONAL',
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
expect(policy.handle).toHaveBeenCalledWith(
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
isResourcePermission,
|
||||
PermissionAttributes,
|
||||
PermissionMessageBatch,
|
||||
PolicyDecision,
|
||||
} from '@backstage/plugin-permission-common';
|
||||
import {
|
||||
ApplyConditionsRequestEntry,
|
||||
@@ -125,9 +124,7 @@ const handleRequest = async (
|
||||
auth: AuthService,
|
||||
userInfo: UserInfoService,
|
||||
): Promise<
|
||||
IdentifiedPermissionMessage<
|
||||
EvaluatePermissionResponse | BulkDefinitivePolicyDecision
|
||||
>[]
|
||||
IdentifiedPermissionMessage<InternalEvaluatePermissionResponse>[]
|
||||
> => {
|
||||
const applyConditionsLoaderFor = memoize((pluginId: string) => {
|
||||
return new DataLoader<
|
||||
@@ -182,20 +179,11 @@ const handleRequest = async (
|
||||
}
|
||||
|
||||
if (request.resourceRefs) {
|
||||
const results = await Promise.all(
|
||||
request.resourceRefs.map(resourceRef =>
|
||||
applyConditionsLoaderFor(decision.pluginId).load({
|
||||
id: request.id,
|
||||
resourceRef,
|
||||
...decision,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
return applyConditionsLoaderFor(decision.pluginId).load({
|
||||
id: request.id,
|
||||
result: results.map(({ result }) => result),
|
||||
};
|
||||
resourceRefs: request.resourceRefs,
|
||||
...decision,
|
||||
});
|
||||
}
|
||||
|
||||
if (!request.resourceRef) {
|
||||
@@ -254,9 +242,7 @@ export async function createRouter(
|
||||
'/authorize',
|
||||
async (
|
||||
req: Request,
|
||||
res: Response<
|
||||
PermissionMessageBatch<PolicyDecision | BulkDefinitivePolicyDecision>
|
||||
>,
|
||||
res: Response<PermissionMessageBatch<InternalEvaluatePermissionResponse>>,
|
||||
) => {
|
||||
const credentials = await httpAuth.credentials(req, {
|
||||
allow: ['user', 'none'],
|
||||
@@ -307,6 +293,8 @@ export async function createRouter(
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
type BulkDefinitivePolicyDecision = {
|
||||
result: Array<AuthorizeResult.ALLOW | AuthorizeResult.DENY>;
|
||||
};
|
||||
type InternalEvaluatePermissionResponse =
|
||||
| EvaluatePermissionResponse
|
||||
| {
|
||||
result: Array<AuthorizeResult.ALLOW | AuthorizeResult.DENY>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user