Skip to content

Commit

Permalink
fix: update parameters to include ctx and update tests to cover state…
Browse files Browse the repository at this point in the history
… resource usage
  • Loading branch information
meenahoda committed Oct 16, 2023
1 parent 48f349b commit 1269b0c
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 134 deletions.
Expand Up @@ -3,8 +3,11 @@
"Type": "Task",
"Parameters": {
"resourceType": "stateMachine",
"resourceName": "tymlyTest_admin_1_0",
"action": "create"
"resourceName": "tymlyTest_updatePost_1_0",
"action": "create",
"ctx": {
"userId": "molly"
}
},
"Resource": "module:checkUserAuthorization",
"End": true
Expand Down
Expand Up @@ -4,10 +4,10 @@ class CheckUserAuthorization {
}

async run (event, context) {
const { resourceType, resourceName, action } = event
const { resourceType, resourceName, action, ctx } = event
const { userId } = context

const authorized = await this.rbac.checkAuthorization(userId, null, resourceType, resourceName, action)
const authorized = await this.rbac.checkAuthorization(userId, ctx, resourceType, resourceName, action)

context.sendTaskSuccess({ authorized })
}
Expand Down
Expand Up @@ -2,3 +2,4 @@ This document specifies a JSON object called a "User Authorization Check".
A Permission Grant MUST have a string field named "resourceType".
A Permission Grant MUST have a string field named "resourceName".
A Permission Grant MUST have a string field named "action".
A Permission Grant MAY have an object field named "ctx".
180 changes: 50 additions & 130 deletions test/authorisation-tests.js
Expand Up @@ -10,6 +10,7 @@ describe('Authorisation tests', function () {
let tymlyService
let rbac
let rbacAdmin
let statebox

describe('setup', () => {
it('fire up Tymly', async () => {
Expand All @@ -31,13 +32,31 @@ describe('Authorisation tests', function () {
)

tymlyService = tymlyServices.tymly
statebox = tymlyServices.statebox
rbac = tymlyServices.rbac
rbac.debug()
rbacAdmin = tymlyServices.rbacAdmin
})
})

describe('checkRoleAuthorization', async () => {
const resourceType = 'stateMachine'

const tests = [
['authorize boss to purge site', 'tymlyTest_purgeSite_1_0', 'boss', null, 'create', true],
['authorize something $everyone can do', 'tymlyTest_readPost_1_0', null, null, 'create', true],
['authorize something an $authenticated user can do', 'tymlyTest_createPost_1_0', 'john.smith', null, 'create', true],
['deny something if user is not authenticated, when they need to be', 'tymlyTest_createPost_1_0', undefined, null, 'create', false],
['authorize an $owner', 'tymlyTest_updatePost_1_0', 'molly', { userId: 'molly' }, 'create', true],
['authorize something directly allowed via a role', 'tymlyTest_createPost_1_0', 'test_dev', null, 'cancel', true],
['deny if no matching role', 'tymlyTest_createPost_1_0', 'spaceman', null, 'cancel', false],
['deny if no appropriate role', 'tymlyTest_deletePost_1_0', 'test_dev', null, 'create', false],
['authorize something because of role inheritance', 'tymlyTest_createPost_1_0', 'boss', null, 'cancel', true],
['authorize something with resource and action wildcards', 'tymlyTest_purgeSite_1_0', 'test_admin', null, 'create', true],
['authorize something with just an action wildcard', 'tymlyTest_purgeSite_1_0', 'reader', null, 'get', true],
['fail to authorize if irrelevant action wildcard', 'tymlyTest_purgeSite_1_0', 'reader', null, 'create', false]
]

it('set up roles', async () => {
await rbacAdmin.ensureUserRoles('boss', 'tymlyTest_boss')
await rbacAdmin.ensureUserRoles('test_dev', 'tymlyTest_developer')
Expand All @@ -46,137 +65,38 @@ describe('Authorisation tests', function () {
await rbacAdmin.ensureUserRoles('reader', 'tymlyTest_tymlyTestReadOnly')
})

it('authorize boss to purge site', async () => {
expect(
await rbac.checkAuthorization(
'boss', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_purgeSite_1_0', // resourceName
'create' // action
)).to.equal(true)
})

it('authorize something $everyone can do', async () => {
expect(
await rbac.checkAuthorization(
null, // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_readPost_1_0', // resourceName
'create' // action
)).to.equal(true)
})

it('authorize something an $authenticated user can do', async () => {
expect(
await rbac.checkAuthorization(
'john.smith', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_createPost_1_0', // resourceName
'create' // action
)).to.equal(true)
})

it('deny something if user is not authenticated, when they need to be', async () => {
expect(
await rbac.checkAuthorization(
undefined, // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_createPost_1_0', // resourceName
'create' // action
)).to.equal(false)
})

it('authorize an $owner', async () => {
expect(
await rbac.checkAuthorization(
'molly', // userId
{ userId: 'molly' }, // ctx
'stateMachine', // resourceType
'tymlyTest_updatePost_1_0', // resourceName
'create' // action
)).to.equal(true)
})

it('authorize something directly allowed via a role', async () => {
expect(
await rbac.checkAuthorization(
'test_dev', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_createPost_1_0', // resourceName
'cancel' // action
)).to.equal(true)
})

it('deny if no matching role', async () => {
expect(
await rbac.checkAuthorization(
'spaceman', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_createPost_1_0', // resourceName
'cancel' // action
)).to.equal(false)
})

it('deny if no appropriate role', async () => {
expect(
await rbac.checkAuthorization(
'test_dev', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_deletePost_1_0', // resourceName
'create' // action
)).to.equal(false)
})

it('authorize something because of role inheritance', async () => {
expect(
await rbac.checkAuthorization(
'boss', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_createPost_1_0', // resourceName
'cancel' // action
)).to.equal(true)
})

it('authorize something with resource and action wildcards', async () => {
expect(
await rbac.checkAuthorization(
'test_admin', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_purgeSite_1_0', // resourceName
'create' // action
)).to.equal(true)
})

it('authorize something with just an action wildcard', async () => {
expect(
await rbac.checkAuthorization(
'reader', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_purgeSite_1_0', // resourceName
'get' // action
)).to.equal(true)
})
for (const [title, resourceName, userId, ctx, action, expected] of tests) {
it(title, async () => {
const actual = await rbac.checkAuthorization(
userId,
ctx,
resourceType,
resourceName,
action
)

expect(actual).to.equal(expected)
})

it(`${title} (via state machine)`, async () => {
const execDesc = await statebox.startExecution(
{
resourceType,
resourceName,
action,
ctx
},
'tymlyTest_checkUserAuthorization_1_0',
{
sendResponse: 'COMPLETE',
userId
}
)

it('fail to authorize if irrelevant action wildcard', async () => {
expect(
await rbac.checkAuthorization(
'reader', // userId
null, // ctx
'stateMachine', // resourceType
'tymlyTest_purgeSite_1_0', // resourceName
'create' // action
)).to.equal(false)
})
expect(execDesc.status).to.eql('SUCCEEDED')
expect(execDesc.ctx.authorized).to.eql(expected)
})
}
})

describe('shutdown', () => {
Expand Down
@@ -0,0 +1,20 @@
{
"Comment": "Check user authorization",
"version": "1.0",
"StartAt": "Success",
"States": {
"Success": {
"Type": "Task",
"Resource": "module:checkUserAuthorization",
"End": true
}
},
"restrictions": [
{
"roleId": "$everyone",
"allows": [
"*"
]
}
]
}

0 comments on commit 1269b0c

Please sign in to comment.