/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
var Utils = {};
Utils.DescriptorModelMeta = null;
+// Utils.DescriptorModelMeta = require('./../../plugins/composer/src/src/libraries/model/DescriptorModelMeta.json');
var INACTIVITY_TIMEOUT = 600000;
import './skyquakeNav.scss';
import SelectOption from '../form_controls/selectOption.jsx';
import {FormSection} from '../form_controls/formControls.jsx';
-import SkyquakeRBAC from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
+import {isRBACValid, SkyquakeRBAC} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
//Temporary, until api server is on same port as webserver
var rw = require('utils/rw.js');
skyquakeNav.defaultProps = {
nav: {}
}
+skyquakeNav.contextTypes = {
+ userProfile: React.PropTypes.object
+};
/**
* Returns a React Component
* @param {object} link Information about the nav link
let secondaryNav = [];
let adminNav = [];
let self = this;
+ const User = this.context.userProfile;
self.hasSubNav = {};
let secondaryNavHTML = (
<div className="secondaryNav" key="secondaryNav">
</li>
))
} else {
- navItem.html = (
- <SkyquakeRBAC allow={nav[k].allow || ['*']} key={k} className={navClass}>
- <h2>{dashboardLink} {self.hasSubNav[k] ? <span className="oi" data-glyph="caret-bottom"></span> : ''}</h2>
- <ul className="menu">
- {
- NavList
- }
- </ul>
- </SkyquakeRBAC>
- );
+ let shouldAllow = nav[k].allow || ['*'];
+ if (isRBACValid(User, shouldAllow) ){
+ navItem.html = (
+ <div key={k} className={navClass}>
+ <h2>{dashboardLink} {self.hasSubNav[k] ? <span className="oi" data-glyph="caret-bottom"></span> : ''}</h2>
+ <ul className="menu">
+ {
+ NavList
+ }
+ </ul>
+ </div>
+ );
+ }
navList.push(navItem)
}
import ROLES from 'utils/roleConstants.js';
const PLATFORM = ROLES.PLATFORM;
+export function isRBACValid(User, allow){
+ const UserData = User.data;
+ if(UserData) {
+ const PlatformRole = UserData.platform.role;
+ const isPlatformSuper = PlatformRole[PLATFORM.SUPER];
+ const isPlatformAdmin = PlatformRole[PLATFORM.ADMIN];
+ const isPlatformOper = PlatformRole[PLATFORM.OPER];
+ const hasRoleAccess = checkForRoleAccess(UserData.project[User.projectId], PlatformRole, allow)//false//(this.props.roles.indexOf(userProfile.projectRole) > -1)
+ if (isPlatformSuper) {
+ return true;
+ } else {
+ if (hasRoleAccess) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
export default class SkyquakeRBAC extends React.Component {
constructor(props, context) {
super(props);
const UserData = User.data;
let HTML = null;
// If user object has platform property then it has been populated by the back end.
- if(UserData) {
- const PlatformRole = UserData.platform.role;
- const isPlatformSuper = PlatformRole[PLATFORM.SUPER];
- const isPlatformAdmin = PlatformRole[PLATFORM.ADMIN];
- const isPlatformOper = PlatformRole[PLATFORM.OPER];
- const hasRoleAccess = checkForRoleAccess(UserData.project[User.projectId], PlatformRole, this.props.allow)//false//(this.props.roles.indexOf(userProfile.projectRole) > -1)
- if (isPlatformSuper) {
- HTML = this.props.children;
- } else {
- if (hasRoleAccess) {
- HTML = this.props.children;
- }
- }
+ if(isRBACValid(User, this.props.allow)) {
+ HTML = this.props.children;
}
return (<div className={this.props.className} style={this.props.style}>{HTML}</div>)
}
label: null,
title: null,
src: null,
+ disabled: false,
onClick: () => {}
};
},
const draggable = this.props.draggable;
const className = ClassNames(this.props.className, 'Button');
return (
- <div className={className} onClick={this.props.onClick} title={title} draggable={draggable} onDragStart={this.props.onDragStart}>
+ <div className={className} onClick={this.props.onClick} title={title} draggable={draggable} onDragStart={this.props.onDragStart} style={{pointerEvents: (this.props.disabled ? 'none' : 'auto'), cursor: (this.props.disabled ? 'not-allowed' : 'auto'), position: 'relative'}}>
{ src ? <img src={src} /> : null }
{label}
</div>
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
import React from 'react'
import PureRenderMixin from 'react-addons-pure-render-mixin'
import EditDescriptorModelProperties from './EditDescriptorModelProperties'
+import {SkyquakeRBAC, isRBACValid} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
+import ROLES from 'utils/roleConstants.js';
+const PROJECT_ROLES = ROLES.PROJECT;
+const PLATFORM = ROLES.PLATFORM;
const CatalogItemDetailsEditor = React.createClass({
mixins: [PureRenderMixin],
width: 0
};
},
+ contextTypes: {
+ router: React.PropTypes.object,
+ userProfile: React.PropTypes.object
+ },
componentWillMount() {
},
componentDidMount() {
componentWillUnmount() {
},
render() {
+ const User = this.context.userProfile;
const container = this.props.container || {model: {}, uiState: {}};
if (!(container && container.model && container.uiState)) {
<div className="CatalogItemDetailsEditor">
<form name="details-descriptor-editor-form">
<div className="properties-group">
- <EditDescriptorModelProperties container={this.props.container} width={this.props.width} />
+ {
+ isRBACValid(User, [PROJECT_ROLES.CAT_ADMIN]) ?
+ <EditDescriptorModelProperties container={this.props.container} width={this.props.width} />
+ : <EditDescriptorModelProperties container={this.props.container} width={this.props.width} readonly={true} />
+ }
</div>
</form>
</div>
}
});
+CatalogItemDetailsEditor.contextTypes = {
+ router: React.PropTypes.object,
+ userProfile: React.PropTypes.object
+};
export default CatalogItemDetailsEditor;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
import imgUpdate from '../../../node_modules/open-iconic/svg/rain.svg'
import imgDownload from '../../../node_modules/open-iconic/svg/cloud-download.svg'
import imgDelete from '../../../node_modules/open-iconic/svg/trash.svg'
+import {SkyquakeRBAC, isRBACValid} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
+import ROLES from 'utils/roleConstants.js';
+const PROJECT_ROLES = ROLES.PROJECT;
+const PLATFORM = ROLES.PLATFORM;
const CatalogHeader = React.createClass({
mixins: [PureRenderMixin],
},
componentWillUnmount() {
},
+ contextTypes: {
+ userProfile: React.PropTypes.object
+ },
render() {
+ const disabled = !isRBACValid(this.context.userProfile, [PROJECT_ROLES.CAT_ADMIN]);
return (
<div className="CatalogPanelToolbar">
<h1>Descriptor Catalogs</h1>
<div className="btn-bar">
<div className="btn-group">
- <Button type="image" title="OnBoard a catalog package" className="action-onboard-catalog-package" onClick={this.onClickOnBoardCatalog} src={imgOnboard} />
- <Button type="image" title="Update a catalog package" className="action-update-catalog-package" onClick={this.onClickUpdateCatalog} src={imgUpdate} />
- <Button type="image" title="Export selected catalog item(s)" className="action-export-catalog-items" onClick={this.onClickExportCatalogItems} src={imgDownload} />
+ <Button type="image" title="OnBoard a catalog package" className="action-onboard-catalog-package" onClick={this.onClickOnBoardCatalog} src={imgOnboard} disabled={disabled}/>
+ <Button type="image" title="Update a catalog package" className="action-update-catalog-package" onClick={this.onClickUpdateCatalog} src={imgUpdate} disabled={disabled}/>
+ <Button type="image" title="Export selected catalog item(s)" className="action-export-catalog-items" onClick={this.onClickExportCatalogItems} src={imgDownload} disabled={disabled}/>
</div>
<div className="btn-group">
<div className="menu">
- <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} />
+ <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} disabled={disabled}/>
<div className="sub-menu">
- <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} label="Add NSD" />
- <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'vnfd')} src={imgAdd} label="Add VNFD" />
+ <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'nsd')} src={imgAdd} label="Add NSD" disabled={disabled}/>
+ <Button type="image" title="Create a new catalog item" className="action-create-catalog-item" onClick={this.onClickCreateCatalogItem.bind(null, 'vnfd')} src={imgAdd} label="Add VNFD" disabled={disabled}/>
</div>
</div>
- <Button type="image" title="Copy catalog item" className="action-copy-catalog-item" onClick={this.onClickDuplicateCatalogItem} src={imgCopy} />
+ <Button type="image" title="Copy catalog item" className="action-copy-catalog-item" onClick={this.onClickDuplicateCatalogItem} src={imgCopy} disabled={disabled}/>
</div>
<div className="btn-group">
- <Button type="image" title="Delete catalog item" className="action-delete-catalog-item" onClick = {this.onClickDeleteCatalogItem} src={imgDelete} />
+ <Button type="image" title="Delete catalog item" className="action-delete-catalog-item" onClick = {this.onClickDeleteCatalogItem} src={imgDelete} disabled={disabled}/>
</div>
</div>
</div>
import CatalogItemsActions from '../actions/CatalogItemsActions'
import CommonUtils from 'utils/utils.js'
import FileManagerActions from './filemanager/FileManagerActions';
+import {SkyquakeRBAC, isRBACValid} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
+import ROLES from 'utils/roleConstants.js';
+
import 'normalize.css'
import '../styles/AppRoot.scss'
import 'style/layout.scss'
const preventDefault = e => e.preventDefault();
const clearDragState = () => ComposerAppActions.setDragState(null);
+const PROJECT_ROLES = ROLES.PROJECT;
+const PLATFORM = ROLES.PLATFORM;
const ComposerApp = React.createClass({
mixins: [PureRenderMixin],
getDefaultProps() {
return {};
},
+ contextTypes: {
+ router: React.PropTypes.object,
+ userProfile: React.PropTypes.object
+ },
componentWillMount() {
if (clearLocalStorage) {
window.localStorage.clear();
render() {
let html = null;
let self = this;
+ const User = this.context.userProfile || {};
if(this.state.hasModel) {
function onClickUpdateSelection(event) {
isEditingVNFD={isEditingVNFD}
isModified={isModified}
isNew={isNew}
- disabled={!hasItem}
+ disabled={!hasItem || !isRBACValid(User, [PROJECT_ROLES.CAT_ADMIN])}
onClick={event => event.stopPropagation()}
panelTabShown={self.state.panelTabShown}/>
</div>
});
+
export default ComposerApp;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
}
});
+DetailsPanel.contextTypes = {
+ router: React.PropTypes.object,
+ userProfile: React.PropTypes.object
+};
+
export default DetailsPanel;
export default function EditDescriptorModelProperties(props) {
const container = props.container;
-
+ const readonly = props.readonly;
if (!(DescriptorModelFactory.isContainer(container))) {
return
}
}
CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
}
+ if(readonly) {
+ return null;
+ }
return (
<Button className="inline-hint" onClick={onClickAddProperty.bind(container, property, path)} label="Add" src={imgAdd} />
);
}
CatalogItemsActions.catalogItemDescriptorChanged(this.getRoot());
}
+ if(readonly) {
+ return null;
+ }
return (
<Button className="remove-property-action inline-hint" title="Remove" onClick={onClickRemoveProperty.bind(container, property, path)} label="Remove" src={imgRemove}/>
);
let catalogs = cds.getTransientCatalogs();
const name = path.join('.');
- const isEditable = true;
+ const isEditable = !readonly; //true
const isGuid = Property.isGuid(property);
const isBoolean = Property.isBoolean(property);
const onChange = onFormFieldValueChanged.bind(container);
const noValueDisplayText = changeCase.title(property.name);
options.unshift(<option key={'(value-not-in-enum)' + fieldKey.toString()} value="" placeholder={placeholder}>{noValueDisplayText}</option>);
}
- return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} readOnly={!isEditable}>{options}</select>;
+ return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} disabled={!isEditable}>{options}</select>;
}
if (isLeafRef) {
const noValueDisplayText = changeCase.title(property.name);
options.unshift(<option key={'(value-not-in-leafref)' + fieldKey.toString()} value="" placeholder={placeholder}>{noValueDisplayText}</option>);
}
- return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} readOnly={!isEditable}>{options}</select>;
+ return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={value} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} disabled={!isEditable}>{options}</select>;
}
if (isBoolean) {
val = value ? "TRUE" : "FALSE"
}
const isValueSet = (val != '' && val)
- return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={val && val.toUpperCase()} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} readOnly={!isEditable}>{options}</select>;
+ return <select key={fieldKey.toString()} id={fieldKey.toString()} className={ClassNames({'-value-not-set': !isValueSet})} name={name} value={val && val.toUpperCase()} title={name} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} disabled={!isEditable}>{options}</select>;
}
if (property['preserve-line-breaks']) {
- return <textarea key={fieldKey.toString()} cols="5" id={fieldKey.toString()} name={name} value={value} placeholder={placeholder} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!isEditable} />;
+ return <textarea key={fieldKey.toString()} cols="5" id={fieldKey.toString()} name={name} value={value} placeholder={placeholder} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!!isEditable} />;
}
- return <input key={fieldKey.toString()}
- id={fieldKey.toString()}
- type="text"
- name={name}
- value={fieldValue}
- className={className}
- placeholder={placeholder}
- onChange={onChange}
- onFocus={onFocus}
- onBlur={endEditing}
- onMouseDown={startEditing}
- onMouseOver={startEditing}
- onMouseOut={endEditing}
- onMouseLeave={endEditing}
- readOnly={!isEditable}
+ return <input
+ key={fieldKey.toString()}
+ id={fieldKey.toString()}
+ type="text"
+ name={name}
+ value={fieldValue}
+ className={className}
+ placeholder={placeholder}
+ onChange={onChange}
+ onFocus={onFocus}
+ onBlur={endEditing}
+ onMouseDown={startEditing}
+ onMouseOver={startEditing}
+ onMouseOut={endEditing}
+ onMouseLeave={endEditing}
+ readOnly={!isEditable}
/>;
}
return (
<div key={key} className="choice">
- <select key={Date.now()} className={ClassNames({'-value-not-set': !selectedOptionValue})} name={selectName} value={selectedOptionValue} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing}>
+ <select key={Date.now()} className={ClassNames({'-value-not-set': !selectedOptionValue})} name={selectName} value={selectedOptionValue} onChange={onChange} onFocus={onFocus} onBlur={endEditing} onMouseDown={startEditing} onMouseOver={startEditing} onMouseOut={endEditing} onMouseLeave={endEditing} readOnly={!isEditable}>
{options}
</select>
{valueResponse}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
import onCutDelegateToRemove from './onCutDelegateToRemove'
import onClickSelectAndShowInDetailsPanel from './onClickSelectAndShowInDetailsPanel'
+import {SkyquakeRBAC, isRBACValid} from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
+import ROLES from 'utils/roleConstants.js';
+const PROJECT_ROLES = ROLES.PROJECT;
+const PLATFORM = ROLES.PLATFORM;
+
import '../../styles/EditForwardingGraphPaths.scss'
import imgNSD from '../../images/default-catalog-icon.svg'
<div key={i} className={fg.className} data-uid={fg.uid} data-offset-width="true" onClick={onClickSelectAndShowInDetailsPanel.bind(null, fg)} onCut={onCutDelegateToRemove.bind(null, fg)}>
<div key="outline-indicator" data-outline-indicator="true"></div>
<div className="header-actions">
- <Button className="remove-forwarding-graph" title="Remove" onClick={onClickRemoveForwardingGraph.bind(null, fg)} src={imgRemove}/>
+ {
+ this.isRBACValid ?
+ <Button className="remove-forwarding-graph" title="Remove" onClick={onClickRemoveForwardingGraph.bind(null, fg)} src={imgRemove}/>
+ : null
+ }
</div>
<LayoutRow primaryActionColumn={toggleSelectAllPaths} secondaryActionColumn={<img className="fg-icon" src={imgFG} width="20px" />}>
<small>{fg.title}</small>
{fg.classifier.map(mapClassifier.bind(null, context))}
<div className="footer-actions">
<div className="row-action-column">
- <Button className="create-new-classifier" src={imgAdd} width="20px" onClick={onClickAddClassifier.bind(null, context, fg)} label="Add Classifier" />
+ {
+ this.isRBACValid ?
+ <Button className="create-new-classifier" src={imgAdd} width="20px" onClick={onClickAddClassifier.bind(null, context, fg)} label="Add Classifier" />
+ : null
+ }
</div>
</div>
</div>
{forwardingGraphs}
<div className="footer-actions">
<div className="row-action-column">
- <Button className="create-new-forwarding-graph" src={imgAdd} width="20px" onClick={onClickAddForwardingGraph.bind(null, nsd)} label="Add new Forwarding Graph" />
+ {
+ this.isRBACValid ?
+ <Button className="create-new-forwarding-graph" src={imgAdd} width="20px" onClick={onClickAddForwardingGraph.bind(null, nsd)} label="Add new Forwarding Graph" />
+ : null
+ }
</div>
</div>
</div>
},
componentWillUnmount: function () {
},
+ contextTypes: {
+ userProfile: React.PropTypes.object
+ },
render() {
-
const containers = this.props.containers;
const context = {
component: this,
- containers: containers
+ containers: containers,
+ isRBACValid: isRBACValid(this.context.userProfile, [PROJECT_ROLES.CAT_ADMIN])
};
-
const networkService = containers.filter(d => d.type === 'nsd');
if (networkService.length === 0) {
return <p className="welcome-message">No <img src={imgNSD} width="20px" /> NSD open in the canvas. Try opening an NSD.</p>;