Adds ban/unban to cli. Fix ban user in the admin.

This commit is contained in:
gaba
2016-12-07 14:55:49 -10:00
parent 3463e09cab
commit 0e2a7decd4
10 changed files with 138 additions and 62 deletions
+44
View File
@@ -286,6 +286,40 @@ function removeRole(userID, role) {
});
}
/**
* Ban a user
* @param {String} userID id of the user to ban
*/
function ban(userID) {
User
.setStatus(userID, 'banned', '')
.then(() => {
console.log(`Banned the User ${userID}.`);
util.shutdown();
})
.catch((err) => {
console.error(err);
util.shutdown(1);
});
}
/**
* Unban a user
* @param {String} userUD id of the user to remove the role from
*/
function unban(userID) {
User
.setStatus(userID, 'active', '')
.then(() => {
console.log(`Unban the User ${userID}.`);
util.shutdown();
})
.catch((err) => {
console.error(err);
util.shutdown(1);
});
}
/**
* Disable a given user.
* @param {String} userID the ID of a user to disable
@@ -373,6 +407,16 @@ program
.description('removes a role from a given user')
.action(removeRole);
program
.command('ban <userID>')
.description('ban a given user')
.action(ban);
program
.command('uban <userID>')
.description('unban a given user')
.action(unban);
program
.command('disable <userID>')
.description('disable a given user from logging in')
+16 -6
View File
@@ -1,5 +1,3 @@
import actions from '../constants/users';
/**
* Action disptacher related to comments
*/
@@ -19,9 +17,21 @@ export const createComment = (name, body) => dispatch => {
};
// Dialog Actions
export const showBanUserDialog = () => (dispatch) => {
dispatch({type: actions.SHOW_BANUSER_DIALOG});
export const showBanUserDialog = (userId, userName, commentId) => {
return dispatch => {
dispatch({type: 'SHOW_BANUSER_DIALOG', userId, userName, commentId});
};
};
export const hideBanUserDialog = () => (dispatch) => {
dispatch({type: actions.HIDE_BANUSER_DIALOG});
export const hideBanUserDialog = (showDialog) => {
return dispatch => {
dispatch({type: 'HIDE_BANUSER_DIALOG', showDialog});
};
};
export const banUser = (status, userId, commentId) => {
return dispatch => {
dispatch({type: 'USER_BAN', status, userId, commentId});
dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH'});
};
};
@@ -9,9 +9,14 @@ import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
const lang = new I18n(translations);
const BanUserDialog = ({open, handleClose, authorName}) => (
<Dialog className={styles.dialog} open={open} title={lang.t('bandialog.ban_user')} onClose={handleClose} onCancel={handleClose}>
<span className={styles.close} onClick={handleClose}>×</span>
const BanUserDialog = ({open, handleClose, onClickBanUser, user}) => {
const userName = (typeof user === 'undefined') ? '' : user['userName'];
const userId = (typeof user === 'undefined') ? '' : user['userId'];
const commentId = (typeof user === 'undefined') ? '' : user['commentId'];
return (
<Dialog className={styles.dialog} open={open} onClose={() => handleClose()} onCancel={() => handleClose()} title={lang.t('bandialog.ban_user')}>
<span className={styles.close} onClick={() => handleClose()}>×</span>
<div>
<div className={styles.header}>
<h3>
@@ -20,21 +25,23 @@ const BanUserDialog = ({open, handleClose, authorName}) => (
</div>
<div className={styles.separator}>
<h4>
{lang.t('bandialog.are_you_sure', authorName)}
{lang.t('bandialog.are_you_sure', userName)}
</h4>
<i>
{lang.t('bandialog.note')}
</i>
</div>
<div className={styles.buttons}>
<Button cStyle="cancel" full>
<Button cStyle="cancel" onClick={() => handleClose()} full>
{lang.t('bandialog.cancel')}
</Button>
<Button cStyle="black" full>
<Button cStyle="black" onClick={() => onClickBanUser(userId, commentId)} full>
{lang.t('bandialog.yes_ban_user')}
</Button>
</div>
</div>
</Dialog>
);
);
};
export default BanUserDialog;
+11 -22
View File
@@ -9,9 +9,6 @@ import translations from '../translations.json';
import {Icon} from 'react-mdl';
import {FabButton, Button} from 'coral-ui';
import BanUserDialog from './BanUserDialog';
import {showBanUserDialog, hideBanUserDialog} from '../actions/comments';
const linkify = new Linkify();
@@ -53,35 +50,27 @@ export default props => {
);
};
//return props.author.get('status') === 'banned' ? 'disabled' : 'raised';
// Get the button of the action performed over a comment if any
const getActionButton = (action, i, props) => {
const status = props.comment.get('status');
const flagged = props.comment.get('flagged');
const banned = (props.author.get('status') === 'banned');
if (action === 'flag' && (status || flagged === true)) {
return null;
}
if (action === 'ban') {
return (
// <Button
// {...props.author.get('status') === 'banned' ? 'disabled' : 'raised'}
// key={i}
// onClick={() => props.onClickAction(props.actionsMap[action].status, props.comment.get('id'), props.author.get('id'))}>{lang.t('comment.ban_user')}</Button>
<div key={i}>
<Button {...props.author.get('status') === 'banned' ? 'disabled' : 'raised'}
cStyle="black"
onClick={showBanUserDialog()}
key={i}
{...props} >
{lang.t('comment.ban_user')}
</Button>
<BanUserDialog
open={props.showBanUserDialog}
handleClose={hideBanUserDialog()}
authorName={props.author.get('displayName')}
/>
</div>
);
<Button
disabled={banned ? 'disabled' : ''}
cStyle='black'
onClick={() => props.onClickShowBanDialog(props.author.get('id'), props.author.get('displayName'), props.comment.get('id'))}
key={i} >
{lang.t('comment.ban_user')}
</Button>
);
}
return (
<FabButton icon={props.actionsMap[action].icon} className={styles.actionButton}
@@ -20,6 +20,7 @@ export default class CommentList extends React.Component {
this.state = {active: null};
this.onClickAction = this.onClickAction.bind(this);
this.onClickShowBanDialog = this.onClickShowBanDialog.bind(this);
}
// remove key handlers before leaving
@@ -113,6 +114,10 @@ export default class CommentList extends React.Component {
this.props.onClickAction(action, id, author_id);
}
onClickShowBanDialog(userId, userName, commentId) {
this.props.onClickShowBanDialog(userId, userName, commentId);
}
render () {
const {singleView, commentIds, comments, users, hideActive, key} = this.props;
const {active} = this.state;
@@ -127,6 +132,7 @@ export default class CommentList extends React.Component {
key={index}
index={index}
onClickAction={this.onClickAction}
onClickShowBanDialog={this.onClickShowBanDialog}
actions={this.props.actions}
actionsMap={actions}
isActive={commentId === active}
@@ -1,2 +1,3 @@
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
export const HIDE_BANUSER_DIALOG = 'HIDE_BANUSER_DIALOG';
export const USER_BAN_SUCESS = 'USER_BAN_SUCESS';
@@ -4,9 +4,9 @@ import key from 'keymaster';
import ModerationKeysModal from 'components/ModerationKeysModal';
import CommentList from 'components/CommentList';
import BanUserDialog from 'components/BanUserDialog';
import {updateStatus} from 'actions/comments';
import {banUser} from 'actions/users';
import {updateStatus, showBanUserDialog, hideBanUserDialog, banUser} from 'actions/comments';
import styles from './ModerationQueue.css';
import I18n from 'coral-framework/modules/i18n/i18n';
@@ -52,18 +52,23 @@ class ModerationQueue extends React.Component {
}
// Dispatch the update status action
onCommentAction (action, id, author_id) {
// if we are banning a user by the action then dispatch banUser
// action = 'banned' in the case of banning
if (action === 'banned') {
this.props.dispatch(banUser(action, id, author_id));
this.props.dispatch(updateStatus('rejected', id));
}
onCommentAction (action, id) {
// If not banning then change the status to approved or flagged as action = status
this.props.dispatch(updateStatus(action, id));
}
showBanUserDialog (userId, userName, commentId) {
this.props.dispatch(showBanUserDialog(userId, userName, commentId));
}
hideBanUserDialog () {
this.props.dispatch(hideBanUserDialog(false));
}
banUser (userId, commentId) {
this.props.dispatch(banUser('banned', userId, commentId));
}
onTabClick (activeTab) {
this.setState({activeTab});
}
@@ -96,10 +101,16 @@ class ModerationQueue extends React.Component {
}
comments={comments.get('byId')}
users={users.get('byId')}
onClickAction={(action, id, author_id) => this.onCommentAction(action, id, author_id)}
onClickAction={(action, commentId) => this.onCommentAction(action, commentId)}
onClickShowBanDialog={(userId, userName, commentId) => this.showBanUserDialog(userId, userName, commentId)}
actions={['reject', 'approve', 'ban']}
loading={comments.loading} />
</div>
<BanUserDialog
open={comments.get('showBanUserDialog')}
handleClose={() => this.hideBanUserDialog()}
onClickBanUser={(userId, commentId) => this.banUser(userId, commentId)}
user={comments.get('banUser')}/>
</div>
<div className={`mdl-tabs__panel ${styles.listContainer}`} id='rejected'>
<CommentList
isActive={activeTab === 'rejected'}
+18 -9
View File
@@ -1,5 +1,4 @@
import * as actions from '../constants/users';
import * as actions from '../constants/comments';
import {Map, List, fromJS} from 'immutable';
/**
@@ -13,7 +12,12 @@ const initialState = Map({
byId: Map(),
ids: List(),
loading: false,
showBanUserDialog: false
showBanUserDialog: false,
banUser: {
'userName': '',
'userId': '',
'commentId': ''
}
});
// Handle the comment actions
@@ -26,16 +30,21 @@ export default (state = initialState, action) => {
case 'COMMENT_FLAG': return flag(state, action);
case 'COMMENT_CREATE_SUCCESS': return addComment(state, action);
case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state);
case actions.SHOW_BANUSER_DIALOG:
return state
.set('showBanUserDialog', true);
case actions.HIDE_BANUSER_DIALOG:
return state
.set('showBanUserDialog', false);
case actions.SHOW_BANUSER_DIALOG: return setBanUser(state, true, action);
case actions.HIDE_BANUSER_DIALOG: return setBanUser(state, false, action);
case actions.USER_BAN_SUCESS: return setBanUser(state, false, action);
default: return state;
}
};
// hide or show the UI for the dialog confirming the ban
// set the user that is going to set and the comment that is the reason
const setBanUser = (state, showBanUser, action) => {
const banUser = {'userName': action.userName, 'userId': action.userId, 'commentId': action.commentId};
return state.set('showBanUserDialog', showBanUser)
.set('banUser', banUser);
};
// Update a comment status
const updateStatus = (state, action) => {
const byId = state.get('byId');
-1
View File
@@ -3,7 +3,6 @@ import {Map, List, fromJS} from 'immutable';
const initialState = Map({
byId: Map(),
ids: List(),
showBanUserDialog: false
});
export default (state = initialState, action) => {
@@ -21,8 +21,8 @@ export default store => next => action => {
case 'COMMENT_CREATE':
createComment(store, action.name, action.body);
break;
case 'USER_STATUS_UPDATE':
userStatusUpdate(store, action.author_id, action.status);
case 'USER_BAN':
userStatusUpdate(store, action.status, action.userId, action.commentId);
break;
}
@@ -86,8 +86,8 @@ const createComment = (store, name, comment) => {
};
// Ban a user
const userStatusUpdate = (store, author_id, status) => {
coralApi(`/user/${author_id}/status`, {method: 'POST', body: {status: status, comment_id: ''}})
.then(res => store.dispatch({type: 'USER_BAN_SUCESSS', res}))
const userStatusUpdate = (store, status, userId, commentId) => {
return coralApi(`/user/${userId}/status`, {method: 'POST', body: {status: status, comment_id: commentId}})
.then(res => store.dispatch({type: 'USER_BAN_SUCESS', res}))
.catch(error => store.dispatch({type: 'USER_BAN_FAILED', error}));
};