From e32ab99edf17a85a41c7e1bc7e4f2cfabb3b83d6 Mon Sep 17 00:00:00 2001 From: riley Date: Fri, 12 May 2017 09:57:07 -0600 Subject: [PATCH] remove hasRoles --- .../src/containers/LayoutContainer.js | 2 +- graph/loaders/comments.js | 6 +- graph/mutators/comment.js | 2 +- graph/resolvers/comment.js | 7 +- graph/resolvers/root_query.js | 12 +-- graph/resolvers/user.js | 6 +- models/user.js | 78 ++++++++++++++++--- test/server/graph/mutations/addCommentTag.js | 1 + 8 files changed, 87 insertions(+), 27 deletions(-) diff --git a/client/coral-admin/src/containers/LayoutContainer.js b/client/coral-admin/src/containers/LayoutContainer.js index fea730c98..8a3e0b0d2 100644 --- a/client/coral-admin/src/containers/LayoutContainer.js +++ b/client/coral-admin/src/containers/LayoutContainer.js @@ -27,7 +27,7 @@ class LayoutContainer extends Component { const {handleLogout, toggleShortcutModal, TALK_RECAPTCHA_PUBLIC} = this.props; if (loadingUser) { return ; } - if (roleUtils.canAccessAdmin(user)) { + if (!loggedIn) { return { */ const genComments = ({user}, ids) => { let comments; - if (user && user.hasRoles('ADMIN')) { + if (user && user.canViewOthersComments()) { comments = CommentModel.find({ id: { $in: ids diff --git a/graph/mutators/comment.js b/graph/mutators/comment.js index e2f2d3bac..9557c1dcf 100644 --- a/graph/mutators/comment.js +++ b/graph/mutators/comment.js @@ -22,7 +22,7 @@ const createComment = ({user, loaders: {Comments}, pubsub}, {body, asset_id, par tags = tags.map(tag => ({name: tag})); // If admin or moderator, adding STAFF tag - if (user.hasRoles('ADMIN') || user.hasRoles('MODERATOR')) { + if (user.isStaff()) { tags.push({name: 'STAFF'}); } diff --git a/graph/resolvers/comment.js b/graph/resolvers/comment.js index 19ea11efe..fb01a1585 100644 --- a/graph/resolvers/comment.js +++ b/graph/resolvers/comment.js @@ -23,14 +23,13 @@ const Comment = { }, replyCount({id}, {excludeIgnored}, {user, loaders: {Comments}}) { if (user && excludeIgnored) { - return Comments.countByParentIDPersonalized({id, excludeIgnored}); + return Comments.countByParentIDPersonalized({id, excludeIgnored}); } - return Comments.countByParentID.load(id); + return Comments.countByParentID.load(id); }, actions({id}, _, {user, loaders: {Actions}}) { - // Only return the actions if the user is not an admin. - if (user && user.hasRoles('ADMIN')) { + if (user && user.canViewActions()) { return Actions.getByID.load(id); } diff --git a/graph/resolvers/root_query.js b/graph/resolvers/root_query.js index 4dcb7ea11..9deaba5f6 100644 --- a/graph/resolvers/root_query.js +++ b/graph/resolvers/root_query.js @@ -1,6 +1,6 @@ const RootQuery = { assets(_, args, {loaders: {Assets}, user}) { - if (user == null || !user.hasRoles('ADMIN')) { + if (user == null || !user.canQueryAssets()) { return null; } @@ -22,7 +22,7 @@ const RootQuery = { comments(_, {query: {action_type, statuses, asset_id, parent_id, limit, cursor, sort, excludeIgnored}}, {user, loaders: {Comments, Actions}}) { let query = {statuses, asset_id, parent_id, limit, cursor, sort, excludeIgnored}; - if (user != null && user.hasRoles('ADMIN') && action_type) { + if (user != null && user.canViewOthersComments() && action_type) { return Actions.getByTypes({action_type, item_type: 'COMMENTS'}) .then((ids) => { @@ -37,7 +37,7 @@ const RootQuery = { return Comments.get.load(id); }, commentCount(_, {query: {action_type, statuses, asset_id, parent_id}}, {user, loaders: {Actions, Comments}}) { - if (user == null || !user.hasRoles('ADMIN')) { + if (user == null || !user.canViewOthersComments()) { return null; } @@ -54,7 +54,7 @@ const RootQuery = { }, assetMetrics(_, {from, to, sort, limit = 10}, {user, loaders: {Metrics: {Assets}}}) { - if (user == null || !user.hasRoles('ADMIN')) { + if (user == null || !user.canQueryAssets()) { return null; } @@ -66,7 +66,7 @@ const RootQuery = { }, commentMetrics(_, {from, to, sort, limit = 10}, {user, loaders: {Metrics: {Comments}}}) { - if (user == null || !user.hasRoles('ADMIN')) { + if (user == null || !user.canViewCommentMetrics()) { return null; } @@ -100,7 +100,7 @@ const RootQuery = { // so hide it in the event that we aren't an admin. users(_, {query: {action_type, limit, cursor, sort}}, {user, loaders: {Users, Actions}}) { - if (user == null || !user.hasRoles('ADMIN')) { + if (user == null || !user.canViewOtherUsers()) { return null; } diff --git a/graph/resolvers/user.js b/graph/resolvers/user.js index d8ed7ee15..03e1b121a 100644 --- a/graph/resolvers/user.js +++ b/graph/resolvers/user.js @@ -5,7 +5,7 @@ const User = { actions({id}, _, {user, loaders: {Actions}}) { // Only return the actions if the user is not an admin. - if (user && user.hasRoles('ADMIN')) { + if (user && user.canViewActions()) { return Actions.getByID.load(id); } @@ -14,7 +14,7 @@ const User = { // If the user is not an admin, only return comment list for the owner of // the comments. - if (user && (user.hasRoles('ADMIN') || user.id === id)) { + if (user && (user.canViewOthersComments() || user.id === id)) { return Comments.getByQuery({author_id: id, sort: 'REVERSE_CHRONOLOGICAL'}); } @@ -23,7 +23,7 @@ const User = { roles({id, roles}, _, {user}) { // If the user is not an admin, only return the current user's roles. - if (user && (user.hasRoles('ADMIN') || user.id === id)) { + if (user && (user.canChangeRoles() || user.id === id)) { return roles; } diff --git a/models/user.js b/models/user.js index ec215b3fa..179e6f7a5 100644 --- a/models/user.js +++ b/models/user.js @@ -1,6 +1,7 @@ const mongoose = require('../services/mongoose'); const bcrypt = require('bcrypt'); const uuid = require('uuid'); +const intersection = require('lodash/intersection'); // USER_ROLES is the array of roles that is permissible as a user role. const USER_ROLES = [ @@ -158,14 +159,74 @@ UserSchema.index({ }); /** - * Returns true if the user has all the roles specified. + * returns true if the user can look up assets through the api */ -UserSchema.method('hasRoles', function(...roles) { - return roles.every((role) => { +UserSchema.method('canQueryAssets', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); - // TODO: remove toUpperCase() once we've migrated usage. - return this.roles.indexOf(role.toUpperCase()) >= 0; - }); +/** + * returns true if the user can view actions + */ +UserSchema.method('canViewActions', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +/** + * returns true if the user can view non-null or non-ACCEPTED comments + */ +UserSchema.method('canViewNonNullOrAcceptedComments', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +/** + * returns true when a user can view comments that are not their own + */ +UserSchema.method('canViewOthersComments', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +/** + * returns true when a user can view comment metrics + */ +UserSchema.method('canViewCommentMetrics', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +/** + * returns true if a commenter is staff + */ +UserSchema.method('isStaff', function () { + return !!intersection(['ADMIN', 'MODERATOR', 'STAFF'], this.roles).length; +}); + +/** + * returns true when a user can see other user info + */ +UserSchema.method('canViewOtherUsers', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +/** + * when a user can modify tags + */ +UserSchema.method('canModifyTags', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +/** + * when a user can change roles + */ +UserSchema.method('canChangeUserRoles', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +UserSchema.method('canSetCommentStatus', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; +}); + +UserSchema.method('canSetUserStatus', function () { + return !!intersection(['ADMIN', 'MODERATOR'], this.roles).length; }); /** @@ -216,13 +277,12 @@ UserSchema.method('can', function(...actions) { return false; } - if (actions.some((action) => action === 'mutation:setUserStatus' || action === 'mutation:suspendUser' || action === 'mutation:setCommentStatus') && !this.hasRoles('ADMIN')) { + if (actions.some((action) => action === 'mutation:setUserStatus' || action === 'mutation:suspendUser' || action === 'mutation:setCommentStatus') && !this.canSetUserStatus()) { return false; } // {add,remove}CommentTag - requires admin and/or moderator role - const userCanModifyTags = user => ['ADMIN', 'MODERATOR'].some(r => user.hasRoles(r)); - if (actions.some(a => ['mutation:removeCommentTag', 'mutation:addCommentTag'].includes(a)) && ! userCanModifyTags(this)) { + if (actions.some(a => ['mutation:removeCommentTag', 'mutation:addCommentTag'].includes(a)) && ! this.canModifyTags()) { return false; } diff --git a/test/server/graph/mutations/addCommentTag.js b/test/server/graph/mutations/addCommentTag.js index 018e96631..1386d8339 100644 --- a/test/server/graph/mutations/addCommentTag.js +++ b/test/server/graph/mutations/addCommentTag.js @@ -44,6 +44,7 @@ describe('graph.mutations.addCommentTag', () => { Object.entries({ 'anonymous': undefined, 'regular commenter': new UserModel({}), + 'staff': new UserModel({roles: ['STAFF']}), 'banned moderator': new UserModel({roles: ['MODERATOR'], status: 'BANNED'}) }).forEach(([ userDescription, user ]) => { it(userDescription, async function () {