mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feature: Add support for permission system in unleash frontend
This commit is contained in:
		
							parent
							
								
									6de8c297fd
								
							
						
					
					
						commit
						1eb8fc0464
					
				@ -22,6 +22,8 @@ import {
 | 
			
		||||
} from 'react-mdl';
 | 
			
		||||
import { IconLink, shorten, styles as commonStyles } from '../common';
 | 
			
		||||
import { formatFullDateTimeWithLocale } from '../common/util';
 | 
			
		||||
import { CREATE_FEATURE, CREATE_STRATEGY, UPDATE_APPLICATION } from '../../permissions';
 | 
			
		||||
import PermissionComponent from '../common/permission-container';
 | 
			
		||||
 | 
			
		||||
class StatefulTextfield extends Component {
 | 
			
		||||
    static propTypes = {
 | 
			
		||||
@ -91,11 +93,26 @@ class ClientApplications extends PureComponent {
 | 
			
		||||
                            {seenToggles.map(
 | 
			
		||||
                                ({ name, description, enabled, notFound }, i) =>
 | 
			
		||||
                                    notFound ? (
 | 
			
		||||
                                        <PermissionComponent
 | 
			
		||||
                                            permission={CREATE_FEATURE}
 | 
			
		||||
                                            component={
 | 
			
		||||
                                                <ListItem twoLine key={i}>
 | 
			
		||||
                                            <ListItemContent icon={'report'} subtitle={'Missing, want to create?'}>
 | 
			
		||||
                                                    <ListItemContent
 | 
			
		||||
                                                        icon={'report'}
 | 
			
		||||
                                                        subtitle={'Missing, want to create?'}
 | 
			
		||||
                                                    >
 | 
			
		||||
                                                        <Link to={`/features/create?name=${name}`}>{name}</Link>
 | 
			
		||||
                                                    </ListItemContent>
 | 
			
		||||
                                                </ListItem>
 | 
			
		||||
                                            }
 | 
			
		||||
                                            otherwise={
 | 
			
		||||
                                                <ListItem twoLine key={i}>
 | 
			
		||||
                                                    <ListItemContent icon={'report'} subtitle={'Missing'}>
 | 
			
		||||
                                                        {name}
 | 
			
		||||
                                                    </ListItemContent>
 | 
			
		||||
                                                </ListItem>
 | 
			
		||||
                                            }
 | 
			
		||||
                                        />
 | 
			
		||||
                                    ) : (
 | 
			
		||||
                                        <ListItem twoLine key={i}>
 | 
			
		||||
                                            <ListItemContent
 | 
			
		||||
@ -120,11 +137,26 @@ class ClientApplications extends PureComponent {
 | 
			
		||||
                            {strategies.map(
 | 
			
		||||
                                ({ name, description, notFound }, i) =>
 | 
			
		||||
                                    notFound ? (
 | 
			
		||||
                                        <PermissionComponent
 | 
			
		||||
                                            permission={CREATE_STRATEGY}
 | 
			
		||||
                                            component={
 | 
			
		||||
                                                <ListItem twoLine key={`${name}-${i}`}>
 | 
			
		||||
                                            <ListItemContent icon={'report'} subtitle={'Missing, want to create?'}>
 | 
			
		||||
                                                    <ListItemContent
 | 
			
		||||
                                                        icon={'report'}
 | 
			
		||||
                                                        subtitle={'Missing, want to create?'}
 | 
			
		||||
                                                    >
 | 
			
		||||
                                                        <Link to={`/strategies/create?name=${name}`}>{name}</Link>
 | 
			
		||||
                                                    </ListItemContent>
 | 
			
		||||
                                                </ListItem>
 | 
			
		||||
                                            }
 | 
			
		||||
                                            otherwise={
 | 
			
		||||
                                                <ListItem twoLine key={`${name}-${i}`}>
 | 
			
		||||
                                                    <ListItemContent icon={'report'} subtitle={'Missing'}>
 | 
			
		||||
                                                        {name}
 | 
			
		||||
                                                    </ListItemContent>
 | 
			
		||||
                                                </ListItem>
 | 
			
		||||
                                            }
 | 
			
		||||
                                        />
 | 
			
		||||
                                    ) : (
 | 
			
		||||
                                        <ListItem twoLine key={`${name}-${i}`}>
 | 
			
		||||
                                            <ListItemContent icon={'extension'} subtitle={shorten(description, 60)}>
 | 
			
		||||
@ -203,6 +235,9 @@ class ClientApplications extends PureComponent {
 | 
			
		||||
                    </CardMenu>
 | 
			
		||||
                )}
 | 
			
		||||
                <hr />
 | 
			
		||||
                <PermissionComponent
 | 
			
		||||
                    permission={UPDATE_APPLICATION}
 | 
			
		||||
                    component={
 | 
			
		||||
                        <Tabs
 | 
			
		||||
                            activeTab={this.state.activeTab}
 | 
			
		||||
                            onChange={tabId => this.setState({ activeTab: tabId })}
 | 
			
		||||
@ -213,6 +248,8 @@ class ClientApplications extends PureComponent {
 | 
			
		||||
                            <Tab>Details</Tab>
 | 
			
		||||
                            <Tab>Edit</Tab>
 | 
			
		||||
                        </Tabs>
 | 
			
		||||
                    }
 | 
			
		||||
                />
 | 
			
		||||
 | 
			
		||||
                {content}
 | 
			
		||||
            </Card>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										47
									
								
								frontend/src/component/common/permission-component.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								frontend/src/component/common/permission-component.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { ADMIN } from '../../permissions';
 | 
			
		||||
 | 
			
		||||
class PermissionComponent extends Component {
 | 
			
		||||
    static propTypes = {
 | 
			
		||||
        user: PropTypes.object,
 | 
			
		||||
        component: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
 | 
			
		||||
        others: PropTypes.object,
 | 
			
		||||
        denied: PropTypes.object,
 | 
			
		||||
        granted: PropTypes.object,
 | 
			
		||||
        otherwise: PropTypes.node,
 | 
			
		||||
        permission: PropTypes.string,
 | 
			
		||||
        children: PropTypes.node,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        const { user, otherwise, component: Component, permission, granted, denied, children, ...others } = this.props;
 | 
			
		||||
        let grantedComponent = Component;
 | 
			
		||||
        let deniedCompoinent = otherwise || '';
 | 
			
		||||
 | 
			
		||||
        if (granted || denied) {
 | 
			
		||||
            grantedComponent = (
 | 
			
		||||
                <Component {...others} {...granted || {}}>
 | 
			
		||||
                    {children}
 | 
			
		||||
                </Component>
 | 
			
		||||
            );
 | 
			
		||||
            deniedCompoinent = (
 | 
			
		||||
                <Component {...others} {...denied || {}}>
 | 
			
		||||
                    {children}
 | 
			
		||||
                </Component>
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!user) return deniedCompoinent;
 | 
			
		||||
        if (
 | 
			
		||||
            !user.permissions ||
 | 
			
		||||
            user.permissions.indexOf(ADMIN) !== -1 ||
 | 
			
		||||
            user.permissions.indexOf(permission) !== -1
 | 
			
		||||
        ) {
 | 
			
		||||
            return grantedComponent;
 | 
			
		||||
        }
 | 
			
		||||
        return deniedCompoinent;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default PermissionComponent;
 | 
			
		||||
							
								
								
									
										8
									
								
								frontend/src/component/common/permission-container.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								frontend/src/component/common/permission-container.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import PermissionComponent from './permission-component';
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = state => ({ user: state.user.get('profile') });
 | 
			
		||||
 | 
			
		||||
const Container = connect(mapStateToProps)(PermissionComponent);
 | 
			
		||||
 | 
			
		||||
export default Container;
 | 
			
		||||
@ -22,7 +22,7 @@ exports[`renders correctly with one feature 1`] = `
 | 
			
		||||
  >
 | 
			
		||||
    <react-mdl-Switch
 | 
			
		||||
      checked={false}
 | 
			
		||||
      disabled={false}
 | 
			
		||||
      disabled={true}
 | 
			
		||||
      onChange={[Function]}
 | 
			
		||||
      title="Toggle Another"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ const Feature = ({
 | 
			
		||||
    metricsLastHour = { yes: 0, no: 0, isFallback: true },
 | 
			
		||||
    metricsLastMinute = { yes: 0, no: 0, isFallback: true },
 | 
			
		||||
    revive,
 | 
			
		||||
    updateable,
 | 
			
		||||
}) => {
 | 
			
		||||
    const { name, description, enabled, strategies } = feature;
 | 
			
		||||
    const { showLastHour = false } = settings;
 | 
			
		||||
@ -42,7 +43,7 @@ const Feature = ({
 | 
			
		||||
            </span>
 | 
			
		||||
            <span className={styles.listItemToggle}>
 | 
			
		||||
                <Switch
 | 
			
		||||
                    disabled={toggleFeature === undefined}
 | 
			
		||||
                    disabled={!updateable || toggleFeature === undefined}
 | 
			
		||||
                    title={`Toggle ${name}`}
 | 
			
		||||
                    key="left-actions"
 | 
			
		||||
                    onChange={() => toggleFeature(name)}
 | 
			
		||||
@ -59,7 +60,7 @@ const Feature = ({
 | 
			
		||||
                {strategyChips}
 | 
			
		||||
                {summaryChip}
 | 
			
		||||
            </span>
 | 
			
		||||
            {revive ? (
 | 
			
		||||
            {updateable && revive ? (
 | 
			
		||||
                <ListItemAction onClick={() => revive(feature.name)}>
 | 
			
		||||
                    <Icon name="undo" />
 | 
			
		||||
                </ListItemAction>
 | 
			
		||||
@ -77,6 +78,7 @@ Feature.propTypes = {
 | 
			
		||||
    metricsLastHour: PropTypes.object,
 | 
			
		||||
    metricsLastMinute: PropTypes.object,
 | 
			
		||||
    revive: PropTypes.func,
 | 
			
		||||
    updateable: PropTypes.bool,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Feature;
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@ import { Link } from 'react-router-dom';
 | 
			
		||||
import { Icon, FABButton, Textfield, Menu, MenuItem, Card, CardActions, List } from 'react-mdl';
 | 
			
		||||
import { MenuItemWithIcon, DropdownButton, styles as commonStyles } from '../common';
 | 
			
		||||
import styles from './feature.scss';
 | 
			
		||||
import { CREATE_FEATURE } from '../../permissions';
 | 
			
		||||
import PermissionComponent from '../common/permission-container';
 | 
			
		||||
 | 
			
		||||
export default class FeatureListComponent extends React.Component {
 | 
			
		||||
    static propTypes = {
 | 
			
		||||
@ -62,11 +64,16 @@ export default class FeatureListComponent extends React.Component {
 | 
			
		||||
                        label="Search"
 | 
			
		||||
                        style={{ width: '100%' }}
 | 
			
		||||
                    />
 | 
			
		||||
                    <PermissionComponent
 | 
			
		||||
                        permission={CREATE_FEATURE}
 | 
			
		||||
                        component={
 | 
			
		||||
                            <Link to="/features/create" className={styles.toolbarButton}>
 | 
			
		||||
                                <FABButton accent title="Create feature toggle">
 | 
			
		||||
                                    <Icon name="add" />
 | 
			
		||||
                                </FABButton>
 | 
			
		||||
                            </Link>
 | 
			
		||||
                        }
 | 
			
		||||
                    />
 | 
			
		||||
                </div>
 | 
			
		||||
                <Card shadow={0} className={commonStyles.fullwidth} style={{ overflow: 'visible' }}>
 | 
			
		||||
                    <CardActions>
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,8 @@ import MetricComponent from './metric-container';
 | 
			
		||||
import EditFeatureToggle from './form/form-update-feature-container';
 | 
			
		||||
import ViewFeatureToggle from './form/form-view-feature-container';
 | 
			
		||||
import { styles as commonStyles } from '../common';
 | 
			
		||||
import { CREATE_FEATURE, DELETE_FEATURE, UPDATE_FEATURE } from '../../permissions';
 | 
			
		||||
import PermissionComponent from '../common/permission-container';
 | 
			
		||||
 | 
			
		||||
const TABS = {
 | 
			
		||||
    strategies: 0,
 | 
			
		||||
@ -54,7 +56,17 @@ export default class ViewFeatureToggleComponent extends React.Component {
 | 
			
		||||
        } else if (TABS[activeTab] === TABS.strategies) {
 | 
			
		||||
            if (this.isFeatureView) {
 | 
			
		||||
                return (
 | 
			
		||||
                    <EditFeatureToggle featureToggle={featureToggle} features={features} history={this.props.history} />
 | 
			
		||||
                    <PermissionComponent
 | 
			
		||||
                        permission={UPDATE_FEATURE}
 | 
			
		||||
                        component={
 | 
			
		||||
                            <EditFeatureToggle
 | 
			
		||||
                                featureToggle={featureToggle}
 | 
			
		||||
                                features={features}
 | 
			
		||||
                                history={this.props.history}
 | 
			
		||||
                            />
 | 
			
		||||
                        }
 | 
			
		||||
                        otherwise={<ViewFeatureToggle featureToggle={featureToggle} />}
 | 
			
		||||
                    />
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            return <ViewFeatureToggle featureToggle={featureToggle} />;
 | 
			
		||||
@ -87,6 +99,9 @@ export default class ViewFeatureToggleComponent extends React.Component {
 | 
			
		||||
            return (
 | 
			
		||||
                <span>
 | 
			
		||||
                    Could not find the toggle{' '}
 | 
			
		||||
                    <PermissionComponent
 | 
			
		||||
                        permission={CREATE_FEATURE}
 | 
			
		||||
                        component={
 | 
			
		||||
                            <Link
 | 
			
		||||
                                to={{
 | 
			
		||||
                                    pathname: '/features/create',
 | 
			
		||||
@ -95,6 +110,9 @@ export default class ViewFeatureToggleComponent extends React.Component {
 | 
			
		||||
                            >
 | 
			
		||||
                                {featureToggleName}
 | 
			
		||||
                            </Link>
 | 
			
		||||
                        }
 | 
			
		||||
                        otherwise={featureToggleName}
 | 
			
		||||
                    />
 | 
			
		||||
                </span>
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
@ -115,8 +133,8 @@ export default class ViewFeatureToggleComponent extends React.Component {
 | 
			
		||||
            revive(featureToggle.name);
 | 
			
		||||
            this.props.history.push('/features');
 | 
			
		||||
        };
 | 
			
		||||
        const updateFeatureToggle = () => {
 | 
			
		||||
            let feature = { ...featureToggle };
 | 
			
		||||
        const updateFeatureToggle = e => {
 | 
			
		||||
            let feature = { ...featureToggle, description: e.target.value };
 | 
			
		||||
            if (Array.isArray(feature.strategies)) {
 | 
			
		||||
                feature.strategies.forEach(s => {
 | 
			
		||||
                    delete s.id;
 | 
			
		||||
@ -135,15 +153,22 @@ export default class ViewFeatureToggleComponent extends React.Component {
 | 
			
		||||
                <CardTitle style={{ paddingTop: '24px', wordBreak: 'break-all' }}>{featureToggle.name}</CardTitle>
 | 
			
		||||
                <CardText>
 | 
			
		||||
                    {this.isFeatureView ? (
 | 
			
		||||
                        <Textfield
 | 
			
		||||
                        <PermissionComponent
 | 
			
		||||
                            permission={UPDATE_FEATURE}
 | 
			
		||||
                            component={Textfield}
 | 
			
		||||
                            granted={{
 | 
			
		||||
                                onChange: v => setValue('description', v),
 | 
			
		||||
                                onBlur: updateFeatureToggle,
 | 
			
		||||
                            }}
 | 
			
		||||
                            denied={{
 | 
			
		||||
                                disabled: true,
 | 
			
		||||
                            }}
 | 
			
		||||
                            floatingLabel
 | 
			
		||||
                            style={{ width: '100%' }}
 | 
			
		||||
                            rows={1}
 | 
			
		||||
                            label="Description"
 | 
			
		||||
                            required
 | 
			
		||||
                            value={featureToggle.description}
 | 
			
		||||
                            onChange={v => setValue('description', v)}
 | 
			
		||||
                            onBlur={updateFeatureToggle}
 | 
			
		||||
                        />
 | 
			
		||||
                    ) : (
 | 
			
		||||
                        <Textfield
 | 
			
		||||
@ -167,24 +192,41 @@ export default class ViewFeatureToggleComponent extends React.Component {
 | 
			
		||||
                    }}
 | 
			
		||||
                >
 | 
			
		||||
                    <span style={{ paddingRight: '24px' }}>
 | 
			
		||||
                        <Switch
 | 
			
		||||
                            disabled={!this.isFeatureView}
 | 
			
		||||
                        <PermissionComponent
 | 
			
		||||
                            permission={UPDATE_FEATURE}
 | 
			
		||||
                            component={Switch}
 | 
			
		||||
                            granted={{
 | 
			
		||||
                                disabled: !this.isFeatureView,
 | 
			
		||||
                            }}
 | 
			
		||||
                            denied={{
 | 
			
		||||
                                disabled: true,
 | 
			
		||||
                            }}
 | 
			
		||||
                            ripple
 | 
			
		||||
                            checked={featureToggle.enabled}
 | 
			
		||||
                            onChange={() => toggleFeature(featureToggle.name)}
 | 
			
		||||
                        >
 | 
			
		||||
                            {featureToggle.enabled ? 'Enabled' : 'Disabled'}
 | 
			
		||||
                        </Switch>
 | 
			
		||||
                        </PermissionComponent>
 | 
			
		||||
                    </span>
 | 
			
		||||
 | 
			
		||||
                    {this.isFeatureView ? (
 | 
			
		||||
                        <PermissionComponent
 | 
			
		||||
                            permission={DELETE_FEATURE}
 | 
			
		||||
                            component={
 | 
			
		||||
                                <Button onClick={removeToggle} style={{ flexShrink: 0 }}>
 | 
			
		||||
                                    Archive
 | 
			
		||||
                                </Button>
 | 
			
		||||
                            }
 | 
			
		||||
                        />
 | 
			
		||||
                    ) : (
 | 
			
		||||
                        <PermissionComponent
 | 
			
		||||
                            permission={UPDATE_FEATURE}
 | 
			
		||||
                            component={
 | 
			
		||||
                                <Button onClick={reviveToggle} style={{ flexShrink: 0 }}>
 | 
			
		||||
                                    Revive
 | 
			
		||||
                                </Button>
 | 
			
		||||
                            }
 | 
			
		||||
                        />
 | 
			
		||||
                    )}
 | 
			
		||||
                </CardActions>
 | 
			
		||||
                <hr />
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,8 @@ import { Link } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import { List, ListItem, ListItemContent, IconButton, Grid, Cell } from 'react-mdl';
 | 
			
		||||
import { HeaderTitle } from '../common';
 | 
			
		||||
import { CREATE_STRATEGY, DELETE_STRATEGY } from '../../permissions';
 | 
			
		||||
import PermissionComponent from '../common/permission-container';
 | 
			
		||||
 | 
			
		||||
class StrategiesListComponent extends Component {
 | 
			
		||||
    static propTypes = {
 | 
			
		||||
@ -26,6 +28,9 @@ class StrategiesListComponent extends Component {
 | 
			
		||||
                    <HeaderTitle
 | 
			
		||||
                        title="Strategies"
 | 
			
		||||
                        actions={
 | 
			
		||||
                            <PermissionComponent
 | 
			
		||||
                                permission={CREATE_STRATEGY}
 | 
			
		||||
                                component={
 | 
			
		||||
                                    <IconButton
 | 
			
		||||
                                        raised
 | 
			
		||||
                                        name="add"
 | 
			
		||||
@ -34,6 +39,8 @@ class StrategiesListComponent extends Component {
 | 
			
		||||
                                    />
 | 
			
		||||
                                }
 | 
			
		||||
                            />
 | 
			
		||||
                        }
 | 
			
		||||
                    />
 | 
			
		||||
                    <List>
 | 
			
		||||
                        {strategies.length > 0 ? (
 | 
			
		||||
                            strategies.map((strategy, i) => (
 | 
			
		||||
@ -46,7 +53,12 @@ class StrategiesListComponent extends Component {
 | 
			
		||||
                                    {strategy.editable === false ? (
 | 
			
		||||
                                        ''
 | 
			
		||||
                                    ) : (
 | 
			
		||||
                                        <PermissionComponent
 | 
			
		||||
                                            permission={DELETE_STRATEGY}
 | 
			
		||||
                                            component={
 | 
			
		||||
                                                <IconButton name="delete" onClick={() => removeStrategy(strategy)} />
 | 
			
		||||
                                            }
 | 
			
		||||
                                        />
 | 
			
		||||
                                    )}
 | 
			
		||||
                                </ListItem>
 | 
			
		||||
                            ))
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,8 @@ import { Tabs, Tab, ProgressBar, Grid, Cell } from 'react-mdl';
 | 
			
		||||
import ShowStrategy from './show-strategy-component';
 | 
			
		||||
import EditStrategy from './edit-container';
 | 
			
		||||
import { HeaderTitle } from '../common';
 | 
			
		||||
import { UPDATE_STRATEGY } from '../../permissions';
 | 
			
		||||
import PermissionComponent from '../common/permission-container';
 | 
			
		||||
 | 
			
		||||
const TABS = {
 | 
			
		||||
    view: 0,
 | 
			
		||||
@ -69,10 +71,15 @@ export default class StrategyDetails extends Component {
 | 
			
		||||
                    {strategy.editable === false ? (
 | 
			
		||||
                        ''
 | 
			
		||||
                    ) : (
 | 
			
		||||
                        <PermissionComponent
 | 
			
		||||
                            permission={UPDATE_STRATEGY}
 | 
			
		||||
                            component={
 | 
			
		||||
                                <Tabs activeTab={activeTabId} ripple>
 | 
			
		||||
                                    <Tab onClick={() => this.goToTab('view')}>Details</Tab>
 | 
			
		||||
                                    <Tab onClick={() => this.goToTab('edit')}>Edit</Tab>
 | 
			
		||||
                                </Tabs>
 | 
			
		||||
                            }
 | 
			
		||||
                        />
 | 
			
		||||
                    )}
 | 
			
		||||
 | 
			
		||||
                    <section>
 | 
			
		||||
 | 
			
		||||
@ -23,12 +23,25 @@ export class AuthenticationError extends Error {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ForbiddenError extends Error {
 | 
			
		||||
    constructor(statusCode, body) {
 | 
			
		||||
        super('You cannot perform this action');
 | 
			
		||||
        this.name = 'ForbiddenError';
 | 
			
		||||
        this.statusCode = statusCode;
 | 
			
		||||
        this.body = body;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function throwIfNotSuccess(response) {
 | 
			
		||||
    if (!response.ok) {
 | 
			
		||||
        if (response.status === 401) {
 | 
			
		||||
            return new Promise((resolve, reject) => {
 | 
			
		||||
                response.json().then(body => reject(new AuthenticationError(response.status, body)));
 | 
			
		||||
            });
 | 
			
		||||
        } else if (response.status === 403) {
 | 
			
		||||
            return new Promise((resolve, reject) => {
 | 
			
		||||
                response.json().then(body => reject(new ForbiddenError(response.status, body)));
 | 
			
		||||
            });
 | 
			
		||||
        } else if (response.status > 399 && response.status < 404) {
 | 
			
		||||
            return new Promise((resolve, reject) => {
 | 
			
		||||
                response.json().then(body => {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								frontend/src/permissions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								frontend/src/permissions.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
export const ADMIN = 'ADMIN';
 | 
			
		||||
export const CREATE_FEATURE = 'CREATE_FEATURE';
 | 
			
		||||
export const UPDATE_FEATURE = 'UPDATE_FEATURE';
 | 
			
		||||
export const DELETE_FEATURE = 'DELETE_FEATURE';
 | 
			
		||||
export const CREATE_STRATEGY = 'CREATE_STRATEGY';
 | 
			
		||||
export const UPDATE_STRATEGY = 'UPDATE_STRATEGY';
 | 
			
		||||
export const DELETE_STRATEGY = 'DELETE_STRATEGY';
 | 
			
		||||
export const UPDATE_APPLICATION = 'UPDATE_APPLICATION';
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user