func updateActive(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) user_id := props["user_id"] if len(user_id) != 26 { c.SetInvalidParam("updateActive", "user_id") return } active := props["active"] == "true" var user *model.User if result := <-Srv.Store.User().Get(user_id); result.Err != nil { c.Err = result.Err return } else { user = result.Data.(*model.User) } if !c.HasPermissionsToTeam(user.TeamId, "updateActive") { return } if !c.IsTeamAdmin() { c.Err = model.NewAppError("updateActive", "You do not have the appropriate permissions", "userId="+user_id) c.Err.StatusCode = http.StatusForbidden return } // make sure there is at least 1 other active admin if !active && model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) { if result := <-Srv.Store.User().GetProfiles(user.TeamId); result.Err != nil { c.Err = result.Err return } else { activeAdmins := -1 profileUsers := result.Data.(map[string]*model.User) for _, profileUser := range profileUsers { if profileUser.DeleteAt == 0 && model.IsInRole(profileUser.Roles, model.ROLE_TEAM_ADMIN) { activeAdmins = activeAdmins + 1 } } if activeAdmins <= 0 { c.Err = model.NewAppError("updateRoles", "There must be at least one active admin", "userId="+user_id) return } } } ruser := UpdateActive(c, user, active) if c.Err == nil { w.Write([]byte(ruser.ToJson())) } }
func updateTeamDisplayName(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) new_name := props["new_name"] if len(new_name) == 0 { c.SetInvalidParam("updateTeamDisplayName", "new_name") return } teamId := props["team_id"] if len(teamId) > 0 && len(teamId) != 26 { c.SetInvalidParam("updateTeamDisplayName", "team_id") return } else if len(teamId) == 0 { teamId = c.Session.TeamId } if !c.HasPermissionsToTeam(teamId, "updateTeamDisplayName") { return } if !model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) { c.Err = model.NewAppError("updateTeamDisplayName", "You do not have the appropriate permissions", "userId="+c.Session.UserId) c.Err.StatusCode = http.StatusForbidden return } if result := <-Srv.Store.Team().UpdateDisplayName(new_name, c.Session.TeamId); result.Err != nil { c.Err = result.Err return } w.Write([]byte(model.MapToJson(props))) }
func (c *Context) IsSystemAdmin() bool { // TODO XXX FIXME && IsPrivateIpAddress(c.IpAddress) if model.IsInRole(c.Session.Roles, model.ROLE_SYSTEM_ADMIN) { return true } return false }
func (c *Context) IsTeamAdmin(userId string) bool { if uresult := <-Srv.Store.User().Get(userId); uresult.Err != nil { c.Err = uresult.Err return false } else { user := uresult.Data.(*model.User) return model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) && user.TeamId == c.Session.TeamId } }
func InviteMembers(c *Context, team *model.Team, user *model.User, invites []string) { for _, invite := range invites { if len(invite) > 0 { sender := user.GetDisplayName() senderRole := "" if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) || model.IsInRole(user.Roles, model.ROLE_SYSTEM_ADMIN) { senderRole = "administrator" } else { senderRole = "member" } subjectPage := NewServerTemplatePage("invite_subject") subjectPage.Props["SiteURL"] = c.GetSiteURL() subjectPage.Props["SenderName"] = sender subjectPage.Props["TeamDisplayName"] = team.DisplayName bodyPage := NewServerTemplatePage("invite_body") bodyPage.Props["SiteURL"] = c.GetSiteURL() bodyPage.Props["TeamDisplayName"] = team.DisplayName bodyPage.Props["SenderName"] = sender bodyPage.Props["SenderStatus"] = senderRole bodyPage.Props["Email"] = invite props := make(map[string]string) props["email"] = invite props["id"] = team.Id props["display_name"] = team.DisplayName props["name"] = team.Name props["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(props) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt)) bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash)) if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV { l4g.Info("sending invitation to %v %v", invite, bodyPage.Props["Link"]) } if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil { l4g.Error("Failed to send invite email successfully err=%v", err) } } } }
func (c *Context) IsTeamAdmin() bool { if c.IsSystemAdmin() { return true } team := c.Session.GetTeamByTeamId(c.TeamId) if team == nil { return false } return model.IsInRole(team.Roles, model.ROLE_TEAM_ADMIN) }
func UpdateRoles(c *Context, user *model.User, roles string) *model.User { // make sure there is at least 1 other active admin if !model.IsInRole(roles, model.ROLE_SYSTEM_ADMIN) { if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) && !model.IsInRole(roles, model.ROLE_TEAM_ADMIN) { if result := <-Srv.Store.User().GetProfiles(user.TeamId); result.Err != nil { c.Err = result.Err return nil } else { activeAdmins := -1 profileUsers := result.Data.(map[string]*model.User) for _, profileUser := range profileUsers { if profileUser.DeleteAt == 0 && model.IsInRole(profileUser.Roles, model.ROLE_TEAM_ADMIN) { activeAdmins = activeAdmins + 1 } } if activeAdmins <= 0 { c.Err = model.NewAppError("updateRoles", "There must be at least one active admin", "") return nil } } } } user.Roles = roles var ruser *model.User if result := <-Srv.Store.User().Update(user, true); result.Err != nil { c.Err = result.Err return nil } else { c.LogAuditWithUserId(user.Id, "roles="+roles) ruser = result.Data.([2]*model.User)[0] } return ruser }
func updateValetFeature(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) allowValetStr := props["allow_valet"] if len(allowValetStr) == 0 { c.SetInvalidParam("updateValetFeature", "allow_valet") return } allowValet := allowValetStr == "true" teamId := props["team_id"] if len(teamId) > 0 && len(teamId) != 26 { c.SetInvalidParam("updateValetFeature", "team_id") return } else if len(teamId) == 0 { teamId = c.Session.TeamId } tchan := Srv.Store.Team().Get(teamId) if !c.HasPermissionsToTeam(teamId, "updateValetFeature") { return } if !model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) { c.Err = model.NewAppError("updateValetFeature", "You do not have the appropriate permissions", "userId="+c.Session.UserId) c.Err.StatusCode = http.StatusForbidden return } var team *model.Team if tResult := <-tchan; tResult.Err != nil { c.Err = tResult.Err return } else { team = tResult.Data.(*model.Team) } team.AllowValet = allowValet if result := <-Srv.Store.Team().Update(team); result.Err != nil { c.Err = result.Err return } w.Write([]byte(model.MapToJson(props))) }
func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks { c.Err = model.NewAppError("createIncomingHook", "Incoming webhooks have been disabled by the system admin.", "") c.Err.StatusCode = http.StatusNotImplemented return } c.LogAudit("attempt") props := model.MapFromJson(r.Body) id := props["id"] if len(id) == 0 { c.SetInvalidParam("deleteIncomingHook", "id") return } if result := <-Srv.Store.Webhook().GetIncoming(id); result.Err != nil { c.Err = result.Err return } else { if c.Session.UserId != result.Data.(*model.IncomingWebhook).UserId && !model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) { c.LogAudit("fail - inappropriate conditions") c.Err = model.NewAppError("deleteIncomingHook", "Inappropriate permissions to delete incoming webhook", "user_id="+c.Session.UserId) return } } if err := (<-Srv.Store.Webhook().DeleteIncoming(id, model.GetMillis())).Err; err != nil { c.Err = err return } c.LogAudit("success") w.Write([]byte(model.MapToJson(props))) }
func (c *Context) IsTeamAdmin() bool { if model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) || c.IsSystemAdmin() { return true } return false }
func updateActive(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) user_id := props["user_id"] if len(user_id) != 26 { c.SetInvalidParam("updateActive", "user_id") return } active := props["active"] == "true" var user *model.User if result := <-Srv.Store.User().Get(user_id); result.Err != nil { c.Err = result.Err return } else { user = result.Data.(*model.User) } if !c.HasPermissionsToTeam(user.TeamId, "updateActive") { return } if !c.IsTeamAdmin() { c.Err = model.NewAppError("updateActive", "You do not have the appropriate permissions", "userId="+user_id) c.Err.StatusCode = http.StatusForbidden return } // make sure there is at least 1 other active admin if !active && model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) { if result := <-Srv.Store.User().GetProfiles(user.TeamId); result.Err != nil { c.Err = result.Err return } else { activeAdmins := -1 profileUsers := result.Data.(map[string]*model.User) for _, profileUser := range profileUsers { if profileUser.DeleteAt == 0 && model.IsInRole(profileUser.Roles, model.ROLE_TEAM_ADMIN) { activeAdmins = activeAdmins + 1 } } if activeAdmins <= 0 { c.Err = model.NewAppError("updateRoles", "There must be at least one active admin", "userId="+user_id) return } } } if active { user.DeleteAt = 0 } else { user.DeleteAt = model.GetMillis() } if result := <-Srv.Store.User().Update(user, true); result.Err != nil { c.Err = result.Err return } else { c.LogAuditWithUserId(user.Id, fmt.Sprintf("active=%v", active)) if user.DeleteAt > 0 { RevokeAllSession(c, user.Id) } ruser := result.Data.([2]*model.User)[0] options := utils.SanitizeOptions options["passwordupdate"] = false ruser.Sanitize(options) w.Write([]byte(ruser.ToJson())) } }
func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) user_id := props["user_id"] if len(user_id) != 26 { c.SetInvalidParam("updateRoles", "user_id") return } new_roles := props["new_roles"] if !model.IsValidRoles(new_roles) { c.SetInvalidParam("updateRoles", "new_roles") return } if model.IsInRole(new_roles, model.ROLE_SYSTEM_ADMIN) && !c.IsSystemAdmin() { c.Err = model.NewAppError("updateRoles", "The system admin role can only be set by another system admin", "") c.Err.StatusCode = http.StatusForbidden return } var user *model.User if result := <-Srv.Store.User().Get(user_id); result.Err != nil { c.Err = result.Err return } else { user = result.Data.(*model.User) } if !c.HasPermissionsToTeam(user.TeamId, "updateRoles") { return } if !c.IsTeamAdmin() { c.Err = model.NewAppError("updateRoles", "You do not have the appropriate permissions", "userId="+user_id) c.Err.StatusCode = http.StatusForbidden return } if user.IsInRole(model.ROLE_SYSTEM_ADMIN) && !c.IsSystemAdmin() { c.Err = model.NewAppError("updateRoles", "The system admin role can only by modified by another system admin", "") c.Err.StatusCode = http.StatusForbidden return } ruser := UpdateRoles(c, user, new_roles) if c.Err != nil { return } uchan := Srv.Store.Session().UpdateRoles(user.Id, new_roles) gchan := Srv.Store.Session().GetSessions(user.Id) if result := <-uchan; result.Err != nil { // soft error since the user roles were still updated l4g.Error(result.Err) } 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) } } options := utils.SanitizeOptions options["passwordupdate"] = false ruser.Sanitize(options) w.Write([]byte(ruser.ToJson())) }
func deletePost(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) channelId := params["id"] if len(channelId) != 26 { c.SetInvalidParam("deletePost", "channelId") return } postId := params["post_id"] if len(postId) != 26 { c.SetInvalidParam("deletePost", "postId") return } cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId) pchan := Srv.Store.Post().Get(postId) if result := <-pchan; result.Err != nil { c.Err = result.Err return } else { post := result.Data.(*model.PostList).Posts[postId] if !c.HasPermissionsToChannel(cchan, "deletePost") && !c.IsTeamAdmin(post.UserId) { return } if post == nil { c.SetInvalidParam("deletePost", "postId") return } if post.ChannelId != channelId { c.Err = model.NewAppError("deletePost", "You do not have the appropriate permissions", "") c.Err.StatusCode = http.StatusForbidden return } if post.UserId != c.Session.UserId && !model.IsInRole(c.Session.Roles, model.ROLE_TEAM_ADMIN) { c.Err = model.NewAppError("deletePost", "You do not have the appropriate permissions", "") c.Err.StatusCode = http.StatusForbidden return } if dresult := <-Srv.Store.Post().Delete(postId, model.GetMillis()); dresult.Err != nil { c.Err = dresult.Err return } message := model.NewMessage(c.Session.TeamId, post.ChannelId, c.Session.UserId, model.ACTION_POST_DELETED) message.Add("post", post.ToJson()) PublishAndForget(message) result := make(map[string]string) result["id"] = postId w.Write([]byte(model.MapToJson(result))) } }
func convertTeamTo30(primaryTeamName string, team *TeamForUpgrade, uniqueEmails map[string]bool, uniqueUsernames map[string]bool) []*UserForUpgrade { store := api.Srv.Store.(*store.SqlStore) var users []*UserForUpgrade if _, err := store.GetMaster().Select(&users, "SELECT Users.Id, Users.Username, Users.Email, Users.Roles, Users.TeamId FROM Users WHERE Users.TeamId = :TeamId", map[string]interface{}{"TeamId": team.Id}); err != nil { l4g.Error("Failed to load profiles for team details=%v", err) flushLogAndExit(1) } var members []*model.TeamMember if result := <-api.Srv.Store.Team().GetMembers(team.Id); result.Err != nil { l4g.Error("Failed to load team membership details=%v", result.Err) flushLogAndExit(1) } else { members = result.Data.([]*model.TeamMember) } for _, user := range users { shouldUpdateUser := false previousRole := user.Roles previousEmail := user.Email previousUsername := user.Username member := &model.TeamMember{ TeamId: team.Id, UserId: user.Id, } if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) { member.Roles = model.ROLE_TEAM_ADMIN user.Roles = "" shouldUpdateUser = true } exists := false for _, member := range members { if member.UserId == user.Id { exists = true break } } if !exists { if result := <-api.Srv.Store.Team().SaveMember(member); result.Err != nil { l4g.Error("Failed to save membership for %v details=%v", user.Email, result.Err) flushLogAndExit(1) } } err := api.MoveFile( "teams/"+team.Id+"/users/"+user.Id+"/profile.png", "users/"+user.Id+"/profile.png", ) if err != nil { l4g.Warn("No profile image to move for %v", user.Email) } if uniqueEmails[user.Email] { shouldUpdateUser = true emailParts := strings.Split(user.Email, "@") if len(emailParts) == 2 { user.Email = emailParts[0] + "+" + team.Name + "@" + emailParts[1] } else { user.Email = user.Email + "." + team.Name } if len(user.Email) > 127 { user.Email = user.Email[:127] } } if uniqueUsernames[user.Username] { shouldUpdateUser = true user.Username = team.Name + "." + user.Username if len(user.Username) > 63 { user.Username = user.Username[:63] } } if shouldUpdateUser { if _, err := store.GetMaster().Exec(` UPDATE Users SET Email = :Email, Username = :Username, Roles = :Roles WHERE Id = :Id `, map[string]interface{}{ "Email": user.Email, "Username": user.Username, "Roles": user.Roles, "Id": user.Id, }, ); err != nil { l4g.Error("Failed to update user %v details=%v", user.Email, err) flushLogAndExit(1) } l4g.Info("modified user_id=%v, changed email from=%v to=%v, changed username from=%v to %v changed roles from=%v to=%v", user.Id, previousEmail, user.Email, previousUsername, user.Username, previousRole, user.Roles) emailChanged := previousEmail != user.Email usernameChanged := previousUsername != user.Username if emailChanged || usernameChanged { bodyPage := utils.NewHTMLTemplate("upgrade_30_body", "") EmailChanged := "" UsernameChanged := "" if emailChanged { EmailChanged = "true" } if usernameChanged { UsernameChanged = "true" } bodyPage.Html["Info"] = template.HTML(utils.T("api.templates.upgrade_30_body.info", map[string]interface{}{ "SiteName": utils.ClientCfg["SiteName"], "TeamName": team.Name, "Email": user.Email, "Username": user.Username, "EmailChanged": EmailChanged, "UsernameChanged": UsernameChanged, })) utils.SendMail( previousEmail, utils.T("api.templates.upgrade_30_subject.info"), bodyPage.Render(), ) } } uniqueEmails[user.Email] = true uniqueUsernames[user.Username] = true } return users }