diff --git a/SAS/TMSS/frontend/tmss_webapp/src/App.js b/SAS/TMSS/frontend/tmss_webapp/src/App.js index ceea994ca2747fc341be426dfa424e759c1e8d34..563065029dd6533cd87ab700d05f34f874bb90b0 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/App.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/App.js @@ -24,9 +24,8 @@ import { Login } from './authenticate/login'; import pubsub from './utils/pubSub'; import { CustomDialog } from './layout/components/CustomDialog'; -import userrole from './authenticate/userrole'; +import AuthStore from './authenticate/auth.store'; import {Provider} from "react-redux"; -import PermissionStackUtil from './utils/permission.stack.handler'; const { publish, subscribe } = pubsub(); @@ -251,7 +250,7 @@ class App extends Component { return ( <React.Fragment> <div className="App"> - <Provider store={userrole}> + <Provider store={AuthStore}> {/* <div className={wrapperClass} onClick={this.onWrapperClick}> */} <div className={wrapperClass}> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.js b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.js index 21be9b99469908499c807477621900cd19cc1182..4f66abbf5e0626a4f7361141868754060033e7cb 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.js @@ -1,5 +1,5 @@ import AuthService from "../services/auth.service"; -import PermissionStackUtil from './../utils/permission.stack.handler'; +import PermissionStackUtil from './permission.stack.handler'; const axios = require('axios'); /** diff --git a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/userrole.js b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.store.js similarity index 86% rename from SAS/TMSS/frontend/tmss_webapp/src/authenticate/userrole.js rename to SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.store.js index 9b2e5b27a07acc193e9255a2960d50893b1f88ef..cff48f02427bbbe989fca8c8c96d4d8682710489 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/userrole.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/auth.store.js @@ -28,9 +28,9 @@ const rolePermissionReducer = (state, action) => { default: { const actionType = action.type; if (permissionStack && permissionStack[actionType]) { - if(state && state[actionType]) { - delete state[actionType]; - } + //if(state && state[actionType]) { + //delete state[actionType]; + // } return { ...state, [actionType]:permissionStack[actionType]}; } else { return { ...state, rolePermission: {}}; @@ -44,5 +44,5 @@ const rootReducer = redux.combineReducers({ userRolePermission: rolePermissionReducer }); -const userrole = redux.createStore(rootReducer); -export default userrole; +const AuthStore = redux.createStore(rootReducer); +export default AuthStore; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js new file mode 100644 index 0000000000000000000000000000000000000000..24e19f7fc48e7f793b9ee9d03ad21a970d0a557e --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/authenticate/permission.stack.handler.js @@ -0,0 +1,73 @@ +import AuthStore from './../authenticate/auth.store'; +import AuthService from '../services/auth.service'; +import Auth from './auth'; +import _ from 'lodash'; + +const PermissionStackUtil = { + /** + * Get current user permission from API + * @param {*} loadPermission + * @returns + */ + getPermissions: async(loadPermission) => { + let permissionStack = {}; + if (loadPermission) { + permissionStack = await PermissionStackUtil.getAPIBasedPermission(); + //Use this code if API role permission is not ready for demo + /* let user = Auth.getUser(); + user = user?user.name:""; + if (user === 'scientist' ) { + permissionStack['project'] = {create: true, edit: false, delete: true}; + permissionStack['scheduleunit'] = {create: true, edit: false, delete: true, createsub: false, autodeletion:false, + copysu:false, excelview:true, cleanuptask:false, cancelsu:false, viewworkflow:true,dataproduct: true,}; + } else if (user === 'operator' ) { + permissionStack['project'] = {create: true, edit: false, delete: false}; + permissionStack['scheduleunit'] = {create: true, edit: false, delete: false, createsub: false, autodeletion:true, + copysu:true, excelview:false, cleanuptask:true, cancelsu:false, viewworkflow:true,dataproduct: false,}; + } else { + permissionStack['project'] = {create: true, edit: false, delete: true}; + permissionStack['scheduleunit'] = {create: true, edit: false, delete: true, createsub: false, autodeletion:false, + copysu:false, excelview:true, cleanuptask:false, cancelsu:false, viewworkflow:true,dataproduct: true,}; + } */ + } + AuthStore.dispatch({ type: 'loadpermission', payload: permissionStack}); + return permissionStack + }, + async getAPIBasedPermission() { + let permissionStack = {}; + const modules = ['project', 'scheduleunit_draft', 'scheduleunit_blueprint']; + const module_url = { + project: 'project', + scheduleunit_draft: 'scheduling_unit_draft', + scheduleunit_blueprint: 'scheduling_unit_blueprint' + } + for(const module of modules) { + const url = module_url[module]; + const allowedPermission = await AuthService.getAccessControlMethod(url); + if (allowedPermission && allowedPermission.headers && allowedPermission.headers['access-control-allow-methods']) { + const allowedMethods = allowedPermission.headers['access-control-allow-methods']; + if (module === 'project') { + permissionStack[module] ={ + create: allowedMethods?(_.includes(allowedMethods, 'PUT')):false, + edit: allowedMethods?(_.includes(allowedMethods, 'PATCH')):false, + delete: allowedMethods?(_.includes(allowedMethods, 'DELETE')):false}; + } else { + let putAccesss = allowedMethods?(_.includes(allowedMethods, 'PUT')):false; + let patchAccess = allowedMethods?(_.includes(allowedMethods, 'PATCH')):false; + let deleteAccess = allowedMethods?(_.includes(allowedMethods, 'DELETE')):false; + permissionStack['scheduleunit'] ={ + create: putAccesss, edit: patchAccess, delete: deleteAccess, + createsub: putAccesss, autodeletion:deleteAccess, copysu:putAccesss, excelview:putAccesss, + cleanuptask:deleteAccess, cancelsu:deleteAccess, viewworkflow:true,dataproduct: true }; + } + } else { + permissionStack['project'] = {create: false, edit: false, delete: false}; + permissionStack['scheduleunit'] = {create: false, edit: false, delete: false, createsub: false, autodeletion:false, + copysu:false, excelview:false, cleanuptask:false, cancelsu:false, viewworkflow:true,dataproduct: true,}; + } + } + return permissionStack; + } +} + +export default PermissionStackUtil; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js index 7eb149b6789d967bfd71bc3aae5b3f5d4473e9af..26e6bd4e78ef24865128d7b6d834fcf925d923e7 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js @@ -5,8 +5,7 @@ import AppLoader from '../../layout/components/AppLoader'; import PageHeader from '../../layout/components/PageHeader'; import CycleService from '../../services/cycle.service'; import UtilService from '../../services/util.service'; -import userrole from '../../authenticate/userrole'; -import PermissionStackUtil from './../../utils/permission.stack.handler'; +import AuthUtil from '../../utils/auth.util'; /* eslint-disable no-unused-expressions */ @@ -123,7 +122,9 @@ export class ProjectList extends Component { this.setToggleBySorting(); } - getPopulatedProjectList(cycleId) { + async getPopulatedProjectList(cycleId) { + const permission = await AuthUtil.getUserRolePermission('project'); + this.setState({userrole: permission}); Promise.all([ProjectService.getFileSystem(), ProjectService.getCluster()]).then(async (response) => { const options = {}; response[0].map(fileSystem => { @@ -154,8 +155,8 @@ export class ProjectList extends Component { }); } - componentDidMount() { - this.getUserRolePermission(); + componentDidMount() { + //this.getUserRolePermission(); // Show Project for the Cycle, This request will be coming from Cycle View. Otherwise it is consider as normal Project List. this.pageUpdated = true; let cycle = this.props.cycle; @@ -186,10 +187,10 @@ export class ProjectList extends Component { /** * Get current user role permission for Project list */ - getUserRolePermission = async () => { - userrole.dispatch({ type: 'project' }); - this.setState({userrole: userrole.getState()}) - } + // getUserRolePermission = async () => { + // userrole.dispatch({ type: 'project' }); + // this.setState({userrole: userrole.getState()}) + // } render() { return ( @@ -209,8 +210,8 @@ export class ProjectList extends Component { </> : <PageHeader location={this.props.location} title={'Project - List'} - actions={[{ icon: 'fa-plus-square', title: 'Click to Add Project', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.project.create:true, props: { pathname: '/project/create' } }]} + actions={[{ icon: 'fa-plus-square', title: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project.create?'Click to Add Project':"Don't have permission", + disabled: this.state.userrole && this.state.userrole.userRolePermission.project?!this.state.userrole.userRolePermission.project.create:true, props: { pathname: '/project/create' } }]} /> } {this.state.isLoading ? <AppLoader /> : (this.state.isprocessed && this.state.projectlist.length > 0) ? diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js index 3ec4b735f5d43c4bacee740cb639e30860c769b1..074691ce04893dba700b9b9777ca874aea1057f7 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/view.js @@ -13,7 +13,7 @@ import ProjectService from '../../services/project.service'; import UnitConverter from '../../utils/unit.converter'; import SchedulingUnitList from './../Scheduling/SchedulingUnitList'; import UIConstants from '../../utils/ui.constants'; -import userrole from '../../authenticate/userrole'; +import AuthUtil from '../../utils/auth.util'; /** * Component to view the details of a project @@ -36,7 +36,6 @@ export class ProjectView extends Component { } componentDidMount() { - this.getUserRolePermission(); const projectId = this.state.projectId; if (projectId) { this.getProjectDetails(projectId); @@ -61,6 +60,8 @@ export class ProjectView extends Component { * */ async getProjectDetails() { + const permission = await AuthUtil.getUserRolePermission('project'); + this.setState({userrole: permission}); let project = await ProjectService.getProjectDetails(this.state.projectId); let projectQuota = []; let resources = []; @@ -85,10 +86,10 @@ export class ProjectView extends Component { /** * Get current user role permission for selected Project */ - getUserRolePermission = async () => { - await userrole.dispatch({ type: 'project' }); - this.setState({userrole: userrole.getState()}); - } + // getUserRolePermission = async () => { + // await userrole.dispatch({ type: 'project' }); + // this.setState({userrole: userrole.getState()}); + // } render() { if (this.state.redirect) { @@ -99,8 +100,10 @@ export class ProjectView extends Component { <React.Fragment> <TieredMenu className="app-header-menu" model={this.menuOptions} popup ref={el => this.optionsMenu = el} /> <PageHeader location={this.props.location} title={'Project - Details'} - actions={[ {icon: 'fa-edit',title:'Click to Edit Project', type:'link', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.project.edit:true, + actions={[ {icon: 'fa-edit', + title: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project.edit?'Click to Edit Project':"Don't have permission", + type:'link', + disabled: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project?!this.state.userrole.userRolePermission.project.edit:true, props : { pathname: `/project/edit/${this.state.project.name}`, state: {id: this.state.project?this.state.project.name:''&& this.state.project}}}, {icon:'fa-window-close',title: 'Click to Close Project View', link: this.props.history.goBack}]}/> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js index 6350a358826df2d3fc069c81c57ad93af6e0fd97..b83af2e2b22c26a870fa8c2581545aec2b5d01f8 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js @@ -17,7 +17,7 @@ import { appGrowl } from '../../layout/components/AppGrowl'; import UtilService from '../../services/util.service'; import { Dropdown } from 'primereact/dropdown'; import SUBCreator from './sub.create'; -import userrole from '../../authenticate/userrole'; +import AuthUtil from '../../utils/auth.util'; class SchedulingUnitList extends Component{ @@ -159,6 +159,7 @@ class SchedulingUnitList extends Component{ //defaultSortColumn: [{id: "Name", desc: false}], dialog: {header: 'Confirm', detail: 'Do you want to create a Scheduling Unit Blueprint?'} } + this.access_dined_message = "Don't have permission"; this.lsKeySortColumn = "SchedulingUnit_"+this.state.suType+"_SortData"; this.selectedRows = []; this.suDraftsList = []; // List of selected SU Drafts @@ -587,8 +588,10 @@ class SchedulingUnitList extends Component{ this.getFilterColumns(this.state.suType.toLowerCase()); } - componentDidMount(){ - this.getUserRolePermission(); + async componentDidMount(){ + const permission = await AuthUtil.getUserRolePermission('scheduleunit'); + this.setState({userrole: permission}); + //this.getUserRolePermission(); this.pageUpdated = true; this.getSchedulingUnitList(true, this.state.suType, this.filterQry, this.orderBy, this.limit, this.offset); this.setToggleBySorting(); @@ -1380,10 +1383,10 @@ class SchedulingUnitList extends Component{ /** * Get current user role permission for Schedule Unit List */ - getUserRolePermission = async() => { - await userrole.dispatch({ type: 'scheduleunit' }); - this.setState({userrole: userrole.getState()}); - } + // getUserRolePermission = async() => { + // await userrole.dispatch({ type: 'scheduleunit' }); + // this.setState({userrole: userrole.getState()}); + // } render(){ if (this.state.isLoading) { @@ -1427,38 +1430,38 @@ class SchedulingUnitList extends Component{ {this.state.suType === 'Draft' && <> <a href="#" style={{marginLeft: "5px"}} onClick={this.checkAndCreateSUB} - title="Create Blueprint(s)"> - <i class= {this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.createsub ?"fa fa-stamp":"fa fa-disabled fa-stamp"} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.createsub ? "Create Blueprint(s)":this.access_dined_message} > + <i class= {this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.createsub ?"fa fa-stamp":"fa fa-disabled fa-stamp"} aria-hidden="true" ></i> </a> </> } {this.state.suType === 'Blueprint' && <> - <a href="#" style={{marginLeft: "5px"}} onClick={this.cleanUpSUTask} - title="Create Clean-up Task(s)"> - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.cleanuptask?"fa fa-recycle":"fa fa-disabled fa-recycle"} + <a href="#" style={{marginLeft: "5px"}} onClick={this.cleanUpSUTask} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cleanuptask ? "Create Clean-up Task(s)":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cleanuptask?"fa fa-recycle":"fa fa-disabled fa-recycle"} aria-hidden="true" ></i> </a> - <a href="#" style={{marginLeft: "5px"}} onClick={this.confirmCancelSchedulingUnit} - title="Cancel selected Scheduling Unit(s)"> - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.cancelsu?"fa fa-ban":"fa fa-disabled fa-ban"} + <a href="#" style={{marginLeft: "5px"}} onClick={this.confirmCancelSchedulingUnit} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cancelsu ? "Cancel selected Scheduling Unit(s)":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cancelsu?"fa fa-ban":"fa fa-disabled fa-ban"} aria-hidden="true" ></i> </a> </> } <a href="#" style={{marginLeft: "5px"}} onClick={this.confirmAutoDeletion} - title="Prevent/Allow Automatic Deletion"> - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.autodeletion?"fa fa-thumbtack":"fa fa-disabled fa-thumbtack"} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.autodeletion ? "Prevent/Allow Automatic Deletion":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.autodeletion?"fa fa-thumbtack":"fa fa-disabled fa-thumbtack"} aria-hidden="true" ></i> </a> - <a href="#" style={{marginLeft: "5px"}} onClick={this.confirmCopyingSU} - title="Copy Scheduling Unit(s) Draft/Blueprint" > - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.copysu?"fa fa-copy":"fa fa-disabled fa-copy"} ></i> + <a href="#" style={{marginLeft: "5px"}} onClick={this.confirmCopyingSU} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.copysu ? "Copy Scheduling Unit(s) Draft/Blueprint":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.copysu?"fa fa-copy":"fa fa-disabled fa-copy"} ></i> </a> - <a href="#" style={{marginLeft: "5px"}} onClick={this.checkAndDeleteSchedulingUnit} - title="Delete selected Scheduling Unit(s)"> - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.delete?"fa fa-trash":"fa fa-disabled fa fa-trash"} + <a href="#" style={{marginLeft: "5px"}} onClick={this.checkAndDeleteSchedulingUnit} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.delete ? "Delete selected Scheduling Unit(s)":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.delete?"fa fa-trash":"fa fa-disabled fa fa-trash"} aria-hidden="true" ></i> </a> </> @@ -1466,12 +1469,12 @@ class SchedulingUnitList extends Component{ {this.props.project && <> <Link style={{marginLeft: "5px"}} to={`${this.props.project?"/project/"+this.props.project:""}/schedulingunit/create`} - title="Add New Scheduling Unit to this Project" > - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.create?"fa fa-plus":"fa fa-disabled fa fa-plus"} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.create ? "Add New Scheduling Unit to this Project":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.create?"fa fa-plus":"fa fa-disabled fa fa-plus"} ></i></Link> <Link style={{marginLeft: "5px"}} to={`${this.props.project?"/project/"+this.props.project:""}/schedulingset/schedulingunit/create`} - title="Add Scheduling Set to this Project" > - <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit.excelview?"fa fa-table":"fa fa-disabled fa fa-table"} + title={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.excelview ? "Add Scheduling Set to this Project":this.access_dined_message} > + <i class={this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.excelview?"fa fa-table":"fa fa-disabled fa fa-table"} ></i></Link> </> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js index 117bf4ee3474273e3930c1739e977358a8309a3c..0f10f05e025952775504c42514b397f77b088318 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js @@ -26,7 +26,7 @@ import TaskService from '../../services/task.service'; import UIConstants from '../../utils/ui.constants'; import UtilService from '../../services/util.service'; import { flattenDiagnosticMessageText } from 'typescript'; -import userrole from '../../authenticate/userrole'; +import AuthUtil from '../../utils/auth.util'; class ViewSchedulingUnit extends Component { lsKeySortColumn = 'SortDataViewSchedulingUnit'; @@ -155,6 +155,7 @@ class ViewSchedulingUnit extends Component { dataformat: ['MeasurementSet'], taskStatus: [] } + this.access_dined_message = "Don't have permission"; this.actions = []; this.stations = []; this.constraintTemplates = []; @@ -213,7 +214,9 @@ class ViewSchedulingUnit extends Component { } async componentDidMount() { - this.getUserRolePermission(); + const permission = await AuthUtil.getUserRolePermission('scheduleunit'); + this.setState({userrole: permission}); + //this.getUserRolePermission(); this.pageUpdated = true; this.setToggleBySorting(); let schedule_id = this.props.match.params.id; @@ -336,64 +339,78 @@ class ViewSchedulingUnit extends Component { getActionMenu(schedule_type, isIngestPresent) { this.actions = []; this.actions.unshift({ - icon: 'fa-copy', title: 'Copy Draft/Blueprint', type: 'button', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.copysu:true, + icon: 'fa-copy', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.copysu?'Copy Draft/Blueprint':this.access_dined_message, + type: 'button', + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.copysu:true, actOn: 'click', props: { callback: this.confirmCopyingSU }, }); let canDelete = (this.state.scheduleunit && (!this.state.scheduleunit.scheduling_unit_blueprints_ids || this.state.scheduleunit.scheduling_unit_blueprints_ids.length === 0)); this.actions.push({ - icon: 'fa fa-trash', title: !canDelete ? 'Cannot delete Draft when Blueprint exists' : 'Scheduling Unit', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.delete:true, - type: 'button', disabled: !canDelete, actOn: 'click', props: { callback: this.showDeleteSUConfirmation } + icon: 'fa fa-trash', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.delete?!canDelete ? 'Cannot delete Draft when Blueprint exists' : 'Delete Scheduling Unit':this.access_dined_message, + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.delete?canDelete?false:true : true, + type: 'button', actOn: 'click', props: { callback: this.showDeleteSUConfirmation } }); this.actions.push({ icon: 'fa-window-close', title: 'Click to Close Scheduling Unit View', link: this.props.history.goBack }); if (this.props.match.params.type ==='draft') { let blueprintExist = this.state.scheduleunit && this.state.scheduleunit.scheduling_unit_blueprints && this.state.scheduleunit.scheduling_unit_blueprints.length>0; if(isIngestPresent) { this.actions.unshift({ - icon: 'fa-file-import', title: 'Data Products To Ingest', type: 'button', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.dataproduct:true, + icon: 'fa-file-import', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.dataproduct?'Data Products To Ingest':this.access_dined_message, + type: 'button', + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.dataproduct:true, actOn: 'click', props: { callback: this.showTaskRelationDialog } }); } this.actions.unshift({ - icon: 'fa-edit', title: 'Click to edit', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.edit:true, + icon: 'fa-edit', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.edit?'Click to edit':this.access_dined_message, + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.edit:true, props: { pathname: `/schedulingunit/edit/${this.props.match.params.id}` } }); this.actions.unshift({ - icon: 'fa-stamp', title: blueprintExist?'Blueprint already exists': 'Create Blueprint', type: 'button', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.createsub:true, + icon: 'fa-stamp', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.createsub?blueprintExist?'Blueprint already exists': 'Create Blueprint':this.access_dined_message, + type: 'button', + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.createsub:true, actOn: 'click', disabled: blueprintExist, props: { callback: this.checkAndCreateBlueprint }, }); } else { this.actions.unshift({ - icon: 'fa-thumbtack', title: this.state.scheduleunit.output_pinned? 'Allow Automatic Deletion' : 'Prevent Automatic Deletion', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.autodeletion:true, + icon: 'fa-thumbtack', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.autodeletion?this.state.scheduleunit.output_pinned? 'Allow Automatic Deletion' : 'Prevent Automatic Deletion':this.access_dined_message, + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.autodeletion:true, type: 'button', actOn: 'click', props: { callback: this.confirmAutoDeletion } }); if(isIngestPresent) { this.actions.unshift({ - icon: 'fa-file-import', title: 'Data Products To Ingest', type: 'button', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.dataproduct:!(this.state.scheduleunit.status === 'defined' || this.state.scheduleunit.status === 'scheduled' || this.state.scheduleunit.status === 'schedulable'), + icon: 'fa-file-import', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.dataproduct?'Data Products To Ingest':this.access_dined_message, + type: 'button', + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.dataproduct:!(this.state.scheduleunit.status === 'defined' || this.state.scheduleunit.status === 'scheduled' || this.state.scheduleunit.status === 'schedulable'), actOn: 'click', props: { callback: this.showTaskRelationDialog } }); } this.actions.unshift({ - icon: 'fa-ban', type: 'button', actOn: 'click', - title: this.SU_END_STATUSES.indexOf(this.state.scheduleunit.status.toLowerCase())>=0?'Cannot Cancel Scheduling Unit':'Cancel Scheduling Unit', - disabled:this.SU_END_STATUSES.indexOf(this.state.scheduleunit.status.toLowerCase())>=0, + icon: 'fa-ban', type: 'button', actOn: 'click', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cancelsu?this.SU_END_STATUSES.indexOf(this.state.scheduleunit.status.toLowerCase())>=0?'Cannot Cancel Scheduling Unit':'Cancel Scheduling Unit':this.access_dined_message, + disabled:this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cancelsu? this.SU_END_STATUSES.indexOf(this.state.scheduleunit.status.toLowerCase())>=0 ? true : false:true, props: { callback: this.showCancelSUConfirmation } }); this.actions.unshift({ - icon: 'fa fa-recycle', title: 'Create Clean-up Task', type: 'button', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.cleanuptask:true, + icon: 'fa fa-recycle', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.cleanuptask?'Create Clean-up Task':this.access_dined_message, + type: 'button', + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.cleanuptask:true, actOn: 'click', props: { callback: this.cleanUpSUTask } }); this.actions.unshift({ - icon: 'fa-sitemap', title: 'View Workflow', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.viewworkflow:true, + icon: 'fa-sitemap', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.viewworkflow?'View Workflow':this.access_dined_message, + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.viewworkflow:true, props: { pathname: `/schedulingunit/${this.props.match.params.id}/workflow` } }); this.actions.unshift({ icon: 'fa-lock', title: 'Cannot edit blueprint' }); } @@ -1239,10 +1256,10 @@ class ViewSchedulingUnit extends Component { /** * Get current user role permission for selected Schedule Unit */ - getUserRolePermission = async () => { - await userrole.dispatch({ type: 'scheduleunit' }); - this.setState({userrole: userrole.getState()}); - } + // getUserRolePermission = async () => { + // await userrole.dispatch({ type: 'scheduleunit' }); + // this.setState({userrole: userrole.getState()}); + // } render() { if (this.state.redirect) { diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js index 3f70737bd6c5fd184067088990a3349c12194d1b..aa4ebe3c2832dfd8b85f8e28738364f6fbd75e08 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js @@ -6,7 +6,7 @@ import SchedulingUnitList from './SchedulingUnitList'; import PageHeader from '../../layout/components/PageHeader'; import { appGrowl } from '../../layout/components/AppGrowl'; import { CustomDialog } from '../../layout/components/CustomDialog'; -import userrole from '../../authenticate/userrole'; +import AuthUtil from '../../utils/auth.util'; export class Scheduling extends Component { constructor(props){ @@ -19,6 +19,7 @@ export class Scheduling extends Component { dialog: {header: 'Confirm', detail: 'Do you want to create blueprints for the selected drafts?'}, dialogVisible: false }; + this.access_dined_message = "Don't have permission"; this.optionsMenu = React.createRef(); this.menuOptions = [ {label:'Add Scheduling Set', icon: "fa fa-", command: () => {this.selectOptionMenu('Add-SU-Set') }}]; this.showOptionMenu = this.showOptionMenu.bind(this); @@ -26,8 +27,10 @@ export class Scheduling extends Component { this.closeDialog = this.closeDialog.bind(this); } - componentDidMount() { - this.getUserRolePermission() + async componentDidMount() { + const permission = await AuthUtil.getUserRolePermission('scheduleunit'); + this.setState({userrole: permission}); + //this.getUserRolePermission() } /** * Callback function to close the dialog prompted. @@ -56,10 +59,10 @@ export class Scheduling extends Component { * Get current user role permission for Schedule Unit List */ - getUserRolePermission = async() => { - await userrole.dispatch({ type: 'scheduleunit' }); - this.setState({userrole: userrole.getState()}); - } + // getUserRolePermission = async() => { + // await userrole.dispatch({ type: 'scheduleunit' }); + // this.setState({userrole: userrole.getState()}); + // } render() { return ( @@ -67,12 +70,14 @@ export class Scheduling extends Component { <TieredMenu className="app-header-menu" model={this.menuOptions} popup ref={el => this.optionsMenu = el} /> <PageHeader location={this.props.location} title={'Scheduling Unit - List'} actions={[ - {icon: 'fa fa-plus-square', title: 'Add New Scheduling Unit', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.create:true, + {icon: 'fa fa-plus-square', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.create?'Add New Scheduling Unit':this.access_dined_message, + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.create:true, props: {pathname: '/schedulingunit/create'}}, - {icon: 'fa fa-table', title: 'Add Scheduling Set', - disabled: this.state.userrole?!this.state.userrole.userRolePermission.scheduleunit.excelview:true, + {icon: 'fa fa-table', + title: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit && this.state.userrole.userRolePermission.scheduleunit.excelview?'Add Scheduling Set':this.access_dined_message, + disabled: this.state.userrole && this.state.userrole.userRolePermission.scheduleunit?!this.state.userrole.userRolePermission.scheduleunit.excelview:true, props: {pathname: '/schedulingset/schedulingunit/create'}}, ]} /> {this.state.scheduleunit && diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/auth.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/auth.service.js index 34d4ca35b3dcc528b5f33dd3994fceabc651b239..26bdf0f93be70bbddf665cc5be5f04fe28434c8a 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/services/auth.service.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/auth.service.js @@ -27,7 +27,15 @@ const AuthService = { } catch(error) { console.error(error); } + }, + getAccessControlMethod: (subdomain) => { + let res = []; + try { + res = axios.get(`/api/${subdomain}/`); + } catch(error) { + console.error('[AuthService.getAccessControlMethod]',error); + } + return res; } } - export default AuthService; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/utils/auth.util.js b/SAS/TMSS/frontend/tmss_webapp/src/utils/auth.util.js new file mode 100644 index 0000000000000000000000000000000000000000..0b9507c79c8754a8f527a751d1007c75515d6708 --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/utils/auth.util.js @@ -0,0 +1,10 @@ +import AuthStore from "../authenticate/auth.store"; + +const AuthUtil = { + getUserRolePermission : async function(module) { + await AuthStore.dispatch({ type: module }); + return AuthStore.getState(); + } +}; + +export default AuthUtil; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/utils/permission.stack.handler.js b/SAS/TMSS/frontend/tmss_webapp/src/utils/permission.stack.handler.js deleted file mode 100644 index 6b69c936434576dd343d83d2b5bc6966703e1ac0..0000000000000000000000000000000000000000 --- a/SAS/TMSS/frontend/tmss_webapp/src/utils/permission.stack.handler.js +++ /dev/null @@ -1,41 +0,0 @@ -import userrole from './../authenticate/userrole'; -import ScheduleService from './../services/schedule.service'; -import Auth from './../authenticate/auth'; - -const PermissionStackUtil = { - /** - * Get current user permission from API - * @param {*} loadPermission - * @returns - */ - getPermissions: async(loadPermission) => { - let permissionStack = {}; - if (loadPermission) { - // Get relavent API permission and prepare the front-end, currently hard coded - /*const permissions = await ScheduleService.getSchedulingUnitFilterDefinition('blueprint'); - if (permissions) { - let allowedPermission = permissions.headers.allow; - }*/ - let user = Auth.getUser(); - user = user?user.name:""; - if (user === 'scientist' ) { - permissionStack['project'] = {create: true, edit: false, delete: true}; - permissionStack['scheduleunit'] = {create: true, edit: false, delete: true, createsub: false, autodeletion:false, - copysu:false, excelview:true, cleanuptask:false, cancelsu:false, viewworkflow:true,dataproduct: true,}; - } else if (user === 'operator' ) { - permissionStack['project'] = {create: true, edit: false, delete: false}; - permissionStack['scheduleunit'] = {create: true, edit: false, delete: false, createsub: false, autodeletion:true, - copysu:true, excelview:false, cleanuptask:true, cancelsu:false, viewworkflow:true,dataproduct: false,}; - } else { - permissionStack['project'] = {create: true, edit: true, delete: true}; - permissionStack['scheduleunit'] = {create: true, edit: true, delete: true, createsub: true, autodeletion:true, - copysu:true, excelview:true, cleanuptask:true, cancelsu:true, viewworkflow:true,dataproduct: true,}; - } - } - userrole.dispatch({ type: 'loadpermission', payload: permissionStack}); - return permissionStack - } - -} - -export default PermissionStackUtil; \ No newline at end of file