From 9e3a806d7b1dc8a40b7cbf3cfbf0bf976b14b211 Mon Sep 17 00:00:00 2001 From: Charles Overbeck Date: Fri, 27 Jul 2018 11:04:15 -0700 Subject: [PATCH] WIP: Better Handling for Permissions (#367) * Better Handling for Permissions UI portion of ga4gh/dockstore#1589 This has a dependency on PR ga4gh/dockstore#1638, which has a new endpoint. Call new endpoint to get allowable actions. If SHARE action is one of the actions, then user is an owner, and go ahead and fetch all permissions for the workflow. Unfortunately, generated TS code doesn't generate a type for the enum returned by Actions. --- .travis.yml | 2 +- cypress/integration/sharedWorkflows.js | 18 +++--- src/app/workflow/workflow.component.html | 2 +- src/app/workflow/workflow.component.ts | 75 ++++++------------------ travisci/web.yml | 11 +++- 5 files changed, 36 insertions(+), 72 deletions(-) diff --git a/.travis.yml b/.travis.yml index aafd43a742..cb7cf5c15d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ jdk: - oraclejdk8 env: global: - - WEBSERVICE_VERSION="1.5.0-alpha.7" + - WEBSERVICE_VERSION="1.5.0-alpha.8" matrix: - RUN_PROD=false - RUN_PROD=true diff --git a/cypress/integration/sharedWorkflows.js b/cypress/integration/sharedWorkflows.js index 65062772bb..abc1665204 100644 --- a/cypress/integration/sharedWorkflows.js +++ b/cypress/integration/sharedWorkflows.js @@ -10,23 +10,23 @@ describe('Shared with me workflow test from my-workflows', function() { cy .route({ method: "GET", - url: /readertest\/permissions/, - response: [{"email":"user_A","role":"READER"}] - }).as('readerPermissions') + url: /readertest\/actions/, + response: ["READ"] + }).as('readerActions') cy .route({ method: "GET", - url: /writertest\/permissions/, - response: [{"email":"user_A","role":"WRITER"}] - }).as('writerPermissions') + url: /writertest\/actions/, + response: ["READ", "WRITE"] + }).as('writerActions') cy .route({ method: "GET", - url: /ownertest\/permissions/, - response: [{"email":"user_A","role":"OWNER"}] - }).as('ownerPermissions') + url: /ownertest\/actions/, + response: ["READ", "WRITE", "SHARE", "DELETE"] + }).as('ownerActions') let readerWorkflow = createHostedWorkflow('readertest', 200) let writerWorkflow = createHostedWorkflow('writertest', 201); diff --git a/src/app/workflow/workflow.component.html b/src/app/workflow/workflow.component.html index 5e915cc5a0..80ca71edea 100644 --- a/src/app/workflow/workflow.component.html +++ b/src/app/workflow/workflow.component.html @@ -165,7 +165,7 @@

To see the DAG, please refresh the workflow. - + diff --git a/src/app/workflow/workflow.component.ts b/src/app/workflow/workflow.component.ts index 54a336d827..d498b4704e 100644 --- a/src/app/workflow/workflow.component.ts +++ b/src/app/workflow/workflow.component.ts @@ -80,14 +80,10 @@ export class WorkflowComponent extends Entry { this.resourcePath = this.location.prepareExternalUrl(this.location.path()); } - private processResponse(userPermissions: Permission[]): void { + private processPermissions(userPermissions: Permission[]): void { this.owners = this.specificPermissionEmails(userPermissions, RoleEnum.OWNER); this.writers = this.specificPermissionEmails(userPermissions, RoleEnum.WRITER); this.readers = this.specificPermissionEmails(userPermissions, RoleEnum.READER); - - this.canRead = this.canUserRead(); - this.canWrite = this.canUserWrite(); - this.isOwner = this.isUserOwner(); } private specificPermissionEmails(permissions: Permission[], role: RoleEnum): string[] { @@ -157,13 +153,22 @@ export class WorkflowComponent extends Entry { if (this.publicPage) { this.sortedVersions = this.dockstoreService.getValidVersions(this.sortedVersions); } - this.workflowsService.getWorkflowPermissions(this.workflow.full_workflow_path).pipe(takeUntil(this.ngUnsubscribe)).subscribe( - (userPermissions: Permission[]) => { - this.processResponse(userPermissions); - }, - () => { - } - ); + this.canRead = this.canWrite = this.isOwner = false; + this.readers = this.writers = this.owners = []; + this.workflowsService.getWorkflowActions(this.workflow.full_workflow_path).pipe(takeUntil(this.ngUnsubscribe)) + .subscribe((actions: Array) => { + // Alas, Swagger codegen does not generate a type for the actions + this.canRead = actions.indexOf('READ') !== -1; + this.canWrite = actions.indexOf('WRITE') !== -1; + this.isOwner = actions.indexOf('SHARE') !== -1; + if (this.isOwner) { + this.workflowsService.getWorkflowPermissions(this.workflow.full_workflow_path).pipe(takeUntil(this.ngUnsubscribe)) + .subscribe((userPermissions: Permission[]) => { + this.processPermissions(userPermissions); + } + ); + } + }); } } @@ -361,50 +366,4 @@ export class WorkflowComponent extends Entry { } } - /** - * True if user is in users list, or username is in read,write,owner permissions, false otherwise - */ - canUserRead(): boolean { - const username = this.user && this.user.username; - if (this.isInUserArray(username)) { - return true; - } - return this.readers.includes(username) || this.writers.includes(username) || this.owners.includes(username) ; - } - - /** - * True if user is in users list, or username is in write or owner permissions, false otherwise - */ - canUserWrite(): boolean { - const username = this.user && this.user.username; - if (this.isInUserArray(username)) { - return true; - } - return this.writers.includes(username) || this.owners.includes(username); - } - - /** - * True if user is in users list, or username is in owner permissions, false otherwise - */ - isUserOwner(): boolean { - const username = this.user && this.user.username; - if (this.isInUserArray(username)) { - return true; - } - return this.owners.includes(username); - } - - /** - * True if username is in the workflow user array, false otherwise - * @param username - */ - isInUserArray(username: string): boolean { - if (this.workflow.users) { - const match = this.workflow.users.find((user) => user.username === username); - if (match !== undefined) { - return true; - } - } - return false; - } } diff --git a/travisci/web.yml b/travisci/web.yml index d2a28690fc..95e6d84bfb 100644 --- a/travisci/web.yml +++ b/travisci/web.yml @@ -12,9 +12,14 @@ bitbucketClientSecret: googleClientID: googleClientSecret: googleRedirectURI: http://localhost:8080/auth/tokens/google.com -hostname: localhost -scheme: http -port: 8080 + +authorizerType: inmemory + +externalConfig: + basePath: / + hostname: localhost + scheme: http + port: 8080 authenticationCachePolicy: maximumSize=10000, expireAfterAccess=10m