-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
112 changed files
with
2,869 additions
and
250 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
apps/server/src/modules/authorization/domain/rules/board-do.rule.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
apps/server/src/modules/authorization/domain/rules/school.rule.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import { schoolFactory } from '@modules/school/testing/school.factory'; | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { Permission } from '@shared/domain/interface'; | ||
import { roleFactory, setupEntities, userFactory } from '@shared/testing'; | ||
import { AuthorizationContextBuilder } from '../mapper'; | ||
import { AuthorizationHelper } from '../service/authorization.helper'; | ||
import { SchoolRule } from './school.rule'; | ||
|
||
describe('SchoolRule', () => { | ||
let rule: SchoolRule; | ||
|
||
beforeAll(async () => { | ||
await setupEntities(); | ||
|
||
const module: TestingModule = await Test.createTestingModule({ | ||
providers: [AuthorizationHelper, SchoolRule], | ||
}).compile(); | ||
|
||
rule = await module.get(SchoolRule); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
const permissionA = 'a' as Permission; | ||
const permissionB = 'b' as Permission; | ||
|
||
const setupSchoolAndUser = () => { | ||
const school = schoolFactory.build(); | ||
const role = roleFactory.build({ permissions: [permissionA] }); | ||
const user = userFactory.build({ | ||
roles: [role], | ||
school, | ||
}); | ||
|
||
return { school, user }; | ||
}; | ||
|
||
describe('isApplicable', () => { | ||
describe('when object is instance of School', () => { | ||
const setup = () => { | ||
const { user, school } = setupSchoolAndUser(); | ||
|
||
return { user, school }; | ||
}; | ||
|
||
it('should return true', () => { | ||
const { user, school } = setup(); | ||
|
||
const result = rule.isApplicable(user, school); | ||
|
||
expect(result).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('when object is not instance of School', () => { | ||
const setup = () => { | ||
const { user } = setupSchoolAndUser(); | ||
const someRandomObject = { foo: 'bar' }; | ||
|
||
return { user, someRandomObject }; | ||
}; | ||
|
||
it('should return false', () => { | ||
const { user, someRandomObject } = setup(); | ||
|
||
// @ts-expect-error Testcase | ||
const result = rule.isApplicable(user, someRandomObject); | ||
|
||
expect(result).toBe(false); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('hasPermission', () => { | ||
describe('when user has required permissions and it is her school', () => { | ||
const setup = () => { | ||
const { user, school } = setupSchoolAndUser(); | ||
const context = AuthorizationContextBuilder.read([permissionA]); | ||
|
||
return { user, school, context }; | ||
}; | ||
|
||
it('should return true', () => { | ||
const { user, school, context } = setup(); | ||
|
||
const result = rule.hasPermission(user, school, context); | ||
|
||
expect(result).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('when user does not have required permissions', () => { | ||
const setup = () => { | ||
const { user, school } = setupSchoolAndUser(); | ||
const context = AuthorizationContextBuilder.read([permissionB]); | ||
|
||
return { user, school, context }; | ||
}; | ||
|
||
it('should return false', () => { | ||
const { user, school, context } = setup(); | ||
|
||
const result = rule.hasPermission(user, school, context); | ||
|
||
expect(result).toBe(false); | ||
}); | ||
}); | ||
|
||
describe('when it is not the users school', () => { | ||
const setup = () => { | ||
const { user } = setupSchoolAndUser(); | ||
const someOtherSchool = schoolFactory.build(); | ||
const context = AuthorizationContextBuilder.read([]); | ||
|
||
return { user, someOtherSchool, context }; | ||
}; | ||
|
||
it('should return false', () => { | ||
const { user, someOtherSchool, context } = setup(); | ||
|
||
const result = rule.hasPermission(user, someOtherSchool, context); | ||
|
||
expect(result).toBe(false); | ||
}); | ||
}); | ||
}); | ||
}); |
27 changes: 27 additions & 0 deletions
27
apps/server/src/modules/authorization/domain/rules/school.rule.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { AuthorizableObject } from '@shared/domain/domain-object'; | ||
import { User } from '@shared/domain/entity'; | ||
import { School } from '@src/modules/school/domain/do'; | ||
import { AuthorizationHelper } from '../service/authorization.helper'; | ||
import { AuthorizationContext, Rule } from '../type'; | ||
|
||
@Injectable() | ||
export class SchoolRule implements Rule { | ||
constructor(private readonly authorizationHelper: AuthorizationHelper) {} | ||
|
||
public isApplicable(user: User, object: AuthorizableObject): boolean { | ||
const isApplicable = object instanceof School; | ||
|
||
return isApplicable; | ||
} | ||
|
||
public hasPermission(user: User, school: School, context: AuthorizationContext): boolean { | ||
const hasRequiredPermissions = this.authorizationHelper.hasAllPermissions(user, context.requiredPermissions); | ||
|
||
const isUsersSchool = user.school.id === school.id; | ||
|
||
const hasPermission = hasRequiredPermissions && isUsersSchool; | ||
|
||
return hasPermission; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.