PLT-6987 User access token UI (#7007)
* Add user access token UI * Fix enter press and update mattermost-redux * Updating UI for access token stuff (#7066) * Revert segment key
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
4ef844298f
Коммит
5da5c0bbfb
@@ -25,6 +25,7 @@ export default class WebhookSettings extends AdminSettings {
|
||||
config.ServiceSettings.EnablePostUsernameOverride = this.state.enablePostUsernameOverride;
|
||||
config.ServiceSettings.EnablePostIconOverride = this.state.enablePostIconOverride;
|
||||
config.ServiceSettings.EnableOAuthServiceProvider = this.state.enableOAuthServiceProvider;
|
||||
config.ServiceSettings.EnableUserAccessTokens = this.state.enableUserAccessTokens;
|
||||
|
||||
return config;
|
||||
}
|
||||
@@ -37,7 +38,8 @@ export default class WebhookSettings extends AdminSettings {
|
||||
enableOnlyAdminIntegrations: config.ServiceSettings.EnableOnlyAdminIntegrations,
|
||||
enablePostUsernameOverride: config.ServiceSettings.EnablePostUsernameOverride,
|
||||
enablePostIconOverride: config.ServiceSettings.EnablePostIconOverride,
|
||||
enableOAuthServiceProvider: config.ServiceSettings.EnableOAuthServiceProvider
|
||||
enableOAuthServiceProvider: config.ServiceSettings.EnableOAuthServiceProvider,
|
||||
enableUserAccessTokens: config.ServiceSettings.EnableUserAccessTokens
|
||||
};
|
||||
}
|
||||
|
||||
@@ -172,6 +174,23 @@ export default class WebhookSettings extends AdminSettings {
|
||||
value={this.state.enablePostIconOverride}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
<BooleanSetting
|
||||
id='enableUserAccessTokens'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.service.userAccessTokensTitle'
|
||||
defaultMessage='Enable User Access Tokens: '
|
||||
/>
|
||||
}
|
||||
helpText={
|
||||
<FormattedHTMLMessage
|
||||
id='admin.service.userAccessTokensDescription'
|
||||
defaultMessage='When true, users can create <a href="https://about.mattermost.com/default-user-access-tokens" target="_blank">user access tokens</a> for integrations in <strong>Account Settings > Security</strong>. They can be used to authenticate against the API and give full access to the account.<br/><br/>To manage who can create user access tokens, go to the <strong>System Console > Users</strong> page.'
|
||||
/>
|
||||
}
|
||||
value={this.state.enableUserAccessTokens}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</SettingsGroup>
|
||||
);
|
||||
}
|
||||
|
||||
25
webapp/components/admin_console/manage_roles_modal/index.js
Обычный файл
25
webapp/components/admin_console/manage_roles_modal/index.js
Обычный файл
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {updateUserRoles} from 'mattermost-redux/actions/users';
|
||||
|
||||
import ManageRolesModal from './manage_roles_modal.jsx';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
...ownProps,
|
||||
userAccessTokensEnabled: state.entities.admin.config.ServiceSettings.EnableUserAccessTokens
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
updateUserRoles
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ManageRolesModal);
|
||||
@@ -0,0 +1,349 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import * as UserUtils from 'mattermost-redux/utils/user_utils';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import {trackEvent} from 'actions/diagnostics_actions.jsx';
|
||||
|
||||
import React from 'react';
|
||||
import {Modal} from 'react-bootstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
||||
|
||||
function getStateFromProps(props) {
|
||||
const roles = props.user && props.user.roles ? props.user.roles : '';
|
||||
|
||||
return {
|
||||
error: null,
|
||||
hasPostAllRole: UserUtils.hasPostAllRole(roles),
|
||||
hasPostAllPublicRole: UserUtils.hasPostAllPublicRole(roles),
|
||||
hasUserAccessTokenRole: UserUtils.hasUserAccessTokenRole(roles),
|
||||
isSystemAdmin: UserUtils.isSystemAdmin(roles)
|
||||
};
|
||||
}
|
||||
|
||||
export default class ManageRolesModal extends React.PureComponent {
|
||||
static propTypes = {
|
||||
|
||||
/**
|
||||
* Set to render the modal
|
||||
*/
|
||||
show: PropTypes.bool.isRequired,
|
||||
|
||||
/**
|
||||
* The user the roles are being managed for
|
||||
*/
|
||||
user: PropTypes.object,
|
||||
|
||||
/**
|
||||
* Set if user access tokens are enabled
|
||||
*/
|
||||
userAccessTokensEnabled: PropTypes.bool.isRequired,
|
||||
|
||||
/**
|
||||
* Function called when modal is dismissed
|
||||
*/
|
||||
onModalDismissed: PropTypes.func.isRequired,
|
||||
|
||||
actions: PropTypes.shape({
|
||||
|
||||
/**
|
||||
* Function to update a user's roles
|
||||
*/
|
||||
updateUserRoles: PropTypes.func.isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = getStateFromProps(props);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const user = this.props.user || {};
|
||||
const nextUser = nextProps.user || {};
|
||||
if (user.id !== nextUser.id) {
|
||||
this.setState(getStateFromProps(nextProps));
|
||||
}
|
||||
}
|
||||
|
||||
handleError = (error) => {
|
||||
this.setState({
|
||||
error
|
||||
});
|
||||
}
|
||||
|
||||
handleSystemAdminChange = (e) => {
|
||||
if (e.target.name === 'systemadmin') {
|
||||
this.setState({isSystemAdmin: true});
|
||||
} else if (e.target.name === 'systemmember') {
|
||||
this.setState({isSystemAdmin: false});
|
||||
}
|
||||
};
|
||||
|
||||
handleUserAccessTokenChange = (e) => {
|
||||
this.setState({
|
||||
hasUserAccessTokenRole: e.target.checked
|
||||
});
|
||||
};
|
||||
|
||||
handlePostAllChange = (e) => {
|
||||
this.setState({
|
||||
hasPostAllRole: e.target.checked
|
||||
});
|
||||
};
|
||||
|
||||
handlePostAllPublicChange = (e) => {
|
||||
this.setState({
|
||||
hasPostAllPublicRole: e.target.checked
|
||||
});
|
||||
};
|
||||
|
||||
trackRoleChanges = (roles, oldRoles) => {
|
||||
if (UserUtils.hasUserAccessTokenRole(roles) && !UserUtils.hasUserAccessTokenRole(oldRoles)) {
|
||||
trackEvent('actions', 'add_roles', {role: General.SYSTEM_USER_ACCESS_TOKEN_ROLE});
|
||||
} else if (!UserUtils.hasUserAccessTokenRole(roles) && UserUtils.hasUserAccessTokenRole(oldRoles)) {
|
||||
trackEvent('actions', 'remove_roles', {role: General.SYSTEM_USER_ACCESS_TOKEN_ROLE});
|
||||
}
|
||||
|
||||
if (UserUtils.hasPostAllRole(roles) && !UserUtils.hasPostAllRole(oldRoles)) {
|
||||
trackEvent('actions', 'add_roles', {role: General.SYSTEM_POST_ALL_ROLE});
|
||||
} else if (!UserUtils.hasPostAllRole(roles) && UserUtils.hasPostAllRole(oldRoles)) {
|
||||
trackEvent('actions', 'remove_roles', {role: General.SYSTEM_POST_ALL_ROLE});
|
||||
}
|
||||
|
||||
if (UserUtils.hasPostAllPublicRole(roles) && !UserUtils.hasPostAllPublicRole(oldRoles)) {
|
||||
trackEvent('actions', 'add_roles', {role: General.SYSTEM_POST_ALL_PUBLIC_ROLE});
|
||||
} else if (!UserUtils.hasPostAllPublicRole(roles) && UserUtils.hasPostAllPublicRole(oldRoles)) {
|
||||
trackEvent('actions', 'remove_roles', {role: General.SYSTEM_POST_ALL_PUBLIC_ROLE});
|
||||
}
|
||||
}
|
||||
|
||||
handleSave = async () => {
|
||||
this.setState({error: null});
|
||||
|
||||
let roles = General.SYSTEM_USER_ROLE;
|
||||
|
||||
if (this.state.isSystemAdmin) {
|
||||
roles += ' ' + General.SYSTEM_ADMIN_ROLE;
|
||||
} else if (this.state.hasUserAccessTokenRole) {
|
||||
roles += ' ' + General.SYSTEM_USER_ACCESS_TOKEN_ROLE;
|
||||
if (this.state.hasPostAllRole) {
|
||||
roles += ' ' + General.SYSTEM_POST_ALL_ROLE;
|
||||
} else if (this.state.hasPostAllPublicRole) {
|
||||
roles += ' ' + General.SYSTEM_POST_ALL_PUBLIC_ROLE;
|
||||
}
|
||||
}
|
||||
|
||||
const data = await this.props.actions.updateUserRoles(this.props.user.id, roles);
|
||||
|
||||
this.trackRoleChanges(roles, this.props.user.roles);
|
||||
|
||||
if (data) {
|
||||
this.props.onModalDismissed();
|
||||
} else {
|
||||
this.handleError(
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.saveError'
|
||||
defaultMessage='Unable to save roles.'
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderContents = () => {
|
||||
const {user} = this.props;
|
||||
|
||||
if (user == null) {
|
||||
return <div/>;
|
||||
}
|
||||
|
||||
let name = UserUtils.getFullName(user);
|
||||
if (name) {
|
||||
name += ` (@${user.username})`;
|
||||
} else {
|
||||
name = `@${user.username}`;
|
||||
}
|
||||
|
||||
let additionalRoles;
|
||||
if (this.state.hasUserAccessTokenRole || this.state.isSystemAdmin) {
|
||||
additionalRoles = (
|
||||
<div>
|
||||
<p>
|
||||
<FormattedHTMLMessage
|
||||
id='admin.manage_roles.additionalRoles'
|
||||
defaultMessage='Select additional permissions for the account. <a href="https://about.mattermost.com/default-permissions" target="_blank">Read more about roles and permissions</a>.'
|
||||
/>
|
||||
</p>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
ref='postall'
|
||||
checked={this.state.hasPostAllRole || this.state.isSystemAdmin}
|
||||
disabled={this.state.isSystemAdmin}
|
||||
onChange={this.handlePostAllChange}
|
||||
/>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.postAllRoleTitle'
|
||||
defaultMessage='post:all'
|
||||
/>
|
||||
</strong>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.postAllRole'
|
||||
defaultMessage='Access to post to all Mattermost channels including direct messages.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
ref='postallpublic'
|
||||
checked={this.state.hasPostAllPublicRole || this.state.hasPostAllRole || this.state.isSystemAdmin}
|
||||
disabled={this.state.hasPostAllRole || this.state.isSystemAdmin}
|
||||
onChange={this.handlePostAllPublicChange}
|
||||
/>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.postAllPublicRoleTitle'
|
||||
defaultMessage='post:channels'
|
||||
/>
|
||||
</strong>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.postAllPublicRole'
|
||||
defaultMessage='Access to post to all Mattermost public channels.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let userAccessTokenContent;
|
||||
if (this.props.userAccessTokensEnabled) {
|
||||
userAccessTokenContent = (
|
||||
<div>
|
||||
<div className='checkbox'>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
ref='postall'
|
||||
checked={this.state.hasUserAccessTokenRole || this.state.isSystemAdmin}
|
||||
disabled={this.state.isSystemAdmin}
|
||||
onChange={this.handleUserAccessTokenChange}
|
||||
/>
|
||||
<FormattedHTMLMessage
|
||||
id='admin.manage_roles.allowUserAccessTokens'
|
||||
defaultMessage='Allow this account to generate <a href="https://about.mattermost.com/default-user-access-tokens" target="_blank">user access tokens</a>.'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className='member-row--padded'>
|
||||
{additionalRoles}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='manage-teams__user'>
|
||||
<img
|
||||
className='manage-teams__profile-picture'
|
||||
src={Client4.getProfilePictureUrl(user.id, user.last_picture_update)}
|
||||
/>
|
||||
<div className='manage-teams__info'>
|
||||
<div className='manage-teams__name'>
|
||||
{name}
|
||||
</div>
|
||||
<div className='manage-teams__email'>
|
||||
{user.email}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className='manage-row--inner'>
|
||||
<div className='radio-inline'>
|
||||
<label>
|
||||
<input
|
||||
name='systemadmin'
|
||||
type='radio'
|
||||
checked={this.state.isSystemAdmin}
|
||||
onChange={this.handleSystemAdminChange}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.systemAdmin'
|
||||
defaultMessage='System Admin'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className='radio-inline'>
|
||||
<label>
|
||||
<input
|
||||
name='systemmember'
|
||||
type='radio'
|
||||
checked={!this.state.isSystemAdmin}
|
||||
onChange={this.handleSystemAdminChange}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.systemMember'
|
||||
defaultMessage='Member'
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{userAccessTokenContent}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal
|
||||
show={this.props.show}
|
||||
onHide={this.props.onModalDismissed}
|
||||
dialogClassName='manage-teams'
|
||||
>
|
||||
<Modal.Header closeButton={true}>
|
||||
<Modal.Title>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.manageRolesTitle'
|
||||
defaultMessage='Manage Roles'
|
||||
/>
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
{this.renderContents()}
|
||||
{this.state.error}
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<button
|
||||
type='button'
|
||||
className='btn btn-link'
|
||||
onClick={this.props.onModalDismissed}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.cancel'
|
||||
defaultMessage='Cancel'
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
type='button'
|
||||
className='btn btn-primary'
|
||||
onClick={this.handleSave}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.manage_roles.save'
|
||||
defaultMessage='Save'
|
||||
/>
|
||||
</button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Modal} from 'react-bootstrap';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import * as TeamActions from 'actions/team_actions.jsx';
|
||||
|
||||
@@ -29,14 +28,6 @@ export default class ManageTeamsModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.loadTeamsAndTeamMembers = this.loadTeamsAndTeamMembers.bind(this);
|
||||
|
||||
this.handleError = this.handleError.bind(this);
|
||||
this.handleMemberChange = this.handleMemberChange.bind(this);
|
||||
this.handleMemberRemove = this.handleMemberRemove.bind(this);
|
||||
|
||||
this.renderContents = this.renderContents.bind(this);
|
||||
|
||||
this.state = {
|
||||
error: null,
|
||||
teams: null,
|
||||
@@ -66,7 +57,7 @@ export default class ManageTeamsModal extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
loadTeamsAndTeamMembers(user = this.props.user) {
|
||||
loadTeamsAndTeamMembers = (user = this.props.user) => {
|
||||
TeamActions.getTeamsForUser(user.id, (teams) => {
|
||||
this.setState({
|
||||
teams: teams.sort(sortTeamsByDisplayName)
|
||||
@@ -80,13 +71,13 @@ export default class ManageTeamsModal extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
handleError = (error) => {
|
||||
this.setState({
|
||||
error
|
||||
});
|
||||
}
|
||||
|
||||
handleMemberChange() {
|
||||
handleMemberChange = () => {
|
||||
TeamActions.getTeamMembersForUser(this.props.user.id, (teamMembers) => {
|
||||
this.setState({
|
||||
teamMembers
|
||||
@@ -94,14 +85,14 @@ export default class ManageTeamsModal extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleMemberRemove(teamId) {
|
||||
handleMemberRemove = (teamId) => {
|
||||
this.setState({
|
||||
teams: this.state.teams.filter((team) => team.id !== teamId),
|
||||
teamMembers: this.state.teamMembers.filter((teamMember) => teamMember.team_id !== teamId)
|
||||
});
|
||||
}
|
||||
|
||||
renderContents() {
|
||||
renderContents = () => {
|
||||
const {user} = this.props;
|
||||
const {teams, teamMembers} = this.state;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ export default class RemoveFromTeamButton extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<button
|
||||
className='btn btn-default'
|
||||
className='btn btn-danger'
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
<FormattedMessage
|
||||
|
||||
27
webapp/components/admin_console/manage_tokens_modal/index.js
Обычный файл
27
webapp/components/admin_console/manage_tokens_modal/index.js
Обычный файл
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {getUserAccessTokensForUser} from 'mattermost-redux/actions/users';
|
||||
|
||||
import ManageTokensModal from './manage_tokens_modal.jsx';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const userId = ownProps.user ? ownProps.user.id : '';
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
userAccessTokens: state.entities.admin.userAccessTokens[userId]
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
getUserAccessTokensForUser
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ManageTokensModal);
|
||||
@@ -0,0 +1,181 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import LoadingScreen from 'components/loading_screen.jsx';
|
||||
import RevokeTokenButton from 'components/admin_console/revoke_token_button';
|
||||
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import * as UserUtils from 'mattermost-redux/utils/user_utils';
|
||||
|
||||
import React from 'react';
|
||||
import {Modal} from 'react-bootstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
||||
|
||||
export default class ManageTokensModal extends React.PureComponent {
|
||||
static propTypes = {
|
||||
|
||||
/**
|
||||
* Set to render the modal
|
||||
*/
|
||||
show: PropTypes.bool.isRequired,
|
||||
|
||||
/**
|
||||
* The user the roles are being managed for
|
||||
*/
|
||||
user: PropTypes.object,
|
||||
|
||||
/**
|
||||
* The user access tokens for a user, object with token ids as keys
|
||||
*/
|
||||
userAccessTokens: PropTypes.object,
|
||||
|
||||
/**
|
||||
* Function called when modal is dismissed
|
||||
*/
|
||||
onModalDismissed: PropTypes.func.isRequired,
|
||||
|
||||
actions: PropTypes.shape({
|
||||
|
||||
/**
|
||||
* Function to get a user's access tokens
|
||||
*/
|
||||
getUserAccessTokensForUser: PropTypes.func.isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {error: null};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const userId = this.props.user ? this.props.user.id : null;
|
||||
const nextUserId = nextProps.user ? nextProps.user.id : null;
|
||||
if (nextUserId && nextUserId !== userId) {
|
||||
this.props.actions.getUserAccessTokensForUser(nextUserId, 0, 200);
|
||||
}
|
||||
}
|
||||
|
||||
handleError = (error) => {
|
||||
this.setState({
|
||||
error
|
||||
});
|
||||
}
|
||||
|
||||
renderContents = () => {
|
||||
const {user, userAccessTokens} = this.props;
|
||||
|
||||
if (!user) {
|
||||
return <LoadingScreen/>;
|
||||
}
|
||||
|
||||
let name = UserUtils.getFullName(user);
|
||||
if (name) {
|
||||
name += ` (@${user.username})`;
|
||||
} else {
|
||||
name = `@${user.username}`;
|
||||
}
|
||||
|
||||
let tokenList;
|
||||
if (userAccessTokens) {
|
||||
const userAccessTokensList = Object.values(userAccessTokens);
|
||||
|
||||
if (userAccessTokensList.length === 0) {
|
||||
tokenList = (
|
||||
<div className='manage-row__empty'>
|
||||
<FormattedMessage
|
||||
id='admin.manage_tokens.userAccessTokensNone'
|
||||
defaultMessage='No user access tokens.'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
tokenList = userAccessTokensList.map((token) => {
|
||||
return (
|
||||
<div
|
||||
key={token.id}
|
||||
className='manage-teams__team'
|
||||
>
|
||||
<div className='manage-teams__team-name'>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='admin.manage_tokens.userAccessTokensNameLabel'
|
||||
defaultMessage='Name: '
|
||||
/>
|
||||
{token.description}
|
||||
</div>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='admin.manage_tokens.userAccessTokensIdLabel'
|
||||
defaultMessage='Token ID: '
|
||||
/>
|
||||
{token.id}
|
||||
</div>
|
||||
</div>
|
||||
<div className='manage-teams__team-actions'>
|
||||
<RevokeTokenButton
|
||||
tokenId={token.id}
|
||||
onError={this.handleError}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
tokenList = <LoadingScreen/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='manage-teams__user'>
|
||||
<img
|
||||
className='manage-teams__profile-picture'
|
||||
src={Client4.getProfilePictureUrl(user.id, user.last_picture_update)}
|
||||
/>
|
||||
<div className='manage-teams__info'>
|
||||
<div className='manage-teams__name'>
|
||||
{name}
|
||||
</div>
|
||||
<div className='manage-teams__email'>
|
||||
{user.email}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='padding-top x2'>
|
||||
<FormattedHTMLMessage
|
||||
id='admin.manage_tokens.userAccessTokensDescription'
|
||||
defaultMessage='User access tokens function similar to session tokens and can be used by integrations to <a href="https://about.mattermost.com/default-api-authentication" target="_blank">authenticate against the REST API</a>. Learn more about <a href="https://about.mattermost.com/default-user-access-tokens" target="_blank">user access tokens</a>.'
|
||||
/>
|
||||
</div>
|
||||
<div className='manage-teams__teams'>
|
||||
{tokenList}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal
|
||||
show={this.props.show}
|
||||
onHide={this.props.onModalDismissed}
|
||||
dialogClassName='manage-teams'
|
||||
>
|
||||
<Modal.Header closeButton={true}>
|
||||
<Modal.Title>
|
||||
<FormattedMessage
|
||||
id='admin.manage_tokens.manageTokensTitle'
|
||||
defaultMessage='Manage User Access Tokens'
|
||||
/>
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
{this.renderContents()}
|
||||
{this.state.error}
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
24
webapp/components/admin_console/revoke_token_button/index.js
Обычный файл
24
webapp/components/admin_console/revoke_token_button/index.js
Обычный файл
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {revokeUserAccessToken} from 'mattermost-redux/actions/users';
|
||||
|
||||
import RevokeTokenButton from './revoke_token_button.jsx';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
...ownProps
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators({
|
||||
revokeUserAccessToken
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(RevokeTokenButton);
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {trackEvent} from 'actions/diagnostics_actions.jsx';
|
||||
|
||||
export default class RevokeTokenButton extends React.PureComponent {
|
||||
static propTypes = {
|
||||
|
||||
/*
|
||||
* Token id to revoke
|
||||
*/
|
||||
tokenId: PropTypes.string.isRequired,
|
||||
|
||||
/*
|
||||
* Function to call on error
|
||||
*/
|
||||
onError: PropTypes.func.isRequired,
|
||||
|
||||
actions: PropTypes.shape({
|
||||
|
||||
/**
|
||||
* Function to revoke a user access token
|
||||
*/
|
||||
revokeUserAccessToken: PropTypes.func.isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
handleClick = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const {error} = await this.props.actions.revokeUserAccessToken(this.props.tokenId);
|
||||
trackEvent('system_console', 'revoke_user_access_token');
|
||||
|
||||
if (error) {
|
||||
this.props.onError(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<button
|
||||
className='btn btn-danger'
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.revoke_token_button.delete'
|
||||
defaultMessage='Delete'
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {getTeams, getTeamStats} from 'mattermost-redux/actions/teams';
|
||||
import {getUser} from 'mattermost-redux/actions/users';
|
||||
import {getUser, getUserAccessToken} from 'mattermost-redux/actions/users';
|
||||
|
||||
import {getTeamsList} from 'mattermost-redux/selectors/entities/teams';
|
||||
|
||||
@@ -22,7 +22,8 @@ function mapDispatchToProps(dispatch) {
|
||||
actions: bindActionCreators({
|
||||
getTeams,
|
||||
getTeamStats,
|
||||
getUser
|
||||
getUser,
|
||||
getUserAccessToken
|
||||
}, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,7 +54,12 @@ export default class SystemUsers extends React.Component {
|
||||
/*
|
||||
* Function to get a user
|
||||
*/
|
||||
getUser: PropTypes.func.isRequired
|
||||
getUser: PropTypes.func.isRequired,
|
||||
|
||||
/*
|
||||
* Function to get a user access token
|
||||
*/
|
||||
getUserAccessToken: PropTypes.func.isRequired
|
||||
}).isRequired
|
||||
}
|
||||
|
||||
@@ -240,7 +245,7 @@ export default class SystemUsers extends React.Component {
|
||||
(users) => {
|
||||
if (users.length === 0 && term.length === USER_ID_LENGTH) {
|
||||
// This term didn't match any users name, but it does look like it might be a user's ID
|
||||
this.getUserById(term);
|
||||
this.getUserByTokenOrId(term);
|
||||
} else {
|
||||
this.setState({loading: false});
|
||||
}
|
||||
@@ -269,6 +274,22 @@ export default class SystemUsers extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
getUserByTokenOrId = async (id) => {
|
||||
if (global.window.mm_config.EnableUserAccessTokens === 'true') {
|
||||
const {data} = await this.props.actions.getUserAccessToken(id);
|
||||
|
||||
if (data) {
|
||||
this.term = data.user_id;
|
||||
this.setState({term: data.user_id});
|
||||
this.updateUsersFromStore(this.state.teamId, data.user_id);
|
||||
this.getUserById(data.user_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.getUserById(id);
|
||||
}
|
||||
|
||||
renderFilterRow(doSearch) {
|
||||
const teams = this.props.teams.map((team) => {
|
||||
return (
|
||||
|
||||
@@ -8,7 +8,7 @@ import UserStore from 'stores/user_store.jsx';
|
||||
|
||||
import Constants from 'utils/constants.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import {updateUserRoles, updateActive} from 'actions/user_actions.jsx';
|
||||
import {updateActive} from 'actions/user_actions.jsx';
|
||||
import {adminResetMfa} from 'actions/admin_actions.jsx';
|
||||
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
@@ -19,28 +19,36 @@ import React from 'react';
|
||||
|
||||
export default class SystemUsersDropdown extends React.Component {
|
||||
static propTypes = {
|
||||
|
||||
/*
|
||||
* User to manage with dropdown
|
||||
*/
|
||||
user: PropTypes.object.isRequired,
|
||||
|
||||
/*
|
||||
* Function to open password reset, takes user as an argument
|
||||
*/
|
||||
doPasswordReset: PropTypes.func.isRequired,
|
||||
doManageTeams: PropTypes.func.isRequired
|
||||
|
||||
/*
|
||||
* Function to open manage teams, takes user as an argument
|
||||
*/
|
||||
doManageTeams: PropTypes.func.isRequired,
|
||||
|
||||
/*
|
||||
* Function to open manage roles, takes user as an argument
|
||||
*/
|
||||
doManageRoles: PropTypes.func.isRequired,
|
||||
|
||||
/*
|
||||
* Function to open manage tokens, takes user as an argument
|
||||
*/
|
||||
doManageTokens: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleMakeMember = this.handleMakeMember.bind(this);
|
||||
this.handleMakeActive = this.handleMakeActive.bind(this);
|
||||
this.handleShowDeactivateMemberModal = this.handleShowDeactivateMemberModal.bind(this);
|
||||
this.handleDeactivateMember = this.handleDeactivateMember.bind(this);
|
||||
this.handleDeactivateCancel = this.handleDeactivateCancel.bind(this);
|
||||
this.handleMakeSystemAdmin = this.handleMakeSystemAdmin.bind(this);
|
||||
this.handleManageTeams = this.handleManageTeams.bind(this);
|
||||
this.handleResetPassword = this.handleResetPassword.bind(this);
|
||||
this.handleResetMfa = this.handleResetMfa.bind(this);
|
||||
this.handleDemoteSystemAdmin = this.handleDemoteSystemAdmin.bind(this);
|
||||
this.handleDemoteSubmit = this.handleDemoteSubmit.bind(this);
|
||||
this.handleDemoteCancel = this.handleDemoteCancel.bind(this);
|
||||
this.renderDeactivateMemberModal = this.renderDeactivateMemberModal.bind(this);
|
||||
|
||||
this.state = {
|
||||
serverError: null,
|
||||
showDemoteModal: false,
|
||||
@@ -50,28 +58,7 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
doMakeMember() {
|
||||
updateUserRoles(
|
||||
this.props.user.id,
|
||||
'system_user',
|
||||
null,
|
||||
(err) => {
|
||||
this.setState({serverError: err.message});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
handleMakeMember(e) {
|
||||
e.preventDefault();
|
||||
const me = UserStore.getCurrentUser();
|
||||
if (this.props.user.id === me.id && me.roles.includes('system_admin')) {
|
||||
this.handleDemoteSystemAdmin(this.props.user, 'member');
|
||||
} else {
|
||||
this.doMakeMember();
|
||||
}
|
||||
}
|
||||
|
||||
handleMakeActive(e) {
|
||||
handleMakeActive = (e) => {
|
||||
e.preventDefault();
|
||||
updateActive(this.props.user.id, true, null,
|
||||
(err) => {
|
||||
@@ -80,31 +67,30 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
handleMakeSystemAdmin(e) {
|
||||
e.preventDefault();
|
||||
|
||||
updateUserRoles(
|
||||
this.props.user.id,
|
||||
'system_user system_admin',
|
||||
null,
|
||||
(err) => {
|
||||
this.setState({serverError: err.message});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
handleManageTeams(e) {
|
||||
handleManageTeams = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
this.props.doManageTeams(this.props.user);
|
||||
}
|
||||
|
||||
handleResetPassword(e) {
|
||||
handleManageRoles = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
this.props.doManageRoles(this.props.user);
|
||||
}
|
||||
|
||||
handleManageTokens = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
this.props.doManageTokens(this.props.user);
|
||||
}
|
||||
|
||||
handleResetPassword = (e) => {
|
||||
e.preventDefault();
|
||||
this.props.doPasswordReset(this.props.user);
|
||||
}
|
||||
|
||||
handleResetMfa(e) {
|
||||
handleResetMfa = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
adminResetMfa(this.props.user.id,
|
||||
@@ -115,7 +101,7 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
handleDemoteSystemAdmin(user, role) {
|
||||
handleDemoteSystemAdmin = (user, role) => {
|
||||
this.setState({
|
||||
serverError: this.state.serverError,
|
||||
showDemoteModal: true,
|
||||
@@ -124,7 +110,7 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleDemoteCancel() {
|
||||
handleDemoteCancel = () => {
|
||||
this.setState({
|
||||
serverError: null,
|
||||
showDemoteModal: false,
|
||||
@@ -133,7 +119,7 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleDemoteSubmit() {
|
||||
handleDemoteSubmit = () => {
|
||||
if (this.state.role === 'member') {
|
||||
this.doMakeMember();
|
||||
}
|
||||
@@ -147,13 +133,13 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleShowDeactivateMemberModal(e) {
|
||||
handleShowDeactivateMemberModal = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({showDeactivateMemberModal: true});
|
||||
}
|
||||
|
||||
handleDeactivateMember() {
|
||||
handleDeactivateMember = () => {
|
||||
updateActive(this.props.user.id, false, null,
|
||||
(err) => {
|
||||
this.setState({serverError: err.message});
|
||||
@@ -163,11 +149,11 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
this.setState({showDeactivateMemberModal: false});
|
||||
}
|
||||
|
||||
handleDeactivateCancel() {
|
||||
handleDeactivateCancel = () => {
|
||||
this.setState({showDeactivateMemberModal: false});
|
||||
}
|
||||
|
||||
renderDeactivateMemberModal() {
|
||||
renderDeactivateMemberModal = () => {
|
||||
const title = (
|
||||
<FormattedMessage
|
||||
id='deactivate_member_modal.title'
|
||||
@@ -240,8 +226,6 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
}
|
||||
|
||||
const me = UserStore.getCurrentUser();
|
||||
let showMakeMember = Utils.isSystemAdmin(user.roles);
|
||||
let showMakeSystemAdmin = !Utils.isSystemAdmin(user.roles);
|
||||
let showMakeActive = false;
|
||||
let showMakeNotActive = !Utils.isSystemAdmin(user.roles);
|
||||
let showManageTeams = true;
|
||||
@@ -255,8 +239,6 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
defaultMessage='Inactive'
|
||||
/>
|
||||
);
|
||||
showMakeMember = false;
|
||||
showMakeSystemAdmin = false;
|
||||
showMakeActive = true;
|
||||
showMakeNotActive = false;
|
||||
showManageTeams = false;
|
||||
@@ -267,44 +249,6 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
disableActivationToggle = true;
|
||||
}
|
||||
|
||||
let makeSystemAdmin = null;
|
||||
if (showMakeSystemAdmin) {
|
||||
makeSystemAdmin = (
|
||||
<li role='presentation'>
|
||||
<a
|
||||
id='makeSystemAdmin'
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.handleMakeSystemAdmin}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.user_item.makeSysAdmin'
|
||||
defaultMessage='Make System Admin'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
let makeMember = null;
|
||||
if (showMakeMember) {
|
||||
makeMember = (
|
||||
<li role='presentation'>
|
||||
<a
|
||||
id='makeMember'
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.handleMakeMember}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.user_item.makeMember'
|
||||
defaultMessage='Make Member'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
let menuClass = '';
|
||||
if (disableActivationToggle) {
|
||||
menuClass = 'disabled';
|
||||
@@ -427,6 +371,25 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let manageTokens;
|
||||
if (global.window.mm_config.EnableUserAccessTokens === 'true') {
|
||||
manageTokens = (
|
||||
<li role='presentation'>
|
||||
<a
|
||||
id='manageTokens'
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.handleManageTokens}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.user_item.manageTokens'
|
||||
defaultMessage='Manage Tokens'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
let makeDemoteModal = null;
|
||||
if (this.props.user.id === me.id) {
|
||||
const title = (
|
||||
@@ -498,11 +461,23 @@ export default class SystemUsersDropdown extends React.Component {
|
||||
className='dropdown-menu member-menu'
|
||||
role='menu'
|
||||
>
|
||||
{makeMember}
|
||||
{makeActive}
|
||||
{makeNotActive}
|
||||
{makeSystemAdmin}
|
||||
<li role='presentation'>
|
||||
<a
|
||||
id='manageRoles'
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.handleManageRoles}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.user_item.manageRoles'
|
||||
defaultMessage='Manage Roles'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
{manageTeams}
|
||||
{manageTokens}
|
||||
{mfaReset}
|
||||
{passwordReset}
|
||||
</ul>
|
||||
|
||||
@@ -6,6 +6,8 @@ import PropTypes from 'prop-types';
|
||||
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
||||
|
||||
import ManageTeamsModal from 'components/admin_console/manage_teams_modal/manage_teams_modal.jsx';
|
||||
import ManageRolesModal from 'components/admin_console/manage_roles_modal';
|
||||
import ManageTokensModal from 'components/admin_console/manage_tokens_modal';
|
||||
import ResetPasswordModal from 'components/admin_console/reset_password_modal.jsx';
|
||||
import SearchableUserList from 'components/searchable_user_list/searchable_user_list.jsx';
|
||||
|
||||
@@ -14,6 +16,7 @@ const dispatch = store.dispatch;
|
||||
const getState = store.getState;
|
||||
|
||||
import {getUser} from 'mattermost-redux/actions/users';
|
||||
import * as UserUtils from 'mattermost-redux/utils/user_utils';
|
||||
import {Constants} from 'utils/constants.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
|
||||
@@ -37,21 +40,12 @@ export default class SystemUsersList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.nextPage = this.nextPage.bind(this);
|
||||
this.previousPage = this.previousPage.bind(this);
|
||||
this.search = this.search.bind(this);
|
||||
|
||||
this.doManageTeams = this.doManageTeams.bind(this);
|
||||
this.doManageTeamsDismiss = this.doManageTeamsDismiss.bind(this);
|
||||
|
||||
this.doPasswordReset = this.doPasswordReset.bind(this);
|
||||
this.doPasswordResetDismiss = this.doPasswordResetDismiss.bind(this);
|
||||
this.doPasswordResetSubmit = this.doPasswordResetSubmit.bind(this);
|
||||
|
||||
this.state = {
|
||||
page: 0,
|
||||
|
||||
showManageTeamsModal: false,
|
||||
showManageRolesModal: false,
|
||||
showManageTokensModal: false,
|
||||
showPasswordModal: false,
|
||||
user: null
|
||||
};
|
||||
@@ -63,17 +57,17 @@ export default class SystemUsersList extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
nextPage() {
|
||||
nextPage = () => {
|
||||
this.setState({page: this.state.page + 1});
|
||||
|
||||
this.props.nextPage(this.state.page + 1);
|
||||
}
|
||||
|
||||
previousPage() {
|
||||
previousPage = () => {
|
||||
this.setState({page: this.state.page - 1});
|
||||
}
|
||||
|
||||
search(term) {
|
||||
search = (term) => {
|
||||
this.props.search(term);
|
||||
|
||||
if (term !== '') {
|
||||
@@ -81,35 +75,63 @@ export default class SystemUsersList extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
doManageTeams(user) {
|
||||
doManageTeams = (user) => {
|
||||
this.setState({
|
||||
showManageTeamsModal: true,
|
||||
user
|
||||
});
|
||||
}
|
||||
|
||||
doManageTeamsDismiss() {
|
||||
doManageRoles = (user) => {
|
||||
this.setState({
|
||||
showManageRolesModal: true,
|
||||
user
|
||||
});
|
||||
}
|
||||
|
||||
doManageTokens = (user) => {
|
||||
this.setState({
|
||||
showManageTokensModal: true,
|
||||
user
|
||||
});
|
||||
}
|
||||
|
||||
doManageTeamsDismiss = () => {
|
||||
this.setState({
|
||||
showManageTeamsModal: false,
|
||||
user: null
|
||||
});
|
||||
}
|
||||
|
||||
doPasswordReset(user) {
|
||||
doManageRolesDismiss = () => {
|
||||
this.setState({
|
||||
showManageRolesModal: false,
|
||||
user: null
|
||||
});
|
||||
}
|
||||
|
||||
doManageTokensDismiss = () => {
|
||||
this.setState({
|
||||
showManageTokensModal: false,
|
||||
user: null
|
||||
});
|
||||
}
|
||||
|
||||
doPasswordReset = (user) => {
|
||||
this.setState({
|
||||
showPasswordModal: true,
|
||||
user
|
||||
});
|
||||
}
|
||||
|
||||
doPasswordResetDismiss() {
|
||||
doPasswordResetDismiss = () => {
|
||||
this.setState({
|
||||
showPasswordModal: false,
|
||||
user: null
|
||||
});
|
||||
}
|
||||
|
||||
doPasswordResetSubmit(user) {
|
||||
doPasswordResetSubmit = (user) => {
|
||||
getUser(user.id)(dispatch, getState);
|
||||
|
||||
this.setState({
|
||||
@@ -174,6 +196,35 @@ export default class SystemUsersList extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const userAccessTokensEnabled = global.window.mm_config.EnableUserAccessTokens === 'true';
|
||||
if (userAccessTokensEnabled) {
|
||||
const hasPostAllRole = UserUtils.hasPostAllRole(user.roles);
|
||||
const hasPostAllPublicRole = UserUtils.hasPostAllPublicRole(user.roles);
|
||||
const hasUserAccessTokenRole = UserUtils.hasUserAccessTokenRole(user.roles);
|
||||
const isSystemAdmin = UserUtils.isSystemAdmin(user.roles);
|
||||
|
||||
let messageId = 'admin.user_item.userAccessTokenNo';
|
||||
if (hasUserAccessTokenRole || isSystemAdmin) {
|
||||
if (isSystemAdmin) {
|
||||
messageId = 'admin.user_item.userAccessTokenAdmin';
|
||||
} else if (hasPostAllRole) {
|
||||
messageId = 'admin.user_item.userAccessTokenPostAll';
|
||||
} else if (hasPostAllPublicRole) {
|
||||
messageId = 'admin.user_item.userAccessTokenPostAllPublic';
|
||||
} else {
|
||||
messageId = 'admin.user_item.userAccessTokenYes';
|
||||
}
|
||||
}
|
||||
|
||||
info.push(', ');
|
||||
info.push(
|
||||
<FormattedHTMLMessage
|
||||
key='admin.user_item.userAccessToken'
|
||||
id={messageId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -236,7 +287,9 @@ export default class SystemUsersList extends React.Component {
|
||||
actions={[SystemUsersDropdown]}
|
||||
actionProps={{
|
||||
doPasswordReset: this.doPasswordReset,
|
||||
doManageTeams: this.doManageTeams
|
||||
doManageTeams: this.doManageTeams,
|
||||
doManageRoles: this.doManageRoles,
|
||||
doManageTokens: this.doManageTokens
|
||||
}}
|
||||
nextPage={this.nextPage}
|
||||
previousPage={this.previousPage}
|
||||
@@ -250,6 +303,16 @@ export default class SystemUsersList extends React.Component {
|
||||
show={this.state.showManageTeamsModal}
|
||||
onModalDismissed={this.doManageTeamsDismiss}
|
||||
/>
|
||||
<ManageRolesModal
|
||||
user={this.state.user}
|
||||
show={this.state.showManageRolesModal}
|
||||
onModalDismissed={this.doManageRolesDismiss}
|
||||
/>
|
||||
<ManageTokensModal
|
||||
user={this.state.user}
|
||||
show={this.state.showManageTokensModal}
|
||||
onModalDismissed={this.doManageTokensDismiss}
|
||||
/>
|
||||
<ResetPasswordModal
|
||||
user={this.state.user}
|
||||
show={this.state.showPasswordModal}
|
||||
|
||||
Ссылка в новой задаче
Block a user