-
+const render = ({
+ params,
+ searchString,
+ handleAdd,
+ activeScopes,
+ RESTRICT_CREATE_ORGANISATION
+}) => {
+ const activeScopesJs = activeScopes.toJS();
+
+ const canCreateOrg = canCreateOrganisationsFn(activeScopesJs, {
+ RESTRICT_CREATE_ORGANISATION
+ });
+
+ console.log('001 canCreateOrg', canCreateOrg);
-
-
-
model.get('name')}
- buttons={[OrgMemberButton, DeleteButton]}
- ModelForm={SiteOrgItem} />
+ return (
+
+
+
+
+
+ model.get('name')}
+ buttons={[OrgMemberButton, DeleteButton]}
+ ModelForm={SiteOrgItem} />
+
-
-);
+ );
+};
export default enhance(render);
diff --git a/ui/src/containers/SubOrgs/index.js b/ui/src/containers/SubOrgs/index.js
index 1be6af8490..d651193033 100644
--- a/ui/src/containers/SubOrgs/index.js
+++ b/ui/src/containers/SubOrgs/index.js
@@ -5,11 +5,13 @@ import { withProps, compose } from 'recompose';
import { addModel } from 'ui/redux/modules/models';
import { queryStringToQuery, modelQueryStringSelector } from 'ui/redux/modules/search';
import { routeNodeSelector } from 'redux-router5';
-import { loggedInUserId } from 'ui/redux/modules/auth';
+import { loggedInUserId, currentScopesSelector } from 'ui/redux/modules/auth';
import SearchBox from 'ui/containers/SearchBox';
import ModelList from 'ui/containers/ModelList';
import SubOrgForm from 'ui/containers/SubOrgForm';
import { withModels } from 'ui/utils/hocs';
+import canCreateOrganisationsFn from 'lib/services/auth/canCreateOrganisations';
+import { getAppDataSelector } from 'ui/redux/modules/app';
const schema = 'organisation';
const OrgList = compose(
@@ -25,7 +27,7 @@ class SubOrgs extends Component {
userId: PropTypes.string,
organisationId: PropTypes.string,
addModel: PropTypes.func,
- searchString: PropTypes.string,
+ searchString: PropTypes.string
};
onClickAdd = () => {
@@ -40,31 +42,39 @@ class SubOrgs extends Component {
});
}
- render = () => (
-
-
-
-
-
model.get('name')}
- ModelForm={SubOrgForm} />
+ render = () => {
+ const activeScopesJs = this.props.activeScopes.toJS();
+
+ const canCreateOrg = canCreateOrganisationsFn(activeScopesJs, {
+ RESTRICT_CREATE_ORGANISATION: this.props.RESTRICT_CREATE_ORGANISATION
+ });
+
+ return (
+
+
+
+
+ model.get('name')}
+ ModelForm={SubOrgForm} />
+
-
- );
+ );
+ }
}
export default connect((state) => {
@@ -74,5 +84,7 @@ export default connect((state) => {
organisationId: params.organisationId,
userId,
searchString: modelQueryStringSelector(schema)(state),
+ activeScopes: currentScopesSelector(state),
+ RESTRICT_CREATE_ORGANISATION: getAppDataSelector('RESTRICT_CREATE_ORGANISATION')(state)
};
}, { addModel })(SubOrgs);
diff --git a/ui/src/containers/UserOrgForm/index.js b/ui/src/containers/UserOrgForm/index.js
index 68fa41837b..0fe4bf6196 100644
--- a/ui/src/containers/UserOrgForm/index.js
+++ b/ui/src/containers/UserOrgForm/index.js
@@ -8,6 +8,9 @@ import UserForm from 'ui/containers/UserForm';
import { activeOrgIdSelector } from 'ui/redux/modules/router';
import Checkbox from 'ui/components/Material/Checkbox';
import { connect } from 'react-redux';
+import { getAppDataSelector } from 'ui/redux/modules/app';
+import { currentScopesSelector } from 'ui/redux/modules/auth';
+import { SITE_ADMIN, SITE_CAN_CREATE_ORG, SITE_SCOPES } from 'lib/constants/scopes';
const ORG_SETTINGS = 'organisationSettings';
@@ -42,6 +45,42 @@ const RolesList = compose(
)
);
+const SiteRolesList = compose(
+ setPropTypes({
+ selectedRoles: PropTypes.instanceOf(List).isRequired,
+ handleRolesChange: PropTypes.func.isRequired,
+ }),
+ withProps({
+ sort: new Map({
+ title: 1,
+ _id: 1,
+ }),
+ filter: new Map({}),
+ }),
+)(({ selectedRoles, handleRolesChange }) => {
+ const models = new List([
+ new Map({
+ _id: SITE_CAN_CREATE_ORG,
+ title: SITE_SCOPES[SITE_CAN_CREATE_ORG]
+ })
+ ]);
+ return (
+ {
+ models.map((model) => {
+ const modelId = model.get('_id');
+ const isChecked = selectedRoles.includes(modelId);
+ return (
+
+ );
+ }).valueSeq()
+ }
+
);
+});
+
const getDefaultOrgSettings = organisation =>
fromJS({
organisation,
@@ -63,7 +102,9 @@ const enhance = compose(
id: PropTypes.string.isRequired,
}),
connect(state => ({
- organisationId: activeOrgIdSelector(state)
+ organisationId: activeOrgIdSelector(state),
+ activeScopes: currentScopesSelector(state),
+ RESTRICT_CREATE_ORGANISATION: getAppDataSelector('RESTRICT_CREATE_ORGANISATION')(state)
})),
withProps({
schema: 'user',
@@ -108,6 +149,13 @@ const enhance = compose(
);
updateOrgSettings('roles', newRoles.toList());
},
+ handleSiteRolesChange: ({ model, updateModel }) => (role, checked) => {
+ const scopes = model.get('scopes', new List()).toSet();
+ const newScopes = checked ?
+ scopes.add(role) :
+ scopes.delete(role);
+ updateModel({ path: 'scopes', value: newScopes.toList() });
+ },
handleFilterChange: ({ updateOrgSettings }) =>
(filter) => {
updateOrgSettings('filter', filter);
@@ -116,13 +164,25 @@ const enhance = compose(
);
const render = (props) => {
- const { model, organisationId, handleRolesChange, handleFilterChange } = props;
+ const {
+ model,
+ organisationId,
+ handleRolesChange,
+ handleFilterChange,
+ handleSiteRolesChange,
+ RESTRICT_CREATE_ORGANISATION
+ } = props;
const userOrgSettings = getActiveOrgSettings({ model, organisationId });
const roles = userOrgSettings.get('roles', new List());
const rolesId = uuid.v4();
+ const siteRolesId = uuid.v4();
const filterId = uuid.v4();
const filter = fromJS(userOrgSettings.get('filter', new Map({})));
+ const siteRoles = model.get('scopes', new List());
+ const canEditSiteRoles = RESTRICT_CREATE_ORGANISATION &&
+ props.activeScopes.includes(SITE_ADMIN);
+
return (
@@ -136,6 +196,19 @@ const render = (props) => {
+
+
+ {canEditSiteRoles &&
}
+
{
data.state = {
app: {
- SUPERADMIN_EDIT_ORGANISATION_ONLY: boolean(defaultTo(process.env.SUPERADMIN_EDIT_ORGANISATION_ONLY, true))
+ RESTRICT_CREATE_ORGANISATION: boolean(defaultTo(process.env.RESTRICT_CREATE_ORGANISATION, true))
}
};
From 41c80e2fa7b216305363d505896b5556d07f9992 Mon Sep 17 00:00:00 2001
From: Chris Bishop
Date: Fri, 23 Feb 2018 08:31:57 +0000
Subject: [PATCH 5/6] Fixed tests.
---
api/src/routes/tests/scopeFiltering/uploadLogo-test.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/api/src/routes/tests/scopeFiltering/uploadLogo-test.js b/api/src/routes/tests/scopeFiltering/uploadLogo-test.js
index 1033030027..3104259688 100644
--- a/api/src/routes/tests/scopeFiltering/uploadLogo-test.js
+++ b/api/src/routes/tests/scopeFiltering/uploadLogo-test.js
@@ -45,9 +45,9 @@ describe('UploadController.uploadLogo scope filtering', () => {
await assertUnauthorised(token);
});
- it('should not allow action when ALL org scope is used', async () => {
+ it('should allow action when ALL org scope is used', async () => {
const token = await createOrgToken([ALL]);
- await assertUnauthorised(token);
+ await assertAuthorised(token);
});
it('should not allow action when MANAGE_ALL_ORGANISATIONS org scope is used', async () => {
From 9dc25ec562c053096158ad9356c5eee68a1e7bcc Mon Sep 17 00:00:00 2001
From: James Mullaney
Date: Thu, 22 Mar 2018 17:01:38 +0000
Subject: [PATCH 6/6] test: Fix scoping tests for org
---
.../tests/modelFilters/organisation-test.js | 28 +++----------------
1 file changed, 4 insertions(+), 24 deletions(-)
diff --git a/lib/services/auth/tests/modelFilters/organisation-test.js b/lib/services/auth/tests/modelFilters/organisation-test.js
index d8a568ef51..5134d8e169 100644
--- a/lib/services/auth/tests/modelFilters/organisation-test.js
+++ b/lib/services/auth/tests/modelFilters/organisation-test.js
@@ -21,12 +21,6 @@ import {
} from 'lib/services/auth/tests/utils/constants';
import createUser from 'lib/services/auth/tests/utils/createUser';
import createUserToken from 'lib/services/auth/tests/utils/createUserToken';
-import createClient from 'lib/services/auth/tests/utils/createClient';
-import createClientToken from 'lib/services/auth/tests/utils/createClientToken';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-
-chai.use(chaiAsPromised);
const modelName = 'organisation';
@@ -39,7 +33,8 @@ describe('model scope filters organisation', () => {
testAllActions(modelName, [SITE_ADMIN], {});
// org admin tests
- // testOrgScopeFilter(modelName, 'create', [ALL], undefined);
+ testOrgScopeFilter(modelName, 'view', [ALL], TEST_USER_ORGS_FILTER);
+ testOrgScopeFilterError(modelName, 'create', [ALL], undefined);
// @todo: tests do not use roles properly. Assign a role to the org setting on the user
// testOrgScopeFilter(modelName, 'edit', [ALL], TEST_USER_ORGS_FILTER);
@@ -71,23 +66,8 @@ describe('model scope filters organisation', () => {
testClientBasicScopeFilter(modelName, 'view', [ALL], TEST_USER_ORGS_FILTER);
testClientBasicScopeFilter(modelName, 'view', [], TEST_USER_NO_ORGS_FILTER);
- it('should error on All scope', async () => {
- const client = createClient();
- const token = createClientToken([ALL]);
-
- getModelScopeFilter('organisation', 'edit', token, undefined, client)
- .should.eventually.be.rejectedWith(Error);
- });
- // testClientBasicScopeFilter(modelName, 'edit', [ALL], TEST_USER_ORGS_FILTER);
-
- it('should error with no scopes', async () => {
- const client = createClient();
- const token = createClientToken([]);
-
- getModelScopeFilter('organisation', 'edit', token, undefined, client)
- .should.eventually.be.rejectedWith(Error);
- });
- // testClientBasicScopeFilter(modelName, 'edit', [], TEST_USER_NO_ORGS_FILTER);
+ testClientBasicScopeFilter(modelName, 'edit', [ALL], TEST_USER_ORGS_FILTER);
+ testClientBasicScopeFilter(modelName, 'edit', [], TEST_USER_NO_ORGS_FILTER);
testClientBasicScopeFilterError(modelName, 'create', []);
testClientBasicScopeFilterError(modelName, 'create', []);