Skip to content

Commit

Permalink
Merge pull request #587 from magieno/adding-debugging
Browse files Browse the repository at this point in the history
- Adding debug logging to the role guard.
  • Loading branch information
etiennenoel authored Oct 23, 2023
2 parents 4aee826 + bfe3a04 commit 4697510
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 33 deletions.
50 changes: 25 additions & 25 deletions package-lock.json

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

34 changes: 28 additions & 6 deletions packages/security/src/guards/role.guard.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
import "reflect-metadata";
import {RoleGuard} from "./role.guard";
import {HttpMethod, Request} from "@pristine-ts/common";
import {LogHandlerInterface} from "@pristine-ts/logging";

class LogHandlerMock implements LogHandlerInterface {
debug(message: string, extra?: any) {
}

info(message: string, extra?: any) {
}

error(message: string, extra?: any) {
}

critical(message: string, extra?: any) {
}

warning(message: string, extra?: any) {
}

terminate() {

}
}

describe("Auth0 roles Guard", () => {
it("should return true when no role is needed", async () => {
const roleGuard = new RoleGuard("http://pristine.com/roles");
const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock());

roleGuard.setContext({
CognitoGroupGuard: RoleGuard,
Expand All @@ -23,7 +45,7 @@ describe("Auth0 roles Guard", () => {
})

it("should return false when groups are needed but identity does not provide groups.", async () => {
const roleGuard = new RoleGuard("http://pristine.com/roles");
const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock());

roleGuard.setContext({
CognitoGroupGuard: RoleGuard,
Expand All @@ -42,7 +64,7 @@ describe("Auth0 roles Guard", () => {
})

it("should return false when groups are needed but identity groups is not an array.", async () => {
const roleGuard = new RoleGuard("http://pristine.com/roles");
const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock());

roleGuard.setContext({
CognitoGroupGuard: RoleGuard,
Expand All @@ -62,7 +84,7 @@ describe("Auth0 roles Guard", () => {
})

it("should return false when groups are needed that are not in the identity groups.", async () => {
const roleGuard = new RoleGuard("http://pristine.com/roles");
const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock());

roleGuard.setContext({
CognitoGroupGuard: RoleGuard,
Expand All @@ -82,7 +104,7 @@ describe("Auth0 roles Guard", () => {
})

it("should return true when all groups needed are in the identity groups.", async () => {
const roleGuard = new RoleGuard("http://pristine.com/roles");
const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock());

roleGuard.setContext({
CognitoGroupGuard: RoleGuard,
Expand All @@ -102,7 +124,7 @@ describe("Auth0 roles Guard", () => {
})

it("should return find the claim when specified in options", async () => {
const roleGuard = new RoleGuard("http://pristine.com/roles");
const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock());

roleGuard.setContext({
CognitoGroupGuard: RoleGuard,
Expand Down
11 changes: 9 additions & 2 deletions packages/security/src/guards/role.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {IdentityInterface} from "@pristine-ts/common";
import {GuardInterface} from "../interfaces/guard.interface";
import {GuardContextInterface} from "../interfaces/guard-context.interface";
import {Request} from "@pristine-ts/common";
import {LogHandlerInterface} from "@pristine-ts/logging";
import {SecurityModuleKeyname} from "../security.module.keyname";

/**
* The role guard is a guard that validates if the identity making the request has the required roles.
Expand All @@ -23,16 +25,19 @@ export class RoleGuard implements GuardInterface {
* The role guard is a guard that validates if the identity making the request has the required roles.
* @param rolesClaimKey The key in the claims of the access token where the roles are defined.
*/
constructor(@inject("%pristine.security.rolesClaimKey%") private readonly rolesClaimKey: string) {
constructor(@inject("%pristine.security.rolesClaimKey%") private readonly rolesClaimKey: string,
@inject("LogHandlerInterface") private readonly logHandler: LogHandlerInterface) {
}

/**
* Sets the context for the guard.
* @param context The context for the guard to use.
*/
setContext(context: any): Promise<void> {
async setContext(context: any): Promise<void> {
this.guardContext = context;

this.logHandler.debug("Setting the context", {context}, SecurityModuleKeyname);

return Promise.resolve();
}

Expand All @@ -58,12 +63,14 @@ export class RoleGuard implements GuardInterface {

// If the identity does not have a roles claim, we deny.
if(neededRoles.length > 0 && (identity?.claims?.hasOwnProperty(this.rolesClaimKey) === false || !Array.isArray(identity?.claims[this.rolesClaimKey]))){
this.logHandler.debug("Identity doesn't have a roles claim. Denying.", {request, identity, neededRoles}, SecurityModuleKeyname);
return false;
}

// If the identity is missing one of the needed roles, we deny.
for(const role of neededRoles) {
if(!identity?.claims[this.rolesClaimKey].includes(role)){
this.logHandler.debug("Role not found in claims. Denying.", {request, identity, neededRoles, role}, SecurityModuleKeyname);
return false;
}
}
Expand Down

0 comments on commit 4697510

Please sign in to comment.