From 5db6a22116006719687d7756d882f19a4b3c2bb3 Mon Sep 17 00:00:00 2001 From: Abdul Azeez Date: Tue, 28 Dec 2021 12:30:56 +0530 Subject: [PATCH] Abdul/infra editor actions (#6453) * editor actions added Signed-off-by: Abdul-Az * infra_editor test cases Signed-off-by: Abdul-Az * test cases fix Signed-off-by: Abdul-Az --- .../sql/79_infra_editor_update.up.sql | 22 +++ .../api/iam/infra_editor_actions.spec.ts | 183 ++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 components/authz-service/storage/postgres/migration/sql/79_infra_editor_update.up.sql create mode 100644 e2e/cypress/integration/api/iam/infra_editor_actions.spec.ts diff --git a/components/authz-service/storage/postgres/migration/sql/79_infra_editor_update.up.sql b/components/authz-service/storage/postgres/migration/sql/79_infra_editor_update.up.sql new file mode 100644 index 00000000000..191d8233a80 --- /dev/null +++ b/components/authz-service/storage/postgres/migration/sql/79_infra_editor_update.up.sql @@ -0,0 +1,22 @@ +BEGIN; + +UPDATE iam_roles + SET + actions = '{ + infra:*:list, + infra:*:get, + infra:*:create, + infra:*:update, + compliance:*, + event:*, + ingest:*, + secrets:*, + iam:projects:list, + iam:projects:get, + iam:projects:assign, + applications:* + }' + WHERE + id = 'editor'; + +COMMIT; \ No newline at end of file diff --git a/e2e/cypress/integration/api/iam/infra_editor_actions.spec.ts b/e2e/cypress/integration/api/iam/infra_editor_actions.spec.ts new file mode 100644 index 00000000000..eff34f1e505 --- /dev/null +++ b/e2e/cypress/integration/api/iam/infra_editor_actions.spec.ts @@ -0,0 +1,183 @@ +describe('Infra Editor Policy', () => { + let withInfraEditorActionToken = ''; + let withoutInfraEditorActionToken = ''; + + const cypressPrefix = 'infra-editor'; + const policyId1 = `${cypressPrefix}-pol-1-${Cypress.moment().format('MMDDYYhhmm')}`; + const policyId2 = `${cypressPrefix}-pol-2-${Cypress.moment().format('MMDDYYhhmm')}`; + const tokenId1 = `${cypressPrefix}-token-1-${Cypress.moment().format('MMDDYYhhmm')}`; + const tokenId2 = `${cypressPrefix}-token-2-${Cypress.moment().format('MMDDYYhhmm')}`; + const objectsToCleanUp = ['tokens', 'policies']; + + const allowInfraEditorPolicy = { + id: policyId1, + name: tokenId1, + projects: [], + members: [`token:${tokenId1}`], + statements: [ + { + effect: 'ALLOW', + actions: [ + 'infra:*:list', + 'infra:*:get', + 'infra:*:create', + 'infra:*:update', + 'compliance:*', + 'event:*', + 'ingest:*', + 'secrets:*', + 'iam:projects:list', + 'iam:projects:get', + 'iam:projects:assign', + 'applications:*' + ], + projects: ['*'] + }] + }; + + + const denyInfraEditorPolicy = { + id: policyId2, + name: tokenId2, + projects: [], + members: [`token:${tokenId2}`], + statements: [ + { + effect: 'DENY', + actions: [ + 'infra:*:list', + 'infra:*:get', + 'infra:*:create', + 'infra:*:update', + 'compliance:*', + 'event:*', + 'ingest:*', + 'secrets:*', + 'iam:projects:list', + 'iam:projects:get', + 'iam:projects:assign', + 'applications:*' + ], + projects: ['*'] + }] + }; + + before(() => { + cy.cleanupIAMObjectsByIDPrefixes(cypressPrefix, objectsToCleanUp); + + cy.request({ + headers: { 'api-token': Cypress.env('ADMIN_TOKEN') }, + method: 'POST', + url: '/apis/iam/v2/tokens', + body: { + id: tokenId1, + name: tokenId1 + } + }).then((resp) => { + withInfraEditorActionToken = resp.body.token.value; + }); + + cy.request({ + headers: { 'api-token': Cypress.env('ADMIN_TOKEN') }, + method: 'POST', + url: '/apis/iam/v2/policies', + body: allowInfraEditorPolicy + }).then((resp) => { + expect(resp.status).to.equal(200); + }); + + cy.request({ + headers: { 'api-token': Cypress.env('ADMIN_TOKEN') }, + method: 'POST', + url: '/apis/iam/v2/tokens', + body: { + id: tokenId2, + name: tokenId2 + } + }).then((resp) => { + withoutInfraEditorActionToken = resp.body.token.value; + }); + + cy.request({ + headers: { 'api-token': Cypress.env('ADMIN_TOKEN') }, + method: 'POST', + url: '/apis/iam/v2/policies', + body: denyInfraEditorPolicy + }).then((resp) => { + expect(resp.status).to.equal(200); + }); + }); + + after(() => { + cy.cleanupIAMObjectsByIDPrefixes(cypressPrefix, objectsToCleanUp); + }); + + it('cookbooks get returns 200 when infraEditor policy is allowed', () => { + cy.request({ + headers: { 'api-token': withInfraEditorActionToken }, + method: 'GET', + url: '/api/v0/infra/servers/local-dev/orgs/test-org/cookbooks' + }).then((resp) => { + assert.equal(resp.status, 200); + }); + }); + + it('cookbooks get returns 403 when infraEditor policy actions is denied', () => { + cy.request({ + headers: { 'api-token': withoutInfraEditorActionToken }, + method: 'GET', + url: '/api/v0/infra/servers/local-dev/orgs/test-org/cookbooks', + failOnStatusCode: false + }).then((resp) => { + assert.equal(resp.status, 403); + }); + }); + + it('Create Env request returns 200 when infraEditor policy is allowed', () => { + cy.request({ + headers: { 'api-token': withInfraEditorActionToken }, + method: 'POST', + body: { + org_id: 'test-org', + server_id: 'local-dev', + name: 'test2', + description: 'cypress testing' + }, + url: '/api/v0/infra/servers/local-dev/orgs/test-org/environments', + }).then((resp) => { + assert.equal(resp.status, 200); + }); + }); + + it('Roles get returns 200 when infraEditor policy is allowed', () => { + cy.request({ + headers: { 'api-token': withInfraEditorActionToken }, + method: 'GET', + url: '/api/v0/infra/servers/local-dev/orgs/test-org/roles' + }).then((resp) => { + assert.equal(resp.status, 200); + }); + }); + + it('Roles get returns 403 when infraEditor policy is denied', () => { + cy.request({ + headers: { 'api-token': withoutInfraEditorActionToken }, + method: 'GET', + url: '/api/v0/infra/servers/local-dev/orgs/test-org/roles', + failOnStatusCode: false + }).then((resp) => { + assert.equal(resp.status, 403); + }); + }); + + it('databags delete returns 403 when infraEditor policy is allowed', () => { + cy.request({ + headers: { 'api-token': withInfraEditorActionToken }, + method: 'DELETE', + url: '/api/v0/infra/servers/local-dev/orgs/test-org/data_bags/test', + failOnStatusCode: false + }).then((resp) => { + assert.equal(resp.status, 403); + }); + }); +}); \ No newline at end of file