authentication authorization
This commit is contained in:
89
apps/api/src/domain/auth/AuthorizationGuard.test.ts
Normal file
89
apps/api/src/domain/auth/AuthorizationGuard.test.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { ForbiddenException, UnauthorizedException } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { AuthorizationGuard } from './AuthorizationGuard';
|
||||
import { Public } from './Public';
|
||||
import { RequireRoles } from './RequireRoles';
|
||||
|
||||
class DummyController {
|
||||
@Public()
|
||||
publicHandler(): void {}
|
||||
|
||||
protectedHandler(): void {}
|
||||
|
||||
@RequireRoles('admin')
|
||||
adminHandler(): void {}
|
||||
}
|
||||
|
||||
function createExecutionContext(options: { handler: Function; userId?: string }) {
|
||||
const request = options.userId ? { user: { userId: options.userId } } : {};
|
||||
|
||||
return {
|
||||
getHandler: () => options.handler,
|
||||
getClass: () => DummyController,
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => request,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
describe('AuthorizationGuard', () => {
|
||||
it('allows public routes without a user session', () => {
|
||||
const authorizationService = { getRolesForUser: vi.fn() };
|
||||
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
|
||||
|
||||
const ctx = createExecutionContext({
|
||||
handler: DummyController.prototype.publicHandler,
|
||||
});
|
||||
|
||||
expect(guard.canActivate(ctx as any)).toBe(true);
|
||||
expect(authorizationService.getRolesForUser).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('denies non-public routes by default when not authenticated', () => {
|
||||
const authorizationService = { getRolesForUser: vi.fn() };
|
||||
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
|
||||
|
||||
const ctx = createExecutionContext({
|
||||
handler: DummyController.prototype.protectedHandler,
|
||||
});
|
||||
|
||||
expect(() => guard.canActivate(ctx as any)).toThrow(UnauthorizedException);
|
||||
});
|
||||
|
||||
it('allows non-public routes when authenticated', () => {
|
||||
const authorizationService = { getRolesForUser: vi.fn().mockReturnValue([]) };
|
||||
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
|
||||
|
||||
const ctx = createExecutionContext({
|
||||
handler: DummyController.prototype.protectedHandler,
|
||||
userId: 'user-1',
|
||||
});
|
||||
|
||||
expect(guard.canActivate(ctx as any)).toBe(true);
|
||||
});
|
||||
|
||||
it('denies routes requiring roles when user does not have any required role', () => {
|
||||
const authorizationService = { getRolesForUser: vi.fn().mockReturnValue(['user']) };
|
||||
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
|
||||
|
||||
const ctx = createExecutionContext({
|
||||
handler: DummyController.prototype.adminHandler,
|
||||
userId: 'user-1',
|
||||
});
|
||||
|
||||
expect(() => guard.canActivate(ctx as any)).toThrow(ForbiddenException);
|
||||
});
|
||||
|
||||
it('allows routes requiring roles when user has a required role', () => {
|
||||
const authorizationService = { getRolesForUser: vi.fn().mockReturnValue(['admin']) };
|
||||
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
|
||||
|
||||
const ctx = createExecutionContext({
|
||||
handler: DummyController.prototype.adminHandler,
|
||||
userId: 'user-1',
|
||||
});
|
||||
|
||||
expect(guard.canActivate(ctx as any)).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user