From 6c75662b824491a20a757a5eec59556a866374b5 Mon Sep 17 00:00:00 2001 From: Corey Hulen Date: Fri, 6 May 2016 11:28:22 -0700 Subject: PLT-2697 Fixing team admins (#2900) * PLT-2697 Fixing team admins * Fixing eslint error * Fixing loc issues * Fixing func * Fixing func --- webapp/client/client.jsx | 3 +- webapp/components/admin_console/team_users.jsx | 39 +++++++++- webapp/components/admin_console/user_item.jsx | 51 ++++++------ webapp/components/audit_table.jsx | 2 +- webapp/components/channel_header.jsx | 3 +- webapp/components/navbar.jsx | 3 +- webapp/components/navbar_dropdown.jsx | 5 +- webapp/components/post_info.jsx | 4 +- webapp/components/rhs_comment.jsx | 4 +- webapp/components/rhs_root_post.jsx | 3 +- webapp/components/sidebar_right_menu.jsx | 5 +- webapp/components/team_members_dropdown.jsx | 104 +++++++++++++------------ webapp/stores/team_store.jsx | 17 ++++ webapp/stores/user_store.jsx | 16 ++++ webapp/tests/client_user.test.jsx | 4 +- 15 files changed, 178 insertions(+), 85 deletions(-) (limited to 'webapp') diff --git a/webapp/client/client.jsx b/webapp/client/client.jsx index 56eb4a137..d1e250e12 100644 --- a/webapp/client/client.jsx +++ b/webapp/client/client.jsx @@ -596,8 +596,9 @@ export default class Client { end(this.handleResponse.bind(this, 'updateUserNotifyProps', success, error)); } - updateRoles = (userId, newRoles, success, error) => { + updateRoles = (teamId, userId, newRoles, success, error) => { var data = { + team_id: teamId, user_id: userId, new_roles: newRoles }; diff --git a/webapp/components/admin_console/team_users.jsx b/webapp/components/admin_console/team_users.jsx index 2b0e6af0a..e41747737 100644 --- a/webapp/components/admin_console/team_users.jsx +++ b/webapp/components/admin_console/team_users.jsx @@ -19,10 +19,12 @@ export default class UserList extends React.Component { this.doPasswordReset = this.doPasswordReset.bind(this); this.doPasswordResetDismiss = this.doPasswordResetDismiss.bind(this); this.doPasswordResetSubmit = this.doPasswordResetSubmit.bind(this); + this.getTeamMemberForUser = this.getTeamMemberForUser.bind(this); this.state = { teamId: props.team.id, users: null, + teamMembers: null, serverError: null, showPasswordModal: false, user: null @@ -38,6 +40,21 @@ export default class UserList extends React.Component { } getTeamProfiles(teamId) { + Client.getTeamMembers( + teamId, + (data) => { + this.setState({ + teamMembers: data + }); + }, + (err) => { + this.setState({ + teamMembers: null, + serverError: err.message + }); + } + ); + Client.getProfilesForTeam( teamId, (users) => { @@ -110,6 +127,22 @@ export default class UserList extends React.Component { }); } + getTeamMemberForUser(userId) { + if (this.state.teamMembers) { + for (const index in this.state.teamMembers) { + if (this.state.teamMembers.hasOwnProperty(index)) { + var teamMember = this.state.teamMembers[index]; + + if (teamMember.user_id === userId) { + return teamMember; + } + } + } + } + + return null; + } + componentWillReceiveProps(newProps) { this.getTeamProfiles(newProps.team.id); } @@ -120,7 +153,7 @@ export default class UserList extends React.Component { serverError =
; } - if (this.state.users == null) { + if (this.state.users == null || this.state.teamMembers == null) { return (

@@ -139,10 +172,14 @@ export default class UserList extends React.Component { } var memberList = this.state.users.map((user) => { + var teamMember = this.getTeamMemberForUser(user.id); + return ( ); diff --git a/webapp/components/admin_console/user_item.jsx b/webapp/components/admin_console/user_item.jsx index 660f75a41..ef6bd9f45 100644 --- a/webapp/components/admin_console/user_item.jsx +++ b/webapp/components/admin_console/user_item.jsx @@ -42,6 +42,7 @@ export default class UserItem extends React.Component { this.handleDemote(this.props.user, ''); } else { Client.updateRoles( + this.props.team.id, this.props.user.id, '', () => { @@ -85,6 +86,7 @@ export default class UserItem extends React.Component { this.handleDemote(this.props.user, 'admin'); } else { Client.updateRoles( + this.props.team.id, this.props.user.id, 'admin', () => { @@ -101,6 +103,7 @@ export default class UserItem extends React.Component { e.preventDefault(); Client.updateRoles( + this.props.team.id, this.props.user.id, 'system_admin', () => { @@ -150,9 +153,12 @@ export default class UserItem extends React.Component { handleDemoteSubmit() { Client.updateRoles( + this.props.team.id, this.props.user.id, this.state.role, () => { + this.props.refreshProfiles(); + this.setState({ serverError: null, showDemoteModal: false, @@ -185,6 +191,7 @@ export default class UserItem extends React.Component { ); } + const teamMember = this.props.teamMember; const user = this.props.user; let currentRoles = ( ); - if (user.roles.length > 0) { - if (Utils.isSystemAdmin(user.roles)) { - currentRoles = ( - - ); - } else if (Utils.isAdmin(user.roles)) { - currentRoles = ( - - ); - } else { - currentRoles = user.roles.charAt(0).toUpperCase() + user.roles.slice(1); - } - } - const email = user.email; - let showMakeMember = user.roles === 'admin' || user.roles === 'system_admin'; + if (teamMember.roles.length > 0 && Utils.isAdmin(teamMember.roles)) { + currentRoles = ( + + ); + } - //let showMakeAdmin = user.roles === '' || user.roles === 'system_admin'; - let showMakeAdmin = false; + if (user.roles.length > 0 && Utils.isSystemAdmin(user.roles)) { + currentRoles = ( + + ); + } + const email = user.email; + let showMakeMember = teamMember.roles === 'admin' || user.roles === 'system_admin'; + let showMakeAdmin = teamMember.roles === '' && user.roles !== 'system_admin'; let showMakeSystemAdmin = user.roles === '' || user.roles === 'admin'; let showMakeActive = false; let showMakeNotActive = user.roles !== 'system_admin'; @@ -521,7 +524,9 @@ export default class UserItem extends React.Component { } UserItem.propTypes = { + team: React.PropTypes.object.isRequired, user: React.PropTypes.object.isRequired, + teamMember: React.PropTypes.object.isRequired, refreshProfiles: React.PropTypes.func.isRequired, doPasswordReset: React.PropTypes.func.isRequired }; diff --git a/webapp/components/audit_table.jsx b/webapp/components/audit_table.jsx index b1f155518..58b5b9af7 100644 --- a/webapp/components/audit_table.jsx +++ b/webapp/components/audit_table.jsx @@ -494,7 +494,7 @@ export function formatAuditInfo(audit, formatMessage) { if (actingUserInfo[0] === 'session_user') { const actingUser = UserStore.getProfile(actingUserInfo[1]); const user = UserStore.getCurrentUser(); - if (user && actingUser && (Utils.isAdmin(user.roles) || Utils.isSystemAdmin(user.roles))) { + if (user && actingUser && (Utils.isSystemAdmin(user.roles))) { auditDesc += formatMessage(holders.by, {username: actingUser.username}); } else if (user && actingUser) { auditDesc += formatMessage(holders.byAdmin); diff --git a/webapp/components/channel_header.jsx b/webapp/components/channel_header.jsx index de6ee20c9..992244915 100644 --- a/webapp/components/channel_header.jsx +++ b/webapp/components/channel_header.jsx @@ -18,6 +18,7 @@ import ToggleModalButton from './toggle_modal_button.jsx'; import ChannelStore from 'stores/channel_store.jsx'; import UserStore from 'stores/user_store.jsx'; +import TeamStore from 'stores/team_store.jsx'; import SearchStore from 'stores/search_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; @@ -181,7 +182,7 @@ export default class ChannelHeader extends React.Component { ); let channelTitle = channel.display_name; const currentId = this.state.currentUser.id; - const isAdmin = Utils.isAdmin(this.state.memberChannel.roles) || Utils.isAdmin(this.state.currentUser.roles); + const isAdmin = Utils.isAdmin(this.state.memberChannel.roles) || TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); const isDirect = (this.state.channel.type === 'D'); if (isDirect) { diff --git a/webapp/components/navbar.jsx b/webapp/components/navbar.jsx index 919a72d0a..21ca53649 100644 --- a/webapp/components/navbar.jsx +++ b/webapp/components/navbar.jsx @@ -452,7 +452,8 @@ export default class Navbar extends React.Component { /> ); - isAdmin = Utils.isAdmin(this.state.member.roles); + + isAdmin = Utils.isAdmin(this.state.member.roles) || TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); if (channel.type === 'O') { channelTitle = channel.display_name; diff --git a/webapp/components/navbar_dropdown.jsx b/webapp/components/navbar_dropdown.jsx index 7004a0cf3..7f1cfce7c 100644 --- a/webapp/components/navbar_dropdown.jsx +++ b/webapp/components/navbar_dropdown.jsx @@ -7,6 +7,7 @@ import * as Utils from 'utils/utils.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; import TeamStore from 'stores/team_store.jsx'; +import UserStore from 'stores/user_store.jsx'; import AboutBuildModal from './about_build_modal.jsx'; import TeamMembersModal from './team_members_modal.jsx'; import ToggleModalButton from './toggle_modal_button.jsx'; @@ -79,8 +80,8 @@ export default class NavbarDropdown extends React.Component { let integrationsLink = null; if (currentUser != null) { - isAdmin = Utils.isAdmin(currentUser.roles); - isSystemAdmin = Utils.isSystemAdmin(currentUser.roles); + isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); + isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); inviteLink = (
  • diff --git a/webapp/components/post_info.jsx b/webapp/components/post_info.jsx index 3f81672e1..50b03c0be 100644 --- a/webapp/components/post_info.jsx +++ b/webapp/components/post_info.jsx @@ -5,6 +5,8 @@ import $ from 'jquery'; import * as Utils from 'utils/utils.jsx'; import TimeSince from './time_since.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; +import TeamStore from 'stores/team_store.jsx'; +import UserStore from 'stores/user_store.jsx'; import Constants from 'utils/constants.jsx'; @@ -30,7 +32,7 @@ export default class PostInfo extends React.Component { createDropdown() { var post = this.props.post; var isOwner = this.props.currentUser.id === post.user_id; - var isAdmin = Utils.isAdmin(this.props.currentUser.roles); + var isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); if (post.state === Constants.POST_FAILED || post.state === Constants.POST_LOADING || Utils.isPostEphemeral(post)) { return ''; diff --git a/webapp/components/rhs_comment.jsx b/webapp/components/rhs_comment.jsx index f21ae24e7..5097e0573 100644 --- a/webapp/components/rhs_comment.jsx +++ b/webapp/components/rhs_comment.jsx @@ -6,6 +6,8 @@ import FileAttachmentList from './file_attachment_list.jsx'; import PostStore from 'stores/post_store.jsx'; import ChannelStore from 'stores/channel_store.jsx'; +import TeamStore from 'stores/team_store.jsx'; +import UserStore from 'stores/user_store.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; @@ -82,7 +84,7 @@ export default class RhsComment extends React.Component { } const isOwner = this.props.currentUser.id === post.user_id; - const isAdmin = Utils.isAdmin(this.props.currentUser.roles); + var isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); var dropdownContents = []; diff --git a/webapp/components/rhs_root_post.jsx b/webapp/components/rhs_root_post.jsx index c771674a6..a9f6612dc 100644 --- a/webapp/components/rhs_root_post.jsx +++ b/webapp/components/rhs_root_post.jsx @@ -4,6 +4,7 @@ import ChannelStore from 'stores/channel_store.jsx'; import UserProfile from './user_profile.jsx'; import UserStore from 'stores/user_store.jsx'; +import TeamStore from 'stores/user_store.jsx'; import * as TextFormatting from 'utils/text_formatting.jsx'; import * as Utils from 'utils/utils.jsx'; import FileAttachmentList from './file_attachment_list.jsx'; @@ -39,7 +40,7 @@ export default class RhsRootPost extends React.Component { const post = this.props.post; const user = this.props.user; var isOwner = this.props.currentUser.id === post.user_id; - var isAdmin = Utils.isAdmin(this.props.currentUser.roles); + var isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); var timestamp = UserStore.getProfile(post.user_id).update_at; var channel = ChannelStore.get(post.channel_id); diff --git a/webapp/components/sidebar_right_menu.jsx b/webapp/components/sidebar_right_menu.jsx index a48dcade6..b36d84b79 100644 --- a/webapp/components/sidebar_right_menu.jsx +++ b/webapp/components/sidebar_right_menu.jsx @@ -7,6 +7,7 @@ import UserSettingsModal from './user_settings/user_settings_modal.jsx'; import AboutBuildModal from './about_build_modal.jsx'; import UserStore from 'stores/user_store.jsx'; +import TeamStore from 'stores/team_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; @@ -77,8 +78,8 @@ export default class SidebarRightMenu extends React.Component { var isSystemAdmin = false; if (currentUser != null) { - isAdmin = Utils.isAdmin(currentUser.roles); - isSystemAdmin = Utils.isSystemAdmin(currentUser.roles); + isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); + isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); inviteLink = (
  • diff --git a/webapp/components/team_members_dropdown.jsx b/webapp/components/team_members_dropdown.jsx index 251c2ce3b..b65b9e050 100644 --- a/webapp/components/team_members_dropdown.jsx +++ b/webapp/components/team_members_dropdown.jsx @@ -39,9 +39,11 @@ export default class TeamMembersDropdown extends React.Component { this.handleDemote(this.props.user, ''); } else { Client.updateRoles( + this.props.teamMember.team_id, this.props.user.id, '', () => { + AsyncClient.getTeamMembers(TeamStore.getCurrentId()); AsyncClient.getProfiles(); }, (err) => { @@ -53,6 +55,7 @@ export default class TeamMembersDropdown extends React.Component { handleMakeActive() { Client.updateActive(this.props.user.id, true, () => { + AsyncClient.getTeamMembers(TeamStore.getCurrentId()); AsyncClient.getProfiles(); AsyncClient.getChannelExtraInfo(ChannelStore.getCurrentId()); }, @@ -64,6 +67,7 @@ export default class TeamMembersDropdown extends React.Component { handleMakeNotActive() { Client.updateActive(this.props.user.id, false, () => { + AsyncClient.getTeamMembers(TeamStore.getCurrentId()); AsyncClient.getProfiles(); AsyncClient.getChannelExtraInfo(ChannelStore.getCurrentId()); }, @@ -78,9 +82,11 @@ export default class TeamMembersDropdown extends React.Component { this.handleDemote(this.props.user, 'admin'); } else { Client.updateRoles( + this.props.teamMember.team_id, this.props.user.id, 'admin', () => { + AsyncClient.getTeamMembers(TeamStore.getCurrentId()); AsyncClient.getProfiles(); }, (err) => { @@ -109,9 +115,13 @@ export default class TeamMembersDropdown extends React.Component { } handleDemoteSubmit() { Client.updateRoles( + this.props.teamMember.team_id, this.props.user.id, this.state.newRole, () => { + AsyncClient.getTeamMembers(TeamStore.getCurrentId()); + AsyncClient.getProfiles(); + const teamUrl = TeamStore.getCurrentTeamUrl(); if (teamUrl) { browserHistory.push(teamUrl); @@ -143,30 +153,26 @@ export default class TeamMembersDropdown extends React.Component { /> ); - if (user.roles.length > 0) { - if (Utils.isSystemAdmin(user.roles)) { - currentRoles = ( - - ); - } else if (Utils.isAdmin(user.roles)) { - currentRoles = ( - - ); - } else { - currentRoles = user.roles.charAt(0).toUpperCase() + user.roles.slice(1); - } + if (teamMember.roles.length > 0 && Utils.isAdmin(teamMember.roles)) { + currentRoles = ( + + ); } - let showMakeMember = teamMember.roles === 'admin' || user.roles === 'system_admin'; + if (user.roles.length > 0 && Utils.isSystemAdmin(user.roles)) { + currentRoles = ( + + ); + } - //let showMakeAdmin = teamMember.roles === '' && user.roles !== 'system_admin'; - let showMakeAdmin = false; + let showMakeMember = teamMember.roles === 'admin' || user.roles === 'system_admin'; + let showMakeAdmin = teamMember.roles === '' && user.roles !== 'system_admin'; let showMakeActive = false; let showMakeNotActive = user.roles !== 'system_admin'; @@ -221,38 +227,38 @@ export default class TeamMembersDropdown extends React.Component { let makeActive = null; if (showMakeActive) { - makeActive = ( -
  • - - - -
  • - ); + // makeActive = ( + //
  • + // + // + // + //
  • + // ); } let makeNotActive = null; if (showMakeNotActive) { - makeNotActive = ( -
  • - - - -
  • - ); + // makeNotActive = ( + //
  • + // + // + // + //
  • + // ); } const me = UserStore.getCurrentUser(); let makeDemoteModal = null; diff --git a/webapp/stores/team_store.jsx b/webapp/stores/team_store.jsx index 29e832633..8eebbaca5 100644 --- a/webapp/stores/team_store.jsx +++ b/webapp/stores/team_store.jsx @@ -3,6 +3,7 @@ import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import EventEmitter from 'events'; +import UserStore from 'stores/user_store.jsx'; import Constants from 'utils/constants.jsx'; const ActionTypes = Constants.ActionTypes; @@ -148,6 +149,22 @@ class TeamStoreClass extends EventEmitter { getTeamListings() { return this.teamListings; } + + isTeamAdminForCurrentTeam() { + if (!Utils) { + Utils = require('utils/utils.jsx'); //eslint-disable-line global-require + } + + const userId = UserStore.getCurrentId(); + var teamMembers = this.getTeamMembers(); + const teamMember = teamMembers.find((m) => m.user_id === userId && m.team_id === this.getCurrentId()); + + if (teamMember) { + return Utils.isAdmin(teamMember.roles); + } + + return false; + } } var TeamStore = new TeamStoreClass(); diff --git a/webapp/stores/user_store.jsx b/webapp/stores/user_store.jsx index 8ae1e1404..855222d47 100644 --- a/webapp/stores/user_store.jsx +++ b/webapp/stores/user_store.jsx @@ -13,6 +13,8 @@ const CHANGE_EVENT_SESSIONS = 'change_sessions'; const CHANGE_EVENT_AUDITS = 'change_audits'; const CHANGE_EVENT_STATUSES = 'change_statuses'; +var Utils; + class UserStoreClass extends EventEmitter { constructor() { super(); @@ -314,6 +316,20 @@ class UserStoreClass extends EventEmitter { setNoAccounts(noAccounts) { this.noAccounts = noAccounts; } + + isSystemAdminForCurrentUser() { + if (!Utils) { + Utils = require('utils/utils.jsx'); //eslint-disable-line global-require + } + + var current = this.getCurrentUser(); + + if (current) { + return Utils.isAdmin(current.roles); + } + + return false; + } } var UserStore = new UserStoreClass(); diff --git a/webapp/tests/client_user.test.jsx b/webapp/tests/client_user.test.jsx index 610308fa3..2b3b1b89a 100644 --- a/webapp/tests/client_user.test.jsx +++ b/webapp/tests/client_user.test.jsx @@ -206,12 +206,14 @@ describe('Client.User', function() { it('updateRoles', function(done) { TestHelper.initBasic(() => { var user = TestHelper.basicUser(); + var team = TestHelper.basicTeam(); TestHelper.basicClient().updateRoles( + team.id, user.id, '', function(data) { - assert.equal(data.roles, ''); + assert.equal(data.user_id, user.id); done(); }, function(err) { -- cgit v1.2.3-1-g7c22