diff --git a/client/coral-admin/src/actions/auth.js b/client/coral-admin/src/actions/auth.js
index 89b56d4dc..68da3577e 100644
--- a/client/coral-admin/src/actions/auth.js
+++ b/client/coral-admin/src/actions/auth.js
@@ -14,8 +14,7 @@ export const handleLogin = (email, password, recaptchaResponse) => dispatch => {
return dispatch(checkLoginFailure('not logged in'));
}
- const isAdmin = !!user.roles.filter(i => i === 'ADMIN').length;
- dispatch(checkLoginSuccess(user, isAdmin));
+ dispatch(checkLoginSuccess(user));
})
.catch(error => {
@@ -41,7 +40,7 @@ export const requestPasswordReset = email => dispatch => {
// Check Login
const checkLoginRequest = () => ({type: actions.CHECK_LOGIN_REQUEST});
-const checkLoginSuccess = (user, isAdmin) => ({type: actions.CHECK_LOGIN_SUCCESS, user, isAdmin});
+const checkLoginSuccess = (user) => ({type: actions.CHECK_LOGIN_SUCCESS, user});
const checkLoginFailure = error => ({type: actions.CHECK_LOGIN_FAILURE, error});
export const checkLogin = () => dispatch => {
@@ -52,8 +51,7 @@ export const checkLogin = () => dispatch => {
return dispatch(checkLoginFailure('not logged in'));
}
- const isAdmin = !!user.roles.filter(i => i === 'ADMIN').length;
- dispatch(checkLoginSuccess(user, isAdmin));
+ dispatch(checkLoginSuccess(user));
})
.catch(error => {
console.error(error);
diff --git a/client/coral-admin/src/containers/LayoutContainer.js b/client/coral-admin/src/containers/LayoutContainer.js
index 42e2baade..fea730c98 100644
--- a/client/coral-admin/src/containers/LayoutContainer.js
+++ b/client/coral-admin/src/containers/LayoutContainer.js
@@ -6,6 +6,7 @@ import {toggleModal as toggleShortcutModal} from '../actions/moderation';
import {fetchConfig} from '../actions/config';
import {FullLoading} from '../components/FullLoading';
import AdminLogin from '../components/AdminLogin';
+import roleUtils from 'coral-framework/utils/roles';
class LayoutContainer extends Component {
componentWillMount () {
@@ -16,7 +17,7 @@ class LayoutContainer extends Component {
}
render () {
const {
- isAdmin,
+ user,
loggedIn,
loadingUser,
loginError,
@@ -26,7 +27,7 @@ class LayoutContainer extends Component {
const {handleLogout, toggleShortcutModal, TALK_RECAPTCHA_PUBLIC} = this.props;
if (loadingUser) { return ; }
- if (!isAdmin) {
+ if (roleUtils.canAccessAdmin(user)) {
return ;
}
- if (isAdmin && loggedIn) {
+ if (roleUtils.canAccessAdmin(user) && loggedIn) {
return ;
}
return ;
diff --git a/client/coral-admin/src/reducers/auth.js b/client/coral-admin/src/reducers/auth.js
index a7054ddfa..2bd42d112 100644
--- a/client/coral-admin/src/reducers/auth.js
+++ b/client/coral-admin/src/reducers/auth.js
@@ -4,7 +4,6 @@ import * as actions from '../constants/auth';
const initialState = Map({
loggedIn: false,
user: null,
- isAdmin: false,
loginError: null,
loginMaxExceeded: false,
passwordRequestSuccess: null
@@ -24,7 +23,6 @@ export default function auth (state = initialState, action) {
return state
.set('loggedIn', true)
.set('loadingUser', false)
- .set('isAdmin', action.isAdmin)
.set('user', action.user);
case actions.LOGOUT_SUCCESS:
return initialState;
diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js
index 0d26cf740..908fd4a90 100644
--- a/client/coral-embed-stream/src/components/Embed.js
+++ b/client/coral-embed-stream/src/components/Embed.js
@@ -1,6 +1,7 @@
import React from 'react';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from 'coral-framework/translations';
+import rolesHelper from 'coral-framework/utils/roles';
const lang = new I18n(translations);
import {TabBar, Tab, TabContent, Button} from 'coral-ui';
@@ -38,7 +39,7 @@ export default class Embed extends React.Component {
render () {
const {activeTab, logout, viewAllComments, commentId} = this.props;
const {asset: {totalCommentCount}} = this.props.root;
- const {loggedIn, isAdmin, user} = this.props.auth;
+ const {loggedIn, user} = this.props.auth;
const userBox = ;
@@ -48,7 +49,7 @@ export default class Embed extends React.Component {
{lang.t('myProfile')}
- Configure Stream
+ Configure Stream
{
commentId &&
diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js
index 46ac75dca..7efadc921 100644
--- a/client/coral-embed-stream/src/components/Stream.js
+++ b/client/coral-embed-stream/src/components/Stream.js
@@ -11,6 +11,7 @@ import QuestionBox from 'coral-plugin-questionbox/QuestionBox';
import IgnoredCommentTombstone from './IgnoredCommentTombstone';
import SuspendedAccount from 'coral-framework/components/SuspendedAccount';
import RestrictedContent from 'coral-framework/components/RestrictedContent';
+import rolesHelper from 'coral-framework/utils/roles';
import ChangeUsernameContainer
from 'coral-sign-in/containers/ChangeUsernameContainer';
@@ -37,7 +38,7 @@ class Stream extends React.Component {
removeCommentTag,
pluginProps,
ignoreUser,
- auth: {loggedIn, isAdmin, user},
+ auth: {loggedIn, user},
commentCountCache,
editName
} = this.props;
@@ -111,7 +112,7 @@ class Stream extends React.Component {
{loggedIn &&
user &&
}
- {loggedIn && }
+ {loggedIn && }
{/* the highlightedComment is isolated after the user followed a permalink */}
{highlightedComment
diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js
index d689aeb63..527369b60 100644
--- a/client/coral-framework/actions/auth.js
+++ b/client/coral-framework/actions/auth.js
@@ -108,7 +108,7 @@ export const cleanState = () => ({type: actions.CLEAN_STATE});
const signInRequest = () => ({type: actions.FETCH_SIGNIN_REQUEST});
// TODO: revisit login redux flow.
-// const signInSuccess = (user, isAdmin) => ({type: actions.FETCH_SIGNIN_SUCCESS, user, isAdmin});
+// const signInSuccess = (user) => ({type: actions.FETCH_SIGNIN_SUCCESS, user});
//
const signInFailure = error => ({type: actions.FETCH_SIGNIN_FAILURE, error});
@@ -236,7 +236,7 @@ export const invalidForm = error => ({type: actions.INVALID_FORM, error});
// Check Login
const checkLoginRequest = () => ({type: actions.CHECK_LOGIN_REQUEST});
-const checkLoginSuccess = (user, isAdmin) => ({type: actions.CHECK_LOGIN_SUCCESS, user, isAdmin});
+const checkLoginSuccess = (user) => ({type: actions.CHECK_LOGIN_SUCCESS, user});
const checkLoginFailure = error => ({type: actions.CHECK_LOGIN_FAILURE, error});
export const checkLogin = () => dispatch => {
@@ -247,8 +247,7 @@ export const checkLogin = () => dispatch => {
throw new Error('Not logged in');
}
- const isAdmin = !!result.user.roles.filter(i => i === 'ADMIN').length;
- dispatch(checkLoginSuccess(result.user, isAdmin));
+ dispatch(checkLoginSuccess(result.user));
})
.catch(error => {
console.error(error);
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index 83ea49ce5..5ac862431 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -4,7 +4,6 @@ import * as actions from '../constants/auth';
const initialState = Map({
isLoading: false,
loggedIn: false,
- isAdmin: false,
user: null,
showSignInDialog: false,
showCreateUsernameDialog: false,
@@ -79,12 +78,10 @@ export default function auth (state = initialState, action) {
return state
.set('checkedInitialLogin', true)
.set('loggedIn', true)
- .set('isAdmin', action.isAdmin)
.set('user', purge(action.user));
case actions.FETCH_SIGNIN_SUCCESS:
return state
.set('loggedIn', true)
- .set('isAdmin', action.isAdmin)
.set('user', purge(action.user));
case actions.FETCH_SIGNIN_FAILURE:
return state
@@ -120,8 +117,7 @@ export default function auth (state = initialState, action) {
return state
.set('user', null)
.set('isLoading', false)
- .set('loggedIn', false)
- .set('isAdmin', false);
+ .set('loggedIn', false);
case actions.INVALID_FORM:
return state
.set('error', action.error);
diff --git a/client/coral-framework/utils/roles.js b/client/coral-framework/utils/roles.js
new file mode 100644
index 000000000..b457ff1b3
--- /dev/null
+++ b/client/coral-framework/utils/roles.js
@@ -0,0 +1,10 @@
+import includes from 'lodash/includes';
+
+export default {
+ canAccessConfig: (user) => includes(user.roles, 'ADMIN'),
+ canChangeRoles: user => includes(user.roles, 'ADMIN'),
+ hasStaffTag: user => includes(user.roles, 'ADMIN', 'MODERATOR', 'STAFF'),
+ canViewUserEmails: user => includes(user.roles, 'ADMIN'),
+ canModerate: user => includes(user.roles, 'ADMIN', 'MODERATOR'),
+ canAccessAdmin: user => includes(user.roles, 'ADMIN', 'MODERATOR')
+};
diff --git a/services/users.js b/services/users.js
index 14301ccf4..246d3fded 100644
--- a/services/users.js
+++ b/services/users.js
@@ -395,13 +395,10 @@ module.exports = class UsersService {
return Promise.reject(new Error(`role ${role} is not supported`));
}
- return UserModel.update({
- id: id
- }, {
- $addToSet: {
- roles: role
- }
- });
+ // 5.11.2017 - Restricting this to a hierarchical system like WordPress
+ // where you can only set one role at a time.
+ // I'm not changing the data structure here, because I don't want a migration
+ return UserModel.update({id}, {$set: {roles: [role]}});
}
/**