Skip to content

Commit

Permalink
SDIT-1223: ✨ Add in role_ prefix if not set by caller (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
petergphillips authored Nov 14, 2023
1 parent f7e7cdf commit 5d99710
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
23 changes: 16 additions & 7 deletions server/middleware/authorisationMiddleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,37 @@ describe('authorisationMiddleware', () => {
jest.resetAllMocks()
})

it('should return next when no required roles', async () => {
it('should return next when no required roles', () => {
const res = createResWithToken({ authorities: [] })

await authorisationMiddleware()(req, res, next)
authorisationMiddleware()(req, res, next)

expect(next).toHaveBeenCalled()
expect(res.redirect).not.toHaveBeenCalled()
})

it('should redirect when user has no authorised roles', async () => {
it('should redirect when user has no authorised roles', () => {
const res = createResWithToken({ authorities: [] })

await authorisationMiddleware(['SOME_REQUIRED_ROLE'])(req, res, next)
authorisationMiddleware(['SOME_REQUIRED_ROLE'])(req, res, next)

expect(next).not.toHaveBeenCalled()
expect(res.redirect).toHaveBeenCalledWith('/authError')
})

it('should return next when user has authorised role', async () => {
const res = createResWithToken({ authorities: ['SOME_REQUIRED_ROLE'] })
it('should return next when user has authorised role', () => {
const res = createResWithToken({ authorities: ['ROLE_SOME_REQUIRED_ROLE'] })

await authorisationMiddleware(['SOME_REQUIRED_ROLE'])(req, res, next)
authorisationMiddleware(['SOME_REQUIRED_ROLE'])(req, res, next)

expect(next).toHaveBeenCalled()
expect(res.redirect).not.toHaveBeenCalled()
})

it('should return next when user has authorised role and middleware created with ROLE_ prefix', () => {
const res = createResWithToken({ authorities: ['ROLE_SOME_REQUIRED_ROLE'] })

authorisationMiddleware(['ROLE_SOME_REQUIRED_ROLE'])(req, res, next)

expect(next).toHaveBeenCalled()
expect(res.redirect).not.toHaveBeenCalled()
Expand Down
5 changes: 4 additions & 1 deletion server/middleware/authorisationMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import asyncMiddleware from './asyncMiddleware'

export default function authorisationMiddleware(authorisedRoles: string[] = []): RequestHandler {
return asyncMiddleware((req, res, next) => {
// authorities in the user token will always be prefixed by ROLE_.
// Convert roles that are passed into this function without the prefix so that we match correctly.
const authorisedAuthorities = authorisedRoles.map(role => (role.startsWith('ROLE_') ? role : `ROLE_${role}`))
if (res.locals?.user?.token) {
const { authorities: roles = [] } = jwtDecode(res.locals.user.token) as { authorities?: string[] }

if (authorisedRoles.length && !roles.some(role => authorisedRoles.includes(role))) {
if (authorisedAuthorities.length && !roles.some(role => authorisedAuthorities.includes(role))) {
logger.error('User is not authorised to access this')
return res.redirect('/authError')
}
Expand Down

0 comments on commit 5d99710

Please sign in to comment.