From 3d5bf17349fb139f627bc4916d6f704ad159d5a6 Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Sun, 24 Jan 2016 23:54:49 +0900 Subject: PLT-588 Add a warning when a user demotes themselves from System Admin to another role. --- .../admin_console/demote_own_role_modal.jsx | 91 +++++++++++++++++ web/react/components/admin_console/user_item.jsx | 111 ++++++++++++++++----- 2 files changed, 177 insertions(+), 25 deletions(-) create mode 100644 web/react/components/admin_console/demote_own_role_modal.jsx diff --git a/web/react/components/admin_console/demote_own_role_modal.jsx b/web/react/components/admin_console/demote_own_role_modal.jsx new file mode 100644 index 000000000..63d4dca5c --- /dev/null +++ b/web/react/components/admin_console/demote_own_role_modal.jsx @@ -0,0 +1,91 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import * as AsyncClient from '../../utils/async_client.jsx'; +import * as Client from '../../utils/client.jsx'; +const Modal = ReactBootstrap.Modal; +import * as Utils from '../../utils/utils.jsx'; + +export default class DemoteOwnRoleModal extends React.Component { + constructor(props) { + super(props); + + this.doDemote = this.doDemote.bind(this); + this.doCancel = this.doCancel.bind(this); + + this.state = { + serverError: null + }; + } + + doDemote() { + const data = { + user_id: this.props.user.id, + new_roles: this.props.role + }; + console.log(JSON.stringify(data)); + + Client.updateRoles(data, + () => { + this.setState({serverError: null}); + this.props.onModalSubmit(); + }, + (err) => { + this.setState({serverError: err.message}); + } + ); + } + + doCancel() { + this.setState({serverError: null}); + this.props.onModalDismissed(); + } + + render() { + let serverError = null; + + if (this.state.serverError) { + serverError =
+ } + + return ( + + +

{'Confirm demotion from System Admin role'}

+
+ + If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you'll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command.

./platform -assign_role -team_name="yourteam" -email="name@yourcompany.com" -role="system_admin" + {serverError} +
+ + + + +
+ ); + } +} + +DemoteOwnRoleModal.propTypes = { + user: React.PropTypes.object, + role: React.PropTypes.string, + show: React.PropTypes.bool.isRequired, + onModalSubmit: React.PropTypes.func, + onModalDismissed: React.PropTypes.func +}; diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx index 59b4861e4..9220b2cc3 100644 --- a/web/react/components/admin_console/user_item.jsx +++ b/web/react/components/admin_console/user_item.jsx @@ -3,6 +3,8 @@ import * as Client from '../../utils/client.jsx'; import * as Utils from '../../utils/utils.jsx'; +import UserStore from '../../stores/user_store.jsx'; +import DemoteOwnRoleModal from './demote_own_role_modal.jsx'; import {FormattedMessage} from 'mm-intl'; @@ -16,25 +18,38 @@ export default class UserItem extends React.Component { this.handleMakeAdmin = this.handleMakeAdmin.bind(this); this.handleMakeSystemAdmin = this.handleMakeSystemAdmin.bind(this); this.handleResetPassword = this.handleResetPassword.bind(this); + this.doDemote = this.doDemote.bind(this); + this.doDemoteSubmit = this.doDemoteSubmit.bind(this); + this.doDemoteDismiss = this.doDemoteDismiss.bind(this); - this.state = {}; + this.state = { + serverError: null, + showDemoteModal: false, + user: null, + role: null + }; } handleMakeMember(e) { e.preventDefault(); - const data = { - user_id: this.props.user.id, - new_roles: '' - }; + var me = UserStore.getCurrentUser(); + if (this.props.user.id === me.id) { + this.doDemote(this.props.user, ''); + } else { + const data = { + user_id: this.props.user.id, + new_roles: '' + }; - Client.updateRoles(data, - () => { - this.props.refreshProfiles(); - }, - (err) => { - this.setState({serverError: err.message}); - } - ); + Client.updateRoles(data, + () => { + this.props.refreshProfiles(); + }, + (err) => { + this.setState({serverError: err.message}); + } + ); + } } handleMakeActive(e) { @@ -63,19 +78,24 @@ export default class UserItem extends React.Component { handleMakeAdmin(e) { e.preventDefault(); - const data = { - user_id: this.props.user.id, - new_roles: 'admin' - }; + var me = UserStore.getCurrentUser(); + if (this.props.user.id === me.id) { + this.doDemote(this.props.user, 'admin'); + } else { + const data = { + user_id: this.props.user.id, + new_roles: 'admin' + }; - Client.updateRoles(data, - () => { - this.props.refreshProfiles(); - }, - (err) => { - this.setState({serverError: err.message}); - } - ); + Client.updateRoles(data, + () => { + this.props.refreshProfiles(); + }, + (err) => { + this.setState({serverError: err.message}); + } + ); + } } handleMakeSystemAdmin(e) { @@ -100,6 +120,33 @@ export default class UserItem extends React.Component { this.props.doPasswordReset(this.props.user); } + doDemote(user, role) { + this.setState({ + serverError: this.state.serverError, + showDemoteModal: true, + user, + role + }); + } + + doDemoteDismiss() { + this.setState({ + serverError: this.state.serverError, + showDemoteModal: false, + user: null, + role: null + }); + } + + doDemoteSubmit() { + this.setState({ + serverError: this.state.serverError, + showDemoteModal: false, + user: null, + role: null + }); + } + render() { let serverError = null; if (this.state.serverError) { @@ -247,6 +294,19 @@ export default class UserItem extends React.Component { ); } + var me = UserStore.getCurrentUser(); + let makeDemoteModal = null; + if (this.props.user.id === me.id) { + makeDemoteModal = ( + + ); + } return ( @@ -293,6 +353,7 @@ export default class UserItem extends React.Component { + {makeDemoteModal} {serverError} -- cgit v1.2.3-1-g7c22 From fecb5870185d36c0649bb2ec343796fc00a4344f Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Mon, 25 Jan 2016 00:39:40 +0900 Subject: fix ESLint warnings. --- web/react/components/admin_console/demote_own_role_modal.jsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/web/react/components/admin_console/demote_own_role_modal.jsx b/web/react/components/admin_console/demote_own_role_modal.jsx index 63d4dca5c..18747e33e 100644 --- a/web/react/components/admin_console/demote_own_role_modal.jsx +++ b/web/react/components/admin_console/demote_own_role_modal.jsx @@ -1,10 +1,8 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import * as AsyncClient from '../../utils/async_client.jsx'; import * as Client from '../../utils/client.jsx'; const Modal = ReactBootstrap.Modal; -import * as Utils from '../../utils/utils.jsx'; export default class DemoteOwnRoleModal extends React.Component { constructor(props) { @@ -23,7 +21,6 @@ export default class DemoteOwnRoleModal extends React.Component { user_id: this.props.user.id, new_roles: this.props.role }; - console.log(JSON.stringify(data)); Client.updateRoles(data, () => { @@ -45,7 +42,7 @@ export default class DemoteOwnRoleModal extends React.Component { let serverError = null; if (this.state.serverError) { - serverError =
+ serverError =
} return ( -- cgit v1.2.3-1-g7c22 From 27f7b9d1219257958579fee104adf8a0e2e37a9f Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Mon, 25 Jan 2016 00:46:59 +0900 Subject: fix ESLint warnings. --- web/react/components/admin_console/demote_own_role_modal.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/react/components/admin_console/demote_own_role_modal.jsx b/web/react/components/admin_console/demote_own_role_modal.jsx index 18747e33e..58646186d 100644 --- a/web/react/components/admin_console/demote_own_role_modal.jsx +++ b/web/react/components/admin_console/demote_own_role_modal.jsx @@ -42,7 +42,7 @@ export default class DemoteOwnRoleModal extends React.Component { let serverError = null; if (this.state.serverError) { - serverError =
+ serverError =
; } return ( -- cgit v1.2.3-1-g7c22 From d8c4705bba161342bb7d2b4dcd8954203d972614 Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Tue, 26 Jan 2016 23:05:26 +0900 Subject: delete DemoteOwnRoleModal --- .../admin_console/demote_own_role_modal.jsx | 88 ---------------------- web/react/components/admin_console/user_item.jsx | 57 ++++++++------ 2 files changed, 36 insertions(+), 109 deletions(-) delete mode 100644 web/react/components/admin_console/demote_own_role_modal.jsx diff --git a/web/react/components/admin_console/demote_own_role_modal.jsx b/web/react/components/admin_console/demote_own_role_modal.jsx deleted file mode 100644 index 58646186d..000000000 --- a/web/react/components/admin_console/demote_own_role_modal.jsx +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import * as Client from '../../utils/client.jsx'; -const Modal = ReactBootstrap.Modal; - -export default class DemoteOwnRoleModal extends React.Component { - constructor(props) { - super(props); - - this.doDemote = this.doDemote.bind(this); - this.doCancel = this.doCancel.bind(this); - - this.state = { - serverError: null - }; - } - - doDemote() { - const data = { - user_id: this.props.user.id, - new_roles: this.props.role - }; - - Client.updateRoles(data, - () => { - this.setState({serverError: null}); - this.props.onModalSubmit(); - }, - (err) => { - this.setState({serverError: err.message}); - } - ); - } - - doCancel() { - this.setState({serverError: null}); - this.props.onModalDismissed(); - } - - render() { - let serverError = null; - - if (this.state.serverError) { - serverError =
; - } - - return ( - - -

{'Confirm demotion from System Admin role'}

-
- - If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you'll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command.

./platform -assign_role -team_name="yourteam" -email="name@yourcompany.com" -role="system_admin" - {serverError} -
- - - - -
- ); - } -} - -DemoteOwnRoleModal.propTypes = { - user: React.PropTypes.object, - role: React.PropTypes.string, - show: React.PropTypes.bool.isRequired, - onModalSubmit: React.PropTypes.func, - onModalDismissed: React.PropTypes.func -}; diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx index 9220b2cc3..41bf0c99f 100644 --- a/web/react/components/admin_console/user_item.jsx +++ b/web/react/components/admin_console/user_item.jsx @@ -4,7 +4,7 @@ import * as Client from '../../utils/client.jsx'; import * as Utils from '../../utils/utils.jsx'; import UserStore from '../../stores/user_store.jsx'; -import DemoteOwnRoleModal from './demote_own_role_modal.jsx'; +import ConfirmModal from '../confirm_modal.jsx'; import {FormattedMessage} from 'mm-intl'; @@ -18,9 +18,9 @@ export default class UserItem extends React.Component { this.handleMakeAdmin = this.handleMakeAdmin.bind(this); this.handleMakeSystemAdmin = this.handleMakeSystemAdmin.bind(this); this.handleResetPassword = this.handleResetPassword.bind(this); - this.doDemote = this.doDemote.bind(this); - this.doDemoteSubmit = this.doDemoteSubmit.bind(this); - this.doDemoteDismiss = this.doDemoteDismiss.bind(this); + this.handleDemote = this.handleDemote.bind(this); + this.handleDemoteSubmit = this.handleDemoteSubmit.bind(this); + this.handleDemoteCancel = this.handleDemoteCancel.bind(this); this.state = { serverError: null, @@ -34,7 +34,7 @@ export default class UserItem extends React.Component { e.preventDefault(); var me = UserStore.getCurrentUser(); if (this.props.user.id === me.id) { - this.doDemote(this.props.user, ''); + this.handleDemote(this.props.user, ''); } else { const data = { user_id: this.props.user.id, @@ -80,7 +80,7 @@ export default class UserItem extends React.Component { e.preventDefault(); var me = UserStore.getCurrentUser(); if (this.props.user.id === me.id) { - this.doDemote(this.props.user, 'admin'); + this.handleDemote(this.props.user, 'admin'); } else { const data = { user_id: this.props.user.id, @@ -120,7 +120,7 @@ export default class UserItem extends React.Component { this.props.doPasswordReset(this.props.user); } - doDemote(user, role) { + handleDemote(user, role) { this.setState({ serverError: this.state.serverError, showDemoteModal: true, @@ -129,22 +129,36 @@ export default class UserItem extends React.Component { }); } - doDemoteDismiss() { + handleDemoteCancel() { this.setState({ - serverError: this.state.serverError, + serverError: null, showDemoteModal: false, user: null, role: null }); } - doDemoteSubmit() { - this.setState({ - serverError: this.state.serverError, - showDemoteModal: false, - user: null, - role: null - }); + handleDemoteSubmit() { + const data = { + user_id: this.props.user.id, + new_roles: this.props.role + }; + + Client.updateRoles(data, + () => { + this.setState({ + serverError: null, + showDemoteModal: false, + user: null, + role: null + }); + }, + (err) => { + this.setState({ + serverError: err.message + }); + } + ); } render() { @@ -298,12 +312,13 @@ export default class UserItem extends React.Component { let makeDemoteModal = null; if (this.props.user.id === me.id) { makeDemoteModal = ( - ,
,`./platform -assign_role -team_name="yourteam" -email="name@yourcompany.com" -role="system_admin"`,serverError]} + confirm_button='Confirm Demotion' + onConfirm={this.handleDemoteSubmit} + onCancel={this.handleDemoteCancel} /> ); } -- cgit v1.2.3-1-g7c22 From 1b804d563dbcbfec776b4083ae89b1222bafa76d Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Tue, 26 Jan 2016 23:32:35 +0900 Subject: fix ESLint warnings. --- web/react/components/admin_console/user_item.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx index 41bf0c99f..511cab7ef 100644 --- a/web/react/components/admin_console/user_item.jsx +++ b/web/react/components/admin_console/user_item.jsx @@ -315,7 +315,7 @@ export default class UserItem extends React.Component { ,
,`./platform -assign_role -team_name="yourteam" -email="name@yourcompany.com" -role="system_admin"`,serverError]} + message={[`If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you'll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command.`, React.createElement('br'), React.createElement('br'), `./platform -assign_role -team_name="yourteam" -email="name@yourcompany.com" -role="system_admin"`, serverError]} confirm_button='Confirm Demotion' onConfirm={this.handleDemoteSubmit} onCancel={this.handleDemoteCancel} @@ -378,6 +378,7 @@ export default class UserItem extends React.Component { UserItem.propTypes = { user: React.PropTypes.object.isRequired, + role: React.PropTypes.string, refreshProfiles: React.PropTypes.func.isRequired, doPasswordReset: React.PropTypes.func.isRequired }; -- cgit v1.2.3-1-g7c22 From c1b38e7119ac537f2dc6e446aec3990474ae8deb Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Wed, 27 Jan 2016 20:49:33 +0900 Subject: fix role bug. add redirect after demote own role. --- web/react/components/admin_console/user_item.jsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx index 511cab7ef..26d294661 100644 --- a/web/react/components/admin_console/user_item.jsx +++ b/web/react/components/admin_console/user_item.jsx @@ -5,6 +5,7 @@ import * as Client from '../../utils/client.jsx'; import * as Utils from '../../utils/utils.jsx'; import UserStore from '../../stores/user_store.jsx'; import ConfirmModal from '../confirm_modal.jsx'; +import TeamStore from '../../stores/team_store.jsx'; import {FormattedMessage} from 'mm-intl'; @@ -32,7 +33,7 @@ export default class UserItem extends React.Component { handleMakeMember(e) { e.preventDefault(); - var me = UserStore.getCurrentUser(); + let me = UserStore.getCurrentUser(); if (this.props.user.id === me.id) { this.handleDemote(this.props.user, ''); } else { @@ -78,7 +79,7 @@ export default class UserItem extends React.Component { handleMakeAdmin(e) { e.preventDefault(); - var me = UserStore.getCurrentUser(); + let me = UserStore.getCurrentUser(); if (this.props.user.id === me.id) { this.handleDemote(this.props.user, 'admin'); } else { @@ -141,7 +142,7 @@ export default class UserItem extends React.Component { handleDemoteSubmit() { const data = { user_id: this.props.user.id, - new_roles: this.props.role + new_roles: this.state.role }; Client.updateRoles(data, @@ -152,6 +153,13 @@ export default class UserItem extends React.Component { user: null, role: null }); + + let teamUrl = TeamStore.getCurrentTeamUrl(); + if (teamUrl) { + window.location.href = teamUrl; + } else { + window.location.href = '/'; + } }, (err) => { this.setState({ @@ -308,7 +316,7 @@ export default class UserItem extends React.Component { ); } - var me = UserStore.getCurrentUser(); + let me = UserStore.getCurrentUser(); let makeDemoteModal = null; if (this.props.user.id === me.id) { makeDemoteModal = ( @@ -378,7 +386,6 @@ export default class UserItem extends React.Component { UserItem.propTypes = { user: React.PropTypes.object.isRequired, - role: React.PropTypes.string, refreshProfiles: React.PropTypes.func.isRequired, doPasswordReset: React.PropTypes.func.isRequired }; -- cgit v1.2.3-1-g7c22 From ae2201b304dc5da907d23dfe1f7da6f7a01c2b6d Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Wed, 27 Jan 2016 21:02:21 +0900 Subject: fix ESLint warnings. --- web/react/components/admin_console/user_item.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx index 26d294661..032b698cd 100644 --- a/web/react/components/admin_console/user_item.jsx +++ b/web/react/components/admin_console/user_item.jsx @@ -33,7 +33,7 @@ export default class UserItem extends React.Component { handleMakeMember(e) { e.preventDefault(); - let me = UserStore.getCurrentUser(); + const me = UserStore.getCurrentUser(); if (this.props.user.id === me.id) { this.handleDemote(this.props.user, ''); } else { @@ -79,7 +79,7 @@ export default class UserItem extends React.Component { handleMakeAdmin(e) { e.preventDefault(); - let me = UserStore.getCurrentUser(); + const me = UserStore.getCurrentUser(); if (this.props.user.id === me.id) { this.handleDemote(this.props.user, 'admin'); } else { @@ -154,7 +154,7 @@ export default class UserItem extends React.Component { role: null }); - let teamUrl = TeamStore.getCurrentTeamUrl(); + const teamUrl = TeamStore.getCurrentTeamUrl(); if (teamUrl) { window.location.href = teamUrl; } else { @@ -316,7 +316,7 @@ export default class UserItem extends React.Component { ); } - let me = UserStore.getCurrentUser(); + const me = UserStore.getCurrentUser(); let makeDemoteModal = null; if (this.props.user.id === me.id) { makeDemoteModal = ( -- cgit v1.2.3-1-g7c22 From 8b2fb86c3a21f7d4bccc4f3497e6f9d514cbad0c Mon Sep 17 00:00:00 2001 From: Tatsuya Niwa Date: Sat, 30 Jan 2016 02:19:41 +0900 Subject: fix text localization. --- web/react/components/admin_console/user_item.jsx | 26 ++++++++++++++++++++---- web/static/i18n/en.json | 3 +++ web/static/i18n/es.json | 3 +++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx index 032b698cd..5ab429dd5 100644 --- a/web/react/components/admin_console/user_item.jsx +++ b/web/react/components/admin_console/user_item.jsx @@ -7,7 +7,22 @@ import UserStore from '../../stores/user_store.jsx'; import ConfirmModal from '../confirm_modal.jsx'; import TeamStore from '../../stores/team_store.jsx'; -import {FormattedMessage} from 'mm-intl'; +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +var messages = defineMessages({ + confirmDemoteRoleTitle: { + id: 'admin.user_item.confirmDemoteRoleTitle', + defaultMessage: 'Confirm demotion from System Admin role' + }, + confirmDemotion: { + id: 'admin.user_item.confirmDemotion', + defaultMessage: 'Confirm Demotion' + }, + confirmDemoteDescription: { + id: 'admin.user_item.confirmDemoteDescription', + defaultMessage: 'If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you\'ll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command.' + } +}); export default class UserItem extends React.Component { constructor(props) { @@ -322,9 +337,9 @@ export default class UserItem extends React.Component { makeDemoteModal = ( @@ -385,7 +400,10 @@ export default class UserItem extends React.Component { } UserItem.propTypes = { + intl: intlShape.isRequired, user: React.PropTypes.object.isRequired, refreshProfiles: React.PropTypes.func.isRequired, doPasswordReset: React.PropTypes.func.isRequired }; + +export default injectIntl(UserItem); diff --git a/web/static/i18n/en.json b/web/static/i18n/en.json index 1a82660fd..6afdafcff 100644 --- a/web/static/i18n/en.json +++ b/web/static/i18n/en.json @@ -396,6 +396,9 @@ "admin.user_item.makeActive": "Make Active", "admin.user_item.makeInactive": "Make Inactive", "admin.user_item.resetPwd": "Reset Password", + "admin.user_item.confirmDemoteRoleTitle": "Confirm demotion from System Admin role", + "admin.user_item.confirmDemotion": "Confirm Demotion", + "admin.user_item.confirmDemoteDescription": "If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you'll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command.", "authorize.title": "An application would like to connect to your {teamName} account", "authorize.app": "The app {appName} would like the ability to access and modify your basic information.", "authorize.access": "Allow {appName} access?", diff --git a/web/static/i18n/es.json b/web/static/i18n/es.json index d54c99535..71465ad1e 100644 --- a/web/static/i18n/es.json +++ b/web/static/i18n/es.json @@ -396,6 +396,9 @@ "admin.user_item.resetPwd": "Reiniciar Contraseña", "admin.user_item.sysAdmin": "Admin de Sistema", "admin.user_item.teamAdmin": "Admin de Equipo", + "admin.user_item.confirmDemoteRoleTitle": "Confirm demotion from System Admin role", + "admin.user_item.confirmDemotion": "Confirm Demotion", + "admin.user_item.confirmDemoteDescription": "If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you'll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command.", "authorize.access": "¿Permitir acceso a {appName}?", "authorize.allow": "Permitir", "authorize.app": "La app {appName} quiere tener la abilidad de accesar y modificar tu información básica.", -- cgit v1.2.3-1-g7c22