Skip to content

Commit

Permalink
fix: handle both Set and array for currentUser.authorities
Browse files Browse the repository at this point in the history
  • Loading branch information
jenniferarnesen committed Oct 5, 2023
1 parent b58ae36 commit e2e46fc
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,38 @@ import {
getCommentAccess,
} from '../getInterpretationAccess.js'

const superuser = {
const superuserD2CurrentUser = {
id: 'iamsuper',
authorities: new Set(['ALL']),
}

const userJoe = {
const userJoeD2CurrentUser = {
id: 'johndoe',
authorities: new Set(['Some']),
}

const userJane = {
const userJaneD2CurrentUser = {
id: 'jane',
authorities: new Set(['Some']),
}

const superuser = {
id: 'iamsuper',
authorities: ['ALL'],
}

const userJoe = {
id: 'johndoe',
authorities: ['Some'],
}

const userJane = {
id: 'jane',
authorities: ['Some'],
}

describe('interpretation and comment access', () => {
describe('getInterpretationAccess', () => {
describe('getInterpretationAccess with D2', () => {
it('returns true for all accesses for superuser', () => {
const interpretation = {
access: {
Expand Down Expand Up @@ -113,6 +128,234 @@ describe('interpretation and comment access', () => {
delete: false,
})
})

it('returns false for all accesses when no currentUser provided', () => {
const interpretation = {
access: {
write: false,
manage: false,
},
createdBy: userJane,
}

expect(getInterpretationAccess(interpretation)).toMatchObject({
share: false,
comment: false,
edit: false,
delete: false,
})
})

it('returns false for all accesses when currentUser missing authorities', () => {
const interpretation = {
access: {
write: false,
manage: false,
},
createdBy: userJane,
}

expect(
getInterpretationAccess(interpretation, {
id: 'usernoauthorties',
})
).toMatchObject({
share: false,
comment: false,
edit: false,
delete: false,
})
})
})

describe('getInterpretationAccess using D2.currentUser', () => {
it('returns true for all accesses for superuser', () => {
const interpretation = {
access: {
write: true,
manage: true,
},
createdBy: userJoeD2CurrentUser,
}

expect(
getInterpretationAccess(interpretation, superuserD2CurrentUser)
).toMatchObject({
share: true,
comment: true,
edit: true,
delete: true,
})
})
it('returns true for all accesses for creator', () => {
const interpretation = {
access: {
write: true,
manage: true,
},
createdBy: userJoeD2CurrentUser,
}

expect(
getInterpretationAccess(interpretation, userJoeD2CurrentUser)
).toMatchObject({
share: true,
comment: true,
edit: true,
delete: true,
})
})

it('returns false for edit/delete if user is not creator/superuser', () => {
const interpretation = {
access: {
write: true,
manage: true,
},
createdBy: userJaneD2CurrentUser,
}

expect(
getInterpretationAccess(interpretation, userJoeD2CurrentUser)
).toMatchObject({
share: true,
comment: true,
edit: false,
delete: false,
})
})

it('returns false for comment/edit/delete if user is not creator/superuser and no write access', () => {
const interpretation = {
access: {
write: false,
manage: true,
},
createdBy: userJaneD2CurrentUser,
}

expect(
getInterpretationAccess(interpretation, userJoeD2CurrentUser)
).toMatchObject({
share: true,
comment: false,
edit: false,
delete: false,
})
})

it('returns false for share/comment/edit/delete if user is not creator/superuser and no write or manage access', () => {
const interpretation = {
access: {
write: false,
manage: false,
},
createdBy: userJaneD2CurrentUser,
}

expect(
getInterpretationAccess(interpretation, userJoeD2CurrentUser)
).toMatchObject({
share: false,
comment: false,
edit: false,
delete: false,
})
})
})

describe('getCommentAccess using D2.currentUser', () => {
it('returns true for all accesses for superuser', () => {
const interpretation = {
access: {
write: true,
},
}

const comment = {
createdBy: userJoeD2CurrentUser,
}

expect(
getCommentAccess(
comment,
interpretation.access.write,
superuserD2CurrentUser
)
).toMatchObject({
edit: true,
delete: true,
})
})

it('returns true for all accesses for creator when interpretation has write access', () => {
const interpretation = {
access: {
write: true,
},
}

const comment = {
createdBy: userJoeD2CurrentUser,
}

expect(
getCommentAccess(
comment,
interpretation.access.write,
userJoeD2CurrentUser
)
).toMatchObject({
edit: true,
delete: true,
})
})

it('returns true for edit and false for delete for creator when interpretation does not have write access', () => {
const interpretation = {
access: {
write: false,
},
}

const comment = {
createdBy: userJoeD2CurrentUser,
}

expect(
getCommentAccess(
comment,
interpretation.access.write,
userJoeD2CurrentUser
)
).toMatchObject({
edit: true,
delete: false,
})
})

it('returns false for edit/delete for user who is not creator or superuser', () => {
const interpretation = {
access: {
write: true,
},
}

const comment = {
createdBy: userJaneD2CurrentUser,
}

expect(
getCommentAccess(
comment,
interpretation.access.write,
userJoeD2CurrentUser
)
).toMatchObject({
edit: false,
delete: false,
})
})
})

describe('getCommentAccess', () => {
Expand Down
13 changes: 12 additions & 1 deletion src/components/Interpretations/common/getInterpretationAccess.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { isArray } from 'lodash'

// For backwards compatibility
// accept both Set (from the old d2.currentUser object) and array
const isSuperuser = (authorities = []) => {
if (isArray(authorities)) {
return authorities.includes('ALL')
}
return authorities.has('ALL')
}

const isCreatorOrSuperuser = (object, currentUser) =>
object?.createdBy.id === currentUser?.id ||
currentUser?.authorities.has('ALL')
isSuperuser(currentUser?.authorities)

export const getInterpretationAccess = (interpretation, currentUser) => {
const canEditDelete = isCreatorOrSuperuser(interpretation, currentUser)
Expand Down

0 comments on commit e2e46fc

Please sign in to comment.