PLT-2697 Fixing team admins (#2900)
* PLT-2697 Fixing team admins * Fixing eslint error * Fixing loc issues * Fixing func * Fixing func
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
4f799b980f
Коммит
6c75662b82
@@ -89,7 +89,7 @@ func (me *TestHelper) InitSystemAdmin() *TestHelper {
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, me.SystemAdminUser, model.ROLE_SYSTEM_ADMIN)
|
||||
UpdateUserRoles(c, me.SystemAdminUser, model.ROLE_SYSTEM_ADMIN)
|
||||
me.SystemAdminUser.Password = "Password1"
|
||||
me.LoginSystemAdmin()
|
||||
me.SystemAdminChannel = me.CreateChannel(me.SystemAdminClient, me.SystemAdminTeam)
|
||||
|
||||
@@ -372,12 +372,12 @@ func (c *Context) IsTeamAdmin() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
team := c.Session.GetTeamByTeamId(c.TeamId)
|
||||
if team == nil {
|
||||
teamMember := c.Session.GetTeamByTeamId(c.TeamId)
|
||||
if teamMember == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return model.IsInRole(team.Roles, model.ROLE_TEAM_ADMIN)
|
||||
return teamMember.IsTeamAdmin()
|
||||
}
|
||||
|
||||
func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -252,7 +252,7 @@ func TestGetAllTeams(t *testing.T) {
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
UpdateUserRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.Login(user.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
@@ -301,7 +301,7 @@ func TestGetAllTeamListings(t *testing.T) {
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
UpdateUserRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.Login(user.Email, "pwd")
|
||||
Client.SetTeamId(team.Id)
|
||||
|
||||
97
api/user.go
97
api/user.go
@@ -1372,16 +1372,23 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
team_id := props["team_id"]
|
||||
if !(len(user_id) == 26 || len(user_id) == 0) {
|
||||
c.SetInvalidParam("updateRoles", "team_id")
|
||||
return
|
||||
}
|
||||
|
||||
new_roles := props["new_roles"]
|
||||
if !model.IsValidUserRoles(new_roles) {
|
||||
if !(model.IsValidUserRoles(new_roles) || model.IsValidTeamRoles(new_roles)) {
|
||||
c.SetInvalidParam("updateRoles", "new_roles")
|
||||
return
|
||||
}
|
||||
|
||||
// If you are not the system admin then you can only demote yourself
|
||||
if !c.IsSystemAdmin() && user_id != c.Session.UserId {
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_set.app_error", nil, "")
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_needed.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
// Only another system admin can add the system admin role
|
||||
@@ -1399,36 +1406,78 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
user = result.Data.(*model.User)
|
||||
}
|
||||
|
||||
ruser := UpdateRoles(c, user, new_roles)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
// if the team role has changed then lets update team members
|
||||
if model.IsValidTeamRoles(new_roles) && len(team_id) > 0 {
|
||||
|
||||
uchan := Srv.Store.Session().UpdateRoles(user.Id, new_roles)
|
||||
gchan := Srv.Store.Session().GetSessions(user.Id)
|
||||
var members []*model.TeamMember
|
||||
if result := <-Srv.Store.Team().GetTeamsForUser(user_id); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
members = result.Data.([]*model.TeamMember)
|
||||
}
|
||||
|
||||
if result := <-uchan; result.Err != nil {
|
||||
// soft error since the user roles were still updated
|
||||
l4g.Error(result.Err)
|
||||
}
|
||||
var member *model.TeamMember
|
||||
for _, m := range members {
|
||||
if m.TeamId == team_id {
|
||||
member = m
|
||||
}
|
||||
}
|
||||
|
||||
if result := <-gchan; result.Err != nil {
|
||||
// soft error since the user roles were still updated
|
||||
l4g.Error(result.Err)
|
||||
} else {
|
||||
sessions := result.Data.([]*model.Session)
|
||||
for _, s := range sessions {
|
||||
sessionCache.Remove(s.Token)
|
||||
if member == nil {
|
||||
c.SetInvalidParam("updateRoles", "team_id")
|
||||
return
|
||||
}
|
||||
|
||||
if !c.IsSystemAdmin() {
|
||||
currentUserTeamMember := c.Session.GetTeamByTeamId(team_id)
|
||||
|
||||
// Only the system admin can modify other team
|
||||
if currentUserTeamMember == nil {
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_needed.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
|
||||
// Only another team admin can make a team admin
|
||||
if !currentUserTeamMember.IsTeamAdmin() && model.IsInRole(new_roles, model.ROLE_TEAM_ADMIN) {
|
||||
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.team_admin_needed.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusForbidden
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
member.Roles = new_roles
|
||||
|
||||
if result := <-Srv.Store.Team().UpdateMember(member); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
options := utils.Cfg.GetSanitizeOptions()
|
||||
options["passwordupdate"] = false
|
||||
ruser.Sanitize(options)
|
||||
w.Write([]byte(ruser.ToJson()))
|
||||
// If the users role has changed then lets update the user
|
||||
if model.IsValidUserRoles(new_roles) {
|
||||
UpdateUserRoles(c, user, new_roles)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uchan := Srv.Store.Session().UpdateRoles(user.Id, new_roles)
|
||||
|
||||
if result := <-uchan; result.Err != nil {
|
||||
// soft error since the user roles were still updated
|
||||
l4g.Error(result.Err)
|
||||
}
|
||||
}
|
||||
|
||||
RemoveAllSessionsForUserId(user_id)
|
||||
|
||||
data := make(map[string]string)
|
||||
data["user_id"] = user_id
|
||||
w.Write([]byte(model.MapToJson(data)))
|
||||
}
|
||||
|
||||
func UpdateRoles(c *Context, user *model.User, roles string) *model.User {
|
||||
func UpdateUserRoles(c *Context, user *model.User, roles string) *model.User {
|
||||
|
||||
user.Roles = roles
|
||||
|
||||
|
||||
132
api/user_test.go
132
api/user_test.go
@@ -366,7 +366,7 @@ func TestGetUser(t *testing.T) {
|
||||
c := &Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
UpdateRoles(c, ruser.Data.(*model.User), model.ROLE_SYSTEM_ADMIN)
|
||||
UpdateUserRoles(c, ruser.Data.(*model.User), model.ROLE_SYSTEM_ADMIN)
|
||||
|
||||
Client.Login(user.Email, "pwd")
|
||||
|
||||
@@ -791,7 +791,6 @@ func TestUserUpdateRoles(t *testing.T) {
|
||||
Client.Login(user.Email, "pwd")
|
||||
|
||||
data["user_id"] = "junk"
|
||||
data["new_roles"] = "admin"
|
||||
|
||||
if _, err := Client.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, bad id")
|
||||
@@ -804,12 +803,141 @@ func TestUserUpdateRoles(t *testing.T) {
|
||||
}
|
||||
|
||||
data["user_id"] = user2.Id
|
||||
data["new_roles"] = "junk"
|
||||
|
||||
if _, err := Client.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, bad role")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserUpdateRolesMoreCases(t *testing.T) {
|
||||
th := Setup().InitSystemAdmin().InitBasic()
|
||||
|
||||
data := make(map[string]string)
|
||||
|
||||
// invalid team Id
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = model.NewId()
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored")
|
||||
}
|
||||
|
||||
// user 1 is trying to change user 2
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, you can only demote yourself")
|
||||
}
|
||||
|
||||
// user 1 is trying to promote user 2
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = model.ROLE_TEAM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, you can only demote yourself")
|
||||
}
|
||||
|
||||
// user 1 is trying to promote user 2
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = model.ROLE_SYSTEM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, you can only demote yourself")
|
||||
}
|
||||
|
||||
// user 1 is trying to promote himself
|
||||
data["user_id"] = th.BasicUser.Id
|
||||
data["new_roles"] = model.ROLE_TEAM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, you cannot elevate your permissions")
|
||||
}
|
||||
|
||||
// user 1 is trying to promote himself
|
||||
data["user_id"] = th.BasicUser.Id
|
||||
data["new_roles"] = model.ROLE_SYSTEM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, you cannot elevate your permissions")
|
||||
}
|
||||
|
||||
th.LoginSystemAdmin()
|
||||
|
||||
// promote user to team admin
|
||||
data["user_id"] = th.BasicUser.Id
|
||||
data["new_roles"] = model.ROLE_TEAM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.SystemAdminClient.UpdateUserRoles(data); err != nil {
|
||||
t.Fatal("Should have succeeded since they are system admin")
|
||||
}
|
||||
|
||||
// demote team admin to basic member
|
||||
data["user_id"] = th.BasicUser.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.SystemAdminClient.UpdateUserRoles(data); err != nil {
|
||||
t.Fatal("Should have succeeded since they are system admin")
|
||||
}
|
||||
|
||||
// re-promote user to team admin
|
||||
data["user_id"] = th.BasicUser.Id
|
||||
data["new_roles"] = model.ROLE_TEAM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.SystemAdminClient.UpdateUserRoles(data); err != nil {
|
||||
t.Fatal("Should have succeeded since they are system admin")
|
||||
}
|
||||
|
||||
// user 1 is promoting user 2 to team admin
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = model.ROLE_TEAM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have succeeded since they are team admin")
|
||||
}
|
||||
|
||||
// user 1 is trying to promote user 2 from team admin to system admin
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = model.ROLE_SYSTEM_ADMIN
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, can only be system admin")
|
||||
}
|
||||
|
||||
// user 1 is demoting user 2 to a regular member
|
||||
data["user_id"] = th.BasicUser2.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have succeeded since they are team admin")
|
||||
}
|
||||
|
||||
// user 1 is trying to demote system admin
|
||||
data["user_id"] = th.SystemAdminUser.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
|
||||
t.Fatal("Should have errored, can only be system admin")
|
||||
}
|
||||
|
||||
// user 1 as team admin is demoting himself
|
||||
data["user_id"] = th.BasicUser.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = th.BasicTeam.Id
|
||||
if _, err := th.BasicClient.UpdateUserRoles(data); err != nil {
|
||||
t.Fatal("Should have succeeded")
|
||||
}
|
||||
|
||||
// system admin demoting himself
|
||||
data["user_id"] = th.SystemAdminUser.Id
|
||||
data["new_roles"] = ""
|
||||
data["team_id"] = ""
|
||||
if _, err := th.SystemAdminClient.UpdateUserRoles(data); err != nil {
|
||||
t.Fatal("Should have succeeded since they are system admin")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserUpdateDeviceId(t *testing.T) {
|
||||
th := Setup()
|
||||
Client := th.CreateClient()
|
||||
|
||||
@@ -156,4 +156,4 @@
|
||||
"Directory": "./data/",
|
||||
"EnableDaily": false
|
||||
}
|
||||
}
|
||||
}
|
||||
12
i18n/en.json
12
i18n/en.json
@@ -1703,14 +1703,18 @@
|
||||
"id": "api.user.update_roles.permissions.app_error",
|
||||
"translation": "You do not have the appropriate permissions"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_mod.app_error",
|
||||
"translation": "The system admin role can only by modified by another system admin"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_set.app_error",
|
||||
"translation": "The system admin role can only be set by another system admin"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_needed.app_error",
|
||||
"translation": "The system admin role is needed for this action"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.team_admin_needed.app_error",
|
||||
"translation": "The team admin role is needed for this action"
|
||||
},
|
||||
{
|
||||
"id": "api.user.upload_profile_user.array.app_error",
|
||||
"translation": "Empty array under 'image' in request"
|
||||
|
||||
@@ -1703,10 +1703,6 @@
|
||||
"id": "api.user.update_roles.permissions.app_error",
|
||||
"translation": "No tienes los permisos apropiados"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_mod.app_error",
|
||||
"translation": "El rol de administrador de sistema sólo puede ser modificado por otro administrador de sistema"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_set.app_error",
|
||||
"translation": "El rol de adminsitrador de sistema sólo puede ser asignado por otro administrador de sistema"
|
||||
|
||||
@@ -1563,10 +1563,6 @@
|
||||
"id": "api.user.update_roles.permissions.app_error",
|
||||
"translation": "Vous n'avez pas les permissions appropriées"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_mod.app_error",
|
||||
"translation": "Le rôle d'administrateur système ne peut être modifié que par un autre administrateur système"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_set.app_error",
|
||||
"translation": "Le rôle d'administrateur système ne peut être donné que par un autre administrateur système"
|
||||
|
||||
@@ -1675,10 +1675,6 @@
|
||||
"id": "api.user.update_roles.permissions.app_error",
|
||||
"translation": "あなたには必要な権限が付与されていません"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_mod.app_error",
|
||||
"translation": "システム管理者の役割は、他のシステム管理者だけが設定変更できます"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_set.app_error",
|
||||
"translation": "システム管理者の役割は、他のシステム管理者だけが設定できます"
|
||||
|
||||
@@ -1699,10 +1699,6 @@
|
||||
"id": "api.user.update_roles.permissions.app_error",
|
||||
"translation": "Você não tem a permissão apropriada"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_mod.app_error",
|
||||
"translation": "A função de administrador do sistema só pode ser modificado por outro administrador do sistema"
|
||||
},
|
||||
{
|
||||
"id": "api.user.update_roles.system_admin_set.app_error",
|
||||
"translation": "A função de administrador do sistema só pode ser definida por um outro administrador do sistema"
|
||||
|
||||
@@ -721,7 +721,7 @@ func cmdAssignRole() {
|
||||
}
|
||||
|
||||
if !user.IsInRole(flagRole) {
|
||||
api.UpdateRoles(c, user, flagRole)
|
||||
api.UpdateUserRoles(c, user, flagRole)
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
|
||||
@@ -1023,7 +1023,7 @@ func (c *Client) UpdateUserRoles(data map[string]string) (*Result, *AppError) {
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,7 +1069,7 @@ func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string)
|
||||
return nil, err
|
||||
} else {
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil
|
||||
r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,48 @@ func TeamMembersFromJson(data io.Reader) []*TeamMember {
|
||||
}
|
||||
}
|
||||
|
||||
func IsValidTeamRoles(teamRoles string) bool {
|
||||
|
||||
roles := strings.Split(teamRoles, " ")
|
||||
|
||||
for _, r := range roles {
|
||||
if !isValidTeamRole(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func isValidTeamRole(role string) bool {
|
||||
if role == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
if role == ROLE_TEAM_ADMIN {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsInTeamRole(teamRoles string, inRole string) bool {
|
||||
roles := strings.Split(teamRoles, " ")
|
||||
|
||||
for _, r := range roles {
|
||||
if r == inRole {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *TeamMember) IsTeamAdmin() bool {
|
||||
return IsInTeamRole(o.Roles, ROLE_TEAM_ADMIN)
|
||||
}
|
||||
|
||||
func (o *TeamMember) IsValid() *AppError {
|
||||
|
||||
if len(o.TeamId) != 26 {
|
||||
|
||||
@@ -203,7 +203,7 @@ func TestIncomingWebhook(t *testing.T) {
|
||||
c := &api.Context{}
|
||||
c.RequestId = model.NewId()
|
||||
c.IpAddress = "cmd_line"
|
||||
api.UpdateRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
api.UpdateUserRoles(c, user, model.ROLE_SYSTEM_ADMIN)
|
||||
ApiClient.Login(user.Email, "pwd")
|
||||
ApiClient.SetTeamId(team.Id)
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
||||
}
|
||||
|
||||
if (this.state.users == null) {
|
||||
if (this.state.users == null || this.state.teamMembers == null) {
|
||||
return (
|
||||
<div className='wrapper--fixed'>
|
||||
<h3>
|
||||
@@ -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 (
|
||||
<UserItem
|
||||
team={this.props.team}
|
||||
key={'user_' + user.id}
|
||||
user={user}
|
||||
teamMember={teamMember}
|
||||
refreshProfiles={this.getCurrentTeamProfiles}
|
||||
doPasswordReset={this.doPasswordReset}
|
||||
/>);
|
||||
|
||||
@@ -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 = (
|
||||
<FormattedMessage
|
||||
@@ -192,32 +199,28 @@ export default class UserItem extends React.Component {
|
||||
defaultMessage='Member'
|
||||
/>
|
||||
);
|
||||
if (user.roles.length > 0) {
|
||||
if (Utils.isSystemAdmin(user.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='admin.user_item.sysAdmin'
|
||||
defaultMessage='System Admin'
|
||||
/>
|
||||
);
|
||||
} else if (Utils.isAdmin(user.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='admin.user_item.teamAdmin'
|
||||
defaultMessage='Team Admin'
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
currentRoles = user.roles.charAt(0).toUpperCase() + user.roles.slice(1);
|
||||
}
|
||||
|
||||
if (teamMember.roles.length > 0 && Utils.isAdmin(teamMember.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.teamAdmin'
|
||||
defaultMessage='Team Admin'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (user.roles.length > 0 && Utils.isSystemAdmin(user.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.systemAdmin'
|
||||
defaultMessage='System Admin'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const email = user.email;
|
||||
let showMakeMember = user.roles === 'admin' || user.roles === 'system_admin';
|
||||
|
||||
//let showMakeAdmin = user.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 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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -452,7 +452,8 @@ export default class Navbar extends React.Component {
|
||||
/>
|
||||
</Popover>
|
||||
);
|
||||
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;
|
||||
|
||||
@@ -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 = (
|
||||
<li>
|
||||
|
||||
@@ -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 '';
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 = (
|
||||
<li>
|
||||
|
||||
@@ -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 = (
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.systemAdmin'
|
||||
defaultMessage='System Admin'
|
||||
/>
|
||||
);
|
||||
} else if (Utils.isAdmin(user.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.teamAdmin'
|
||||
defaultMessage='Team Admin'
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
currentRoles = user.roles.charAt(0).toUpperCase() + user.roles.slice(1);
|
||||
}
|
||||
if (teamMember.roles.length > 0 && Utils.isAdmin(teamMember.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.teamAdmin'
|
||||
defaultMessage='Team Admin'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (user.roles.length > 0 && Utils.isSystemAdmin(user.roles)) {
|
||||
currentRoles = (
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.systemAdmin'
|
||||
defaultMessage='System Admin'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let showMakeMember = teamMember.roles === 'admin' || user.roles === 'system_admin';
|
||||
|
||||
//let showMakeAdmin = teamMember.roles === '' && user.roles !== 'system_admin';
|
||||
let showMakeAdmin = false;
|
||||
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 = (
|
||||
<li role='presentation'>
|
||||
<a
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.handleMakeActive}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.makeActive'
|
||||
defaultMessage='Make Active'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
// makeActive = (
|
||||
// <li role='presentation'>
|
||||
// <a
|
||||
// role='menuitem'
|
||||
// href='#'
|
||||
// onClick={this.handleMakeActive}
|
||||
// >
|
||||
// <FormattedMessage
|
||||
// id='team_members_dropdown.makeActive'
|
||||
// defaultMessage='Make Active'
|
||||
// />
|
||||
// </a>
|
||||
// </li>
|
||||
// );
|
||||
}
|
||||
|
||||
let makeNotActive = null;
|
||||
if (showMakeNotActive) {
|
||||
makeNotActive = (
|
||||
<li role='presentation'>
|
||||
<a
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={this.handleMakeNotActive}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='team_members_dropdown.makeInactive'
|
||||
defaultMessage='Make Inactive'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
// makeNotActive = (
|
||||
// <li role='presentation'>
|
||||
// <a
|
||||
// role='menuitem'
|
||||
// href='#'
|
||||
// onClick={this.handleMakeNotActive}
|
||||
// >
|
||||
// <FormattedMessage
|
||||
// id='team_members_dropdown.makeInactive'
|
||||
// defaultMessage='Make Inactive'
|
||||
// />
|
||||
// </a>
|
||||
// </li>
|
||||
// );
|
||||
}
|
||||
const me = UserStore.getCurrentUser();
|
||||
let makeDemoteModal = null;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Ссылка в новой задаче
Block a user