Skip to content

Commit

Permalink
Merge pull request #18 from icgc-argo/develop
Browse files Browse the repository at this point in the history
adds new functions
  • Loading branch information
hlminh2000 committed Jul 18, 2019
2 parents 597401e + 633666a commit fdca05e
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 27 deletions.
89 changes: 63 additions & 26 deletions src/ego-token-utils.ts
Expand Up @@ -144,8 +144,8 @@ export const serializeScope = (scopeObj: PermissionScopeObj): string => {
}

/**
* get an array of PermissionScopeObj which gives at least .WRITE permission to the token
* does not return entries that are given .DENY
* get an array of PermissionScopeObj which gives at least `.READ` permission to the token
* does not return entries that are given `.DENY`
* @param egoJwt
*/
export const getReadableProgramScopes = (egoJwt: string): PermissionScopeObj[] => {
Expand All @@ -156,16 +156,53 @@ export const getReadableProgramScopes = (egoJwt: string): PermissionScopeObj[] =
const output = policy.indexOf(PROGRAM_PREFIX) === 0 && policy.indexOf(PROGRAM_DATA_PREFIX) !== 0
return output
})
return programPermissions.reduce((acc: PermissionScopeObj[], p) => {
const scopeObj = parseScope(p)
if (
[PERMISSIONS.READ, PERMISSIONS.WRITE, PERMISSIONS.ADMIN].includes(scopeObj.permission) &&
![PERMISSIONS.DENY].includes(scopeObj.permission)
) {
acc.push(scopeObj)
}
return acc
}, [])
return programPermissions
.map(parseScope)
.filter(
scopeObj =>
[PERMISSIONS.READ, PERMISSIONS.WRITE, PERMISSIONS.ADMIN].includes(scopeObj.permission) &&
![PERMISSIONS.DENY].includes(scopeObj.permission)
)
}

/**
* get an array of PermissionScopeObj which gives at least `.WRITE` permission to the token
* does not return entries that are given `.DENY`
* @param egoJwt
*/
export const getWriteableProgramScopes = (egoJwt: string): PermissionScopeObj[] => {
const data = decodeToken(egoJwt)
const permissions = data.context.user.permissions
const programPermissions = permissions.filter(p => {
const policy = p.split('.')[0]
const output = policy.indexOf(PROGRAM_PREFIX) === 0 && policy.indexOf(PROGRAM_DATA_PREFIX) !== 0
return output
})
return programPermissions
.map(parseScope)
.filter(
scopeObj =>
[PERMISSIONS.WRITE, PERMISSIONS.ADMIN].includes(scopeObj.permission) &&
![PERMISSIONS.DENY].includes(scopeObj.permission)
)
}

/**
* get an array of program short names where the user has been given at least `.READ` permission
* in the provided token
* @param egoJwt
*/
export const getReadableProgramShortNames = (egoJwt: string): string[] => {
return getReadableProgramScopes(egoJwt).map(({ policy }) => policy.replace(PROGRAM_PREFIX, ''))
}

/**
* get an array of program short names where the user has been given at least `.READ` permission
* in the provided token
* @param egoJwt
*/
export const getWriteableProgramShortNames = (egoJwt: string): string[] => {
return getWriteableProgramScopes(egoJwt).map(({ policy }) => policy.replace(PROGRAM_PREFIX, ''))
}

/**
Expand Down Expand Up @@ -204,22 +241,19 @@ export const canReadSomeProgram = (egoJwt: string) => {
}

/**
* check if a given JWT has admin access to program with given id
* @param args
* checks if a given token can write to any program at all
* @param egoJwt the ego token
*/
export const isProgramAdmin = (args: { egoJwt: string; programId: string }): boolean => {
return canWriteProgram(args)

/** TODO: switch to below logic when .ADMIN scope is available */
// const authorizedProgramScopes = getReadableProgramScopes(args.egoJwt);
// return authorizedProgramScopes.some(
// ({ policy, permission }) => policy.includes(args.programId) && permission === PERMISSIONS.ADMIN,
// );
export const canWriteSomeProgram = (egoJwt: string) => {
return isDccMember(egoJwt) || !!getWriteableProgramScopes(egoJwt).length
}

export const getReadableProgramShortNames = (egoJwt: string): string[] => {
return getReadableProgramScopes(egoJwt).map(({ policy }) => policy.replace(PROGRAM_PREFIX, ''))
}
/**
* check if a given JWT has admin access to program with given id
* @param args
*/
export const isProgramAdmin = (args: { egoJwt: string; programId: string }): boolean =>
canWriteProgram(args)

export default {
isPermission,
Expand All @@ -230,9 +264,12 @@ export default {
parseScope,
serializeScope,
getReadableProgramScopes,
getWriteableProgramScopes,
canReadProgram,
canWriteProgram,
isProgramAdmin,
canReadSomeProgram,
getReadableProgramShortNames
canWriteSomeProgram,
getReadableProgramShortNames,
getWriteableProgramShortNames
}
35 changes: 34 additions & 1 deletion test/utils.test.ts
Expand Up @@ -13,7 +13,10 @@ const {
serializeScope,
canReadSomeProgram,
decodeToken,
getReadableProgramShortNames
getReadableProgramShortNames,
getWriteableProgramScopes,
canWriteSomeProgram,
getWriteableProgramShortNames
} = utils

/** has the following scopes:
Expand Down Expand Up @@ -126,6 +129,16 @@ describe('getReadableProgramScopes', () => {
})
})

describe('getWriteableProgramScopes', () => {
it('should return authorized program scopes', () => {
expect(getWriteableProgramScopes(DATA_SUBMITTER)).toEqual([])
expect(getWriteableProgramScopes(PROGRAM_ADMIN)).toEqual([
{ policy: 'PROGRAM-PACA-AU', permission: 'WRITE' }
])
expect(getWriteableProgramScopes(DCC_USER)).toEqual([])
})
})

describe('getReadableProgramShortNames', () => {
it('should return authorized program names', () => {
expect(getReadableProgramShortNames(DATA_SUBMITTER)).toEqual([])
Expand All @@ -134,6 +147,14 @@ describe('getReadableProgramShortNames', () => {
})
})

describe('getWriteableProgramShortNames', () => {
it('should return authorized program names', () => {
expect(getWriteableProgramShortNames(DATA_SUBMITTER)).toEqual([])
expect(getWriteableProgramShortNames(PROGRAM_ADMIN)).toEqual(['PACA-AU'])
expect(getWriteableProgramShortNames(DCC_USER)).toEqual([])
})
})

describe('isDccMember', () => {
it('should validate DCC member as such', () => {
expect(isDccMember(DCC_USER)).toBe(true)
Expand Down Expand Up @@ -199,3 +220,15 @@ describe('canReadSomeProgram', () => {
expect(canReadSomeProgram(DATA_SUBMITTER)).toBe(false)
})
})

describe('canWriteSomeProgram', () => {
it('should return true for dcc members', () => {
expect(canWriteSomeProgram(DCC_USER)).toBe(true)
})
it('should return true for program admin', () => {
expect(canWriteSomeProgram(PROGRAM_ADMIN)).toBe(true)
})
it('should return false for data submitters with no program access', () => {
expect(canWriteSomeProgram(DATA_SUBMITTER)).toBe(false)
})
})

0 comments on commit fdca05e

Please sign in to comment.