diff options
Diffstat (limited to 'api/team.go')
-rw-r--r-- | api/team.go | 221 |
1 files changed, 115 insertions, 106 deletions
diff --git a/api/team.go b/api/team.go index 8cce384c3..4794b66df 100644 --- a/api/team.go +++ b/api/team.go @@ -25,18 +25,20 @@ func InitTeam(r *mux.Router) { sr.Handle("/create_from_signup", ApiAppHandler(createTeamFromSignup)).Methods("POST") sr.Handle("/create_with_sso/{service:[A-Za-z]+}", ApiAppHandler(createTeamFromSSO)).Methods("POST") sr.Handle("/signup", ApiAppHandler(signupTeam)).Methods("POST") + sr.Handle("/all", ApiUserRequired(getAll)).Methods("GET") sr.Handle("/find_team_by_name", ApiAppHandler(findTeamByName)).Methods("POST") sr.Handle("/find_teams", ApiAppHandler(findTeams)).Methods("POST") sr.Handle("/email_teams", ApiAppHandler(emailTeams)).Methods("POST") sr.Handle("/invite_members", ApiUserRequired(inviteMembers)).Methods("POST") sr.Handle("/update_name", ApiUserRequired(updateTeamDisplayName)).Methods("POST") - sr.Handle("/update_valet_feature", ApiUserRequired(updateValetFeature)).Methods("POST") sr.Handle("/me", ApiUserRequired(getMyTeam)).Methods("GET") + // These should be moved to the global admain console sr.Handle("/import_team", ApiUserRequired(importTeam)).Methods("POST") + sr.Handle("/export_team", ApiUserRequired(exportTeam)).Methods("GET") } func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { - if utils.Cfg.ServiceSettings.DisableEmailSignUp { + if !utils.Cfg.EmailSettings.EnableSignUpWithEmail { c.Err = model.NewAppError("signupTeam", "Team sign-up with email is disabled.", "") c.Err.StatusCode = http.StatusNotImplemented return @@ -54,16 +56,17 @@ func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { return } - subjectPage := NewServerTemplatePage("signup_team_subject", c.GetSiteURL()) - bodyPage := NewServerTemplatePage("signup_team_body", c.GetSiteURL()) - bodyPage.Props["TourUrl"] = utils.Cfg.TeamSettings.TourLink + subjectPage := NewServerTemplatePage("signup_team_subject") + subjectPage.Props["SiteURL"] = c.GetSiteURL() + bodyPage := NewServerTemplatePage("signup_team_body") + bodyPage.Props["SiteURL"] = c.GetSiteURL() props := make(map[string]string) props["email"] = email props["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(props) - hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt)) + hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash)) @@ -72,10 +75,7 @@ func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { return } - if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV || utils.Cfg.EmailSettings.ByPassEmail { - m["follow_link"] = bodyPage.Props["Link"] - } - + m["follow_link"] = bodyPage.Props["Link"] w.Header().Set("Access-Control-Allow-Origin", " *") w.Write([]byte(model.MapToJson(m))) } @@ -84,7 +84,8 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) service := params["service"] - if !utils.IsServiceAllowed(service) { + sso := utils.Cfg.GetSSOService(service) + if sso != nil && !sso.Enable { c.SetInvalidParam("createTeamFromSSO", "service") return } @@ -96,6 +97,10 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) { return } + if !isTreamCreationAllowed(c, team.Email) { + return + } + team.PreSave() team.Name = model.CleanTeamName(team.Name) @@ -118,8 +123,6 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) { } } - team.AllowValet = utils.Cfg.TeamSettings.AllowValetDefault - if result := <-Srv.Store.Team().Save(team); result.Err != nil { c.Err = result.Err return @@ -139,7 +142,7 @@ func createTeamFromSSO(c *Context, w http.ResponseWriter, r *http.Request) { } func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) { - if utils.Cfg.ServiceSettings.DisableEmailSignUp { + if !utils.Cfg.EmailSettings.EnableSignUpWithEmail { c.Err = model.NewAppError("createTeamFromSignup", "Team sign-up with email is disabled.", "") c.Err.StatusCode = http.StatusNotImplemented return @@ -180,7 +183,7 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) { teamSignup.User.TeamId = "" teamSignup.User.Password = password - if !model.ComparePassword(teamSignup.Hash, fmt.Sprintf("%v:%v", teamSignup.Data, utils.Cfg.ServiceSettings.InviteSalt)) { + if !model.ComparePassword(teamSignup.Hash, fmt.Sprintf("%v:%v", teamSignup.Data, utils.Cfg.EmailSettings.InviteSalt)) { c.Err = model.NewAppError("createTeamFromSignup", "The signup link does not appear to be valid", "") return } @@ -201,8 +204,6 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) { return } - teamSignup.Team.AllowValet = utils.Cfg.TeamSettings.AllowValetDefault - if result := <-Srv.Store.Team().Save(&teamSignup.Team); result.Err != nil { c.Err = result.Err return @@ -222,13 +223,6 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) { return } - if teamSignup.Team.AllowValet { - CreateValet(c, rteam) - if c.Err != nil { - return - } - } - InviteMembers(c, rteam, ruser, teamSignup.Invites) teamSignup.Team = *rteam @@ -239,47 +233,43 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) { } func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { - if utils.Cfg.ServiceSettings.DisableEmailSignUp { - c.Err = model.NewAppError("createTeam", "Team sign-up with email is disabled.", "") - c.Err.StatusCode = http.StatusNotImplemented + team := model.TeamFromJson(r.Body) + rteam := CreateTeam(c, team) + if c.Err != nil { return } - team := model.TeamFromJson(r.Body) + w.Write([]byte(rteam.ToJson())) +} + +func CreateTeam(c *Context, team *model.Team) *model.Team { + if !utils.Cfg.EmailSettings.EnableSignUpWithEmail { + c.Err = model.NewAppError("createTeam", "Team sign-up with email is disabled.", "") + c.Err.StatusCode = http.StatusNotImplemented + return nil + } if team == nil { c.SetInvalidParam("createTeam", "team") - return + return nil } if !isTreamCreationAllowed(c, team.Email) { - return - } - - if utils.Cfg.ServiceSettings.Mode != utils.MODE_DEV { - c.Err = model.NewAppError("createTeam", "The mode does not allow network creation without a valid invite", "") - return + return nil } if result := <-Srv.Store.Team().Save(team); result.Err != nil { c.Err = result.Err - return + return nil } else { rteam := result.Data.(*model.Team) if _, err := CreateDefaultChannels(c, rteam.Id); err != nil { c.Err = err - return + return nil } - if rteam.AllowValet { - CreateValet(c, rteam) - if c.Err != nil { - return - } - } - - w.Write([]byte(rteam.ToJson())) + return rteam } } @@ -287,7 +277,7 @@ func isTreamCreationAllowed(c *Context, email string) bool { email = strings.ToLower(email) - if utils.Cfg.TeamSettings.DisableTeamCreation { + if !utils.Cfg.TeamSettings.EnableTeamCreation { c.Err = model.NewAppError("isTreamCreationAllowed", "Team creation has been disabled. Please ask your systems administrator for details.", "") return false } @@ -312,6 +302,53 @@ func isTreamCreationAllowed(c *Context, email string) bool { return true } +func getAll(c *Context, w http.ResponseWriter, r *http.Request) { + if !c.HasSystemAdminPermissions("getLogs") { + return + } + + if result := <-Srv.Store.Team().GetAll(); result.Err != nil { + c.Err = result.Err + return + } else { + teams := result.Data.([]*model.Team) + m := make(map[string]*model.Team) + for _, v := range teams { + m[v.Id] = v + } + + w.Write([]byte(model.TeamMapToJson(m))) + } +} + +func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) { + props := model.MapFromJson(r.Body) + id := props["id"] + + if result := <-Srv.Store.Session().Get(id); result.Err != nil { + c.Err = result.Err + return + } else { + session := result.Data.(*model.Session) + + c.LogAudit("revoked_all=" + id) + + if session.IsOAuth { + RevokeAccessToken(session.Token) + } else { + sessionCache.Remove(session.Token) + + if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil { + c.Err = result.Err + return + } else { + w.Write([]byte(model.MapToJson(props))) + return + } + } + } +} + func findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) @@ -391,8 +428,10 @@ func emailTeams(c *Context, w http.ResponseWriter, r *http.Request) { return } - subjectPage := NewServerTemplatePage("find_teams_subject", c.GetSiteURL()) - bodyPage := NewServerTemplatePage("find_teams_body", c.GetSiteURL()) + subjectPage := NewServerTemplatePage("find_teams_subject") + subjectPage.Props["SiteURL"] = c.GetSiteURL() + bodyPage := NewServerTemplatePage("find_teams_body") + bodyPage.Props["SiteURL"] = c.GetSiteURL() if result := <-Srv.Store.Team().GetTeamsForEmail(email); result.Err != nil { c.Err = result.Err @@ -467,22 +506,23 @@ func InviteMembers(c *Context, team *model.Team, user *model.User, invites []str sender := user.GetDisplayName() senderRole := "" - if strings.Contains(user.Roles, model.ROLE_ADMIN) || strings.Contains(user.Roles, model.ROLE_SYSTEM_ADMIN) { + 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", c.GetSiteURL()) + subjectPage := NewServerTemplatePage("invite_subject") + subjectPage.Props["SiteURL"] = c.GetSiteURL() subjectPage.Props["SenderName"] = sender subjectPage.Props["TeamDisplayName"] = team.DisplayName - bodyPage := NewServerTemplatePage("invite_body", c.GetSiteURL()) + + 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 @@ -490,10 +530,10 @@ func InviteMembers(c *Context, team *model.Team, user *model.User, invites []str 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)) + hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.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 { + if !utils.Cfg.EmailSettings.SendEmailNotifications { l4g.Info("sending invitation to %v %v", invite, bodyPage.Props["Link"]) } @@ -526,7 +566,7 @@ func updateTeamDisplayName(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !strings.Contains(c.Session.Roles, model.ROLE_ADMIN) { + 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 @@ -540,56 +580,6 @@ func updateTeamDisplayName(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(model.MapToJson(props))) } -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 !strings.Contains(c.Session.Roles, model.ROLE_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 getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) { if len(c.Session.TeamId) == 0 { @@ -675,3 +665,22 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/octet-stream") http.ServeContent(w, r, "MattermostImportLog.txt", time.Now(), bytes.NewReader(log.Bytes())) } + +func exportTeam(c *Context, w http.ResponseWriter, r *http.Request) { + if !c.HasPermissionsToTeam(c.Session.TeamId, "export") || !c.IsTeamAdmin(c.Session.UserId) { + c.Err = model.NewAppError("exportTeam", "Only a team admin can export data.", "userId="+c.Session.UserId) + c.Err.StatusCode = http.StatusForbidden + return + } + + options := ExportOptionsFromJson(r.Body) + + if link, err := ExportToFile(options); err != nil { + c.Err = err + return + } else { + result := map[string]string{} + result["link"] = link + w.Write([]byte(model.MapToJson(result))) + } +} |