Commit 699e30de authored by Paul Kaplan's avatar Paul Kaplan

Fix curator permissions for removing projects

parent c3d266f3
const {selectUserId, selectIsAdmin, selectIsSocial, selectIsLoggedIn} = require('./session'); const {selectUserId, selectIsAdmin, selectIsSocial, selectIsLoggedIn, selectUsername} = require('./session');
// Fine-grain selector helpers - not exported, use the higher level selectors below // Fine-grain selector helpers - not exported, use the higher level selectors below
const isCreator = state => selectUserId(state) === state.studio.owner; const isCreator = state => selectUserId(state) === state.studio.owner;
...@@ -36,8 +36,19 @@ const selectCanRemoveManager = (state, managerId) => ...@@ -36,8 +36,19 @@ const selectCanRemoveManager = (state, managerId) =>
(selectIsAdmin(state) || isManager(state)) && managerId !== state.studio.owner; (selectIsAdmin(state) || isManager(state)) && managerId !== state.studio.owner;
const selectCanPromoteCurators = state => isManager(state); const selectCanPromoteCurators = state => isManager(state);
// TODO this permission needs to account for who added the project const selectCanRemoveProject = (state, creatorUsername, actorId) => {
const selectCanRemoveProjects = state => isCurator(state) || isManager(state) || selectIsAdmin(state); // Admins/managers can remove any projects
if (isManager(state) || selectIsAdmin(state)) return true;
// Project owners can always remove their projects
if (selectUsername(state) === creatorUsername) {
return true;
}
// Curators can remove projects they added
if (isCurator(state)) {
return selectUserId(state) === actorId;
}
return false;
};
export { export {
selectCanEditInfo, selectCanEditInfo,
...@@ -55,5 +66,5 @@ export { ...@@ -55,5 +66,5 @@ export {
selectCanRemoveCurators, selectCanRemoveCurators,
selectCanRemoveManager, selectCanRemoveManager,
selectCanPromoteCurators, selectCanPromoteCurators,
selectCanRemoveProjects selectCanRemoveProject
}; };
...@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; ...@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import {selectCanRemoveProjects} from '../../redux/studio-permissions'; import {selectCanRemoveProject} from '../../redux/studio-permissions';
import {removeProject} from './lib/studio-project-actions'; import {removeProject} from './lib/studio-project-actions';
const StudioProjectTile = ({ const StudioProjectTile = ({
...@@ -73,8 +73,8 @@ StudioProjectTile.propTypes = { ...@@ -73,8 +73,8 @@ StudioProjectTile.propTypes = {
avatar: PropTypes.string avatar: PropTypes.string
}; };
const mapStateToProps = state => ({ const mapStateToProps = (state, ownProps) => ({
canRemove: selectCanRemoveProjects(state) canRemove: selectCanRemoveProject(state, ownProps.username, ownProps.addedBy)
}); });
const mapDispatchToProps = ({ const mapDispatchToProps = ({
......
...@@ -36,6 +36,7 @@ const StudioProjects = ({ ...@@ -36,6 +36,7 @@ const StudioProjects = ({
image={item.image} image={item.image}
avatar={item.avatar['90x90']} avatar={item.avatar['90x90']}
username={item.username} username={item.username}
addedBy={item.actor_id}
/>) />)
)} )}
<div className="studio-projects-load-more"> <div className="studio-projects-load-more">
......
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
"user1Social": { "user1Social": {
"session": { "session": {
"user": { "user": {
"id": 1 "id": 1,
"username": "user1-username"
}, },
"permissions": { "permissions": {
"social": true "social": true
......
...@@ -14,11 +14,11 @@ import { ...@@ -14,11 +14,11 @@ import {
selectCanRemoveCurators, selectCanRemoveCurators,
selectCanRemoveManager, selectCanRemoveManager,
selectCanPromoteCurators, selectCanPromoteCurators,
selectCanRemoveProjects selectCanRemoveProject
} from '../../../src/redux/studio-permissions'; } from '../../../src/redux/studio-permissions';
import {getInitialState as getInitialStudioState} from '../../../src/redux/studio'; import {getInitialState as getInitialStudioState} from '../../../src/redux/studio';
import {getInitialState as getInitialSessionState} from '../../../src/redux/session'; import {getInitialState as getInitialSessionState, selectUserId, selectUsername} from '../../../src/redux/session';
import {sessions, studios} from '../../helpers/state-fixtures.json'; import {sessions, studios} from '../../helpers/state-fixtures.json';
let state; let state;
...@@ -111,19 +111,34 @@ describe('studio projects', () => { ...@@ -111,19 +111,34 @@ describe('studio projects', () => {
describe('can remove projects', () => { describe('can remove projects', () => {
test.each([ test.each([
['admin', true], ['admin', true],
['curator', true], ['curator', false], // false for projects that were not added by them, see below
['manager', true], ['manager', true],
['creator', true], ['creator', true],
['logged in', false], ['logged in', false], // false for projects that are not theirs, see below
['unconfirmed', false], ['unconfirmed', false],
['logged out', false] ['logged out', false]
])('%s: %s', (role, expected) => { ])('%s: %s', (role, expected) => {
setStateByRole(role); setStateByRole(role);
expect(selectCanRemoveProjects(state)).toBe(expected); expect(selectCanRemoveProject(state, 'not-me', 'not-me')).toBe(expected);
});
test('curators can remove projects they added', () => {
setStateByRole('curator');
const addedBy = selectUserId(state);
expect(selectCanRemoveProject(state, 'not-me', addedBy)).toBe(true);
});
test('curators can also remove projects they own that they did not add', () => {
setStateByRole('curator');
const creator = selectUsername(state);
expect(selectCanRemoveProject(state, creator, 'not-me')).toBe(true);
});
test('logged in users can only remove projects they own', () => {
setStateByRole('logged in');
const creator = selectUsername(state);
expect(selectCanRemoveProject(state, creator, 'not-me')).toBe(true);
}); });
// TODO this permission is wrong, curators can only remove projects they added
test.skip('anyone can remove one of their projects', () => {});
test.skip('curators can remove only projects they', () => {});
}); });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment