Skip to content

Commit

Permalink
feat(auth): allow authorizedActions to match every action
Browse files Browse the repository at this point in the history
  • Loading branch information
Nictheboy committed Sep 6, 2024
1 parent 32a9c20 commit a3f5dcb
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
11 changes: 7 additions & 4 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,13 @@ export class AuthService {
throw new Error('resourceId must be a number.');
}
for (const permission of authorization.permissions) {
let actionMatches = false;
for (const authorizedAction of permission.authorizedActions) {
if (authorizedAction === action) {
actionMatches = true;
let actionMatches =
permission.authorizedActions === undefined ? true : false;
if (permission.authorizedActions !== undefined) {
for (const authorizedAction of permission.authorizedActions) {
if (authorizedAction === action) {
actionMatches = true;
}
}
}
if (actionMatches == false) continue;
Expand Down
46 changes: 46 additions & 0 deletions src/auth/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,50 @@ describe('AuthService', () => {
expect(handler_called).toBe(true);
expect(data).toEqual({ some: 'data' });
});
it('should always invoke custom logic successfully', async () => {
let handler_called = false;
const handler: CustomAuthLogicHandler = async (
action: AuthorizedAction,
resourceOwnerId?: number,
resourceType?: string,
resourceId?: number,
) => {
handler_called = true;
return true;
};
authService.customAuthLogics.register('yet_yet_another_logic', handler);
const token = authService.sign({
userId: 0,
permissions: [
{
authorizedActions: undefined, // all actions
authorizedResource: {}, // all resources
customLogic: 'yet_yet_another_logic',
},
],
});
await authService.audit(token, 'some_action', 1, 'user', 1);
expect(handler_called).toBe(true);
handler_called = false;
await authService.audit(token, 'another_action', undefined, 'user', 1);
expect(handler_called).toBe(true);
handler_called = false;
await authService.audit(
token,
'some_action',
1,
'another_resource',
undefined,
);
expect(handler_called).toBe(true);
handler_called = false;
await authService.audit(
token,
'another_action',
undefined,
'another_resource',
undefined,
);
expect(handler_called).toBe(true);
});
});
10 changes: 9 additions & 1 deletion src/auth/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,22 @@ export class AuthorizedResource {
resourceIds?: number[];
data?: any; // additional data
}

// The permission to perform all the actions listed in authorizedActions
// on all the resources that match the authorizedResource property.
//
// If authorizedActions is undefined, the permission is granted to perform
// all the actions on the resources that match the authorizedResource property.
//
// If customLogic is not undefined, the permission is granted only if the
// custom logic allows the specified action on the specified resource.
export class Permission {
authorizedActions: AuthorizedAction[];
authorizedActions?: AuthorizedAction[];
authorizedResource: AuthorizedResource;
customLogic?: string;
customLogicData?: any;
}

// The user, whose id is userId, is granted the permissions.
export class Authorization {
userId: number; // authorization identity
Expand Down
1 change: 0 additions & 1 deletion src/auth/token-payload.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"customLogicData": {}
},
"required": [
"authorizedActions",
"authorizedResource"
],
"type": "object"
Expand Down

0 comments on commit a3f5dcb

Please sign in to comment.