Files
mattermost/api/team.go
Corey Hulen 2e5617c29b PLT-2057 User as a first class object (#2648)
* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding client side unit test

* Cleaning up the clint side tests

* Fixing msg

* Adding more client side unit tests

* Adding more using tests

* Adding last bit of client side unit tests and adding make cmd

* Fixing bad merge

* Fixing libraries

* Updating to new client side API

* Fixing borken unit test

* Fixing unit tests

* ugg...trying to beat gofmt

* ugg...trying to beat gofmt

* Cleaning up remainder of the server side routes

* Adding inital load api

* Increased coverage of webhook unit tests (#2660)

* Adding loading ... to root html

* Fixing bad merge

* Removing explicit content type so superagent will guess corectly (#2685)

* Fixing merge and unit tests

* Adding create team UI

* Fixing signup flows

* Adding LDAP unit tests and enterprise unit test helper (#2702)

* Add the ability to reset MFA from the commandline (#2706)

* Fixing compliance unit tests

* Fixing client side tests

* Adding open server to system console

* Moving websocket connection

* Fixing unit test

* Fixing unit tests

* Fixing unit tests

* Adding nickname and more LDAP unit tests (#2717)

* Adding join open teams

* Cleaning up all TODOs in the code

* Fixing web sockets

* Removing unused webockets file

* PLT-2533 Add the ability to reset a user's MFA from the system console (#2715)

* Add the ability to reset a user's MFA from the system console

* Add client side unit test for adminResetMfa

* Reorganizing authentication to fix LDAP error message (#2723)

* Fixing failing unit test

* Initial upgrade db code

* Adding upgrade script

* Fixing upgrade script after running on core

* Update OAuth and Claim routes to work with user model changes (#2739)

* Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740)

* Fixing team invite ldap login call (#2741)

* Fixing bluebar and some img stuff

* Fix all the different file upload web utils (#2743)

* Fixing invalid session redirect (#2744)

* Redirect on bad channel name (#2746)

* Fixing a bunch of issue and removing dead code

* Patch to fix error message on leave channel (#2747)

* Setting EnableOpenServer to false by default

* Fixing config

* Fixing upgrade

* Fixing reported bugs

* Bug fixes for PLT-2057

* PLT-2563 Redo password recovery to use a database table (#2745)

* Redo password recovery to use a database table

* Update reset password audits

* Split out admin and user reset password APIs to be separate

* Delete password recovery when user is permanently deleted

* Consolidate password resetting into a single function

* Removed private channels as an option for outgoing webhooks (#2752)

* PLT-2577/PLT-2552 Fixes for backstage (#2753)

* Added URL to incoming webhook list

* Fixed client functions for adding/removing integrations

* Disallowed slash commands without trigger words

* Fixed clientside handling of errors on AddCommand page

* Minor auth cleanup (#2758)

* Changed EditPostModal to just close if you save without making any changes (#2759)

* Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756)

* Fixed url in channel info modal (#2755)

* Fixing reported issues

* Moving to version 3 of the apis

* Fixing command unit tests (#2760)

* Adding team admins

* Fixing DM issue

* Fixing eslint error

* Properly set EditPostModal's originalText state in all cases (#2762)

* Update client config check to assume features is defined if server is licensed (#2772)

* Fixing url link

* Fixing issue with websocket crashing when sending messages to different teams
2016-04-21 22:37:01 -07:00

813 lines
22 KiB
Go

// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"bytes"
"fmt"
"html/template"
"net/http"
"net/url"
"strconv"
"strings"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func InitTeam() {
l4g.Debug(utils.T("api.team.init.debug"))
BaseRoutes.Teams.Handle("/create", ApiAppHandler(createTeam)).Methods("POST")
BaseRoutes.Teams.Handle("/create_from_signup", ApiAppHandler(createTeamFromSignup)).Methods("POST")
BaseRoutes.Teams.Handle("/signup", ApiAppHandler(signupTeam)).Methods("POST")
BaseRoutes.Teams.Handle("/all", ApiAppHandler(getAll)).Methods("GET")
BaseRoutes.Teams.Handle("/all_team_listings", ApiUserRequired(GetAllTeamListings)).Methods("GET")
BaseRoutes.Teams.Handle("/get_invite_info", ApiAppHandler(getInviteInfo)).Methods("POST")
BaseRoutes.Teams.Handle("/find_team_by_name", ApiAppHandler(findTeamByName)).Methods("POST")
BaseRoutes.Teams.Handle("/members/{id:[A-Za-z0-9]+}", ApiUserRequired(getMembers)).Methods("GET")
BaseRoutes.NeedTeam.Handle("/me", ApiUserRequired(getMyTeam)).Methods("GET")
BaseRoutes.NeedTeam.Handle("/update", ApiUserRequired(updateTeam)).Methods("POST")
BaseRoutes.NeedTeam.Handle("/invite_members", ApiUserRequired(inviteMembers)).Methods("POST")
BaseRoutes.NeedTeam.Handle("/add_user_to_team", ApiUserRequired(addUserToTeam)).Methods("POST")
// These should be moved to the global admain console
BaseRoutes.Teams.Handle("/import_team", ApiUserRequired(importTeam)).Methods("POST")
BaseRoutes.Teams.Handle("/export_team", ApiUserRequired(exportTeam)).Methods("GET")
BaseRoutes.Teams.Handle("/add_user_to_team_from_invite", ApiUserRequired(addUserToTeamFromInvite)).Methods("POST")
}
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
c.Err = model.NewLocAppError("signupTeam", "api.team.signup_team.email_disabled.app_error", nil, "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
m := model.MapFromJson(r.Body)
email := strings.ToLower(strings.TrimSpace(m["email"]))
if len(email) == 0 {
c.SetInvalidParam("signupTeam", "email")
return
}
if !isTeamCreationAllowed(c, email) {
return
}
subjectPage := utils.NewHTMLTemplate("signup_team_subject", c.Locale)
subjectPage.Props["Subject"] = c.T("api.templates.signup_team_subject",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]})
bodyPage := utils.NewHTMLTemplate("signup_team_body", c.Locale)
bodyPage.Props["SiteURL"] = c.GetSiteURL()
bodyPage.Props["Title"] = c.T("api.templates.signup_team_body.title")
bodyPage.Props["Button"] = c.T("api.templates.signup_team_body.button")
bodyPage.Html["Info"] = template.HTML(c.T("api.templates.signup_team_body.info",
map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}))
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.EmailSettings.InviteSalt))
bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))
if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
c.Err = err
return
}
if !utils.Cfg.EmailSettings.RequireEmailVerification {
m["follow_link"] = fmt.Sprintf("/signup_team_complete/?d=%s&h=%s", url.QueryEscape(data), url.QueryEscape(hash))
}
w.Header().Set("Access-Control-Allow-Origin", " *")
w.Write([]byte(model.MapToJson(m)))
}
func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.email_disabled.app_error", nil, "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
teamSignup := model.TeamSignupFromJson(r.Body)
if teamSignup == nil {
c.SetInvalidParam("createTeam", "teamSignup")
return
}
props := model.MapFromJson(strings.NewReader(teamSignup.Data))
teamSignup.Team.Email = props["email"]
teamSignup.User.Email = props["email"]
teamSignup.Team.PreSave()
if err := teamSignup.Team.IsValid(*utils.Cfg.TeamSettings.RestrictTeamNames); err != nil {
c.Err = err
return
}
if !isTeamCreationAllowed(c, teamSignup.Team.Email) {
return
}
teamSignup.Team.Id = ""
password := teamSignup.User.Password
teamSignup.User.PreSave()
if err := teamSignup.User.IsValid(); err != nil {
c.Err = err
return
}
teamSignup.User.Id = ""
teamSignup.User.Password = password
if !model.ComparePassword(teamSignup.Hash, fmt.Sprintf("%v:%v", teamSignup.Data, utils.Cfg.EmailSettings.InviteSalt)) {
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.invalid_link.app_error", nil, "")
return
}
t, err := strconv.ParseInt(props["time"], 10, 64)
if err != nil || model.GetMillis()-t > 1000*60*60 { // one hour
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.expired_link.app_error", nil, "")
return
}
found := FindTeamByName(teamSignup.Team.Name)
if found {
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.unavailable.app_error", nil, "d="+teamSignup.Team.Name)
return
}
if result := <-Srv.Store.Team().Save(&teamSignup.Team); result.Err != nil {
c.Err = result.Err
return
} else {
rteam := result.Data.(*model.Team)
if _, err := CreateDefaultChannels(c, rteam.Id); err != nil {
c.Err = nil
return
}
teamSignup.User.EmailVerified = true
ruser, err := CreateUser(&teamSignup.User)
if err != nil {
c.Err = err
return
}
JoinUserToTeam(rteam, ruser)
InviteMembers(c, rteam, ruser, teamSignup.Invites)
teamSignup.Team = *rteam
teamSignup.User = *ruser
w.Write([]byte(teamSignup.ToJson()))
}
}
func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
team := model.TeamFromJson(r.Body)
if team == nil {
c.SetInvalidParam("createTeam", "team")
return
}
var user *model.User
if len(c.Session.UserId) > 0 {
uchan := Srv.Store.User().Get(c.Session.UserId)
if result := <-uchan; result.Err != nil {
c.Err = result.Err
return
} else {
user = result.Data.(*model.User)
team.Email = user.Email
}
}
rteam := CreateTeam(c, team)
if c.Err != nil {
return
}
if user != nil {
err := JoinUserToTeam(team, user)
if err != nil {
c.Err = err
return
}
}
w.Write([]byte(rteam.ToJson()))
}
func CreateTeam(c *Context, team *model.Team) *model.Team {
if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
c.Err = model.NewLocAppError("createTeam", "api.team.create_team.email_disabled.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return nil
}
if team == nil {
c.SetInvalidParam("createTeam", "team")
return nil
}
if !isTeamCreationAllowed(c, team.Email) {
return nil
}
if result := <-Srv.Store.Team().Save(team); result.Err != nil {
c.Err = result.Err
return nil
} else {
rteam := result.Data.(*model.Team)
if _, err := CreateDefaultChannels(c, rteam.Id); err != nil {
c.Err = err
return nil
}
return rteam
}
}
func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id}
channelRole := ""
if team.Email == user.Email {
tm.Roles = model.ROLE_TEAM_ADMIN
channelRole = model.CHANNEL_ROLE_ADMIN
}
if tmr := <-Srv.Store.Team().SaveMember(tm); tmr.Err != nil {
return tmr.Err
}
// Soft error if there is an issue joining the default channels
if err := JoinDefaultChannels(team.Id, user, channelRole); err != nil {
l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err)
}
RemoveAllSessionsForUserId(user.Id)
InvalidateCacheForUser(user.Id)
return nil
}
func isTeamCreationAllowed(c *Context, email string) bool {
email = strings.ToLower(email)
if !utils.Cfg.TeamSettings.EnableTeamCreation {
c.Err = model.NewLocAppError("isTeamCreationAllowed", "api.team.is_team_creation_allowed.disabled.app_error", nil, "")
return false
}
// commas and @ signs are optional
// can be in the form of "@corp.mattermost.com, mattermost.com mattermost.org" -> corp.mattermost.com mattermost.com mattermost.org
domains := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(utils.Cfg.TeamSettings.RestrictCreationToDomains, "@", " ", -1), ",", " ", -1))))
matched := false
for _, d := range domains {
if strings.HasSuffix(email, "@"+d) {
matched = true
break
}
}
if len(utils.Cfg.TeamSettings.RestrictCreationToDomains) > 0 && !matched {
c.Err = model.NewLocAppError("isTeamCreationAllowed", "api.team.is_team_creation_allowed.domain.app_error", nil, "")
return false
}
return true
}
func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.Team().GetAllTeamListing(); 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
if !c.IsSystemAdmin() {
m[v.Id].Sanitize()
}
}
w.Write([]byte(model.TeamMapToJson(m)))
}
}
func getAll(c *Context, w http.ResponseWriter, r *http.Request) {
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
if !c.IsSystemAdmin() {
m[v.Id].SanitizeForNotLoggedIn()
}
}
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 inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
invites := model.InvitesFromJson(r.Body)
if len(invites.Invites) == 0 {
c.Err = model.NewLocAppError("Team.InviteMembers", "api.team.invite_members.no_one.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
tchan := Srv.Store.Team().Get(c.TeamId)
uchan := Srv.Store.User().Get(c.Session.UserId)
var team *model.Team
if result := <-tchan; result.Err != nil {
c.Err = result.Err
return
} else {
team = result.Data.(*model.Team)
}
var user *model.User
if result := <-uchan; result.Err != nil {
c.Err = result.Err
return
} else {
user = result.Data.(*model.User)
}
ia := make([]string, len(invites.Invites))
for _, invite := range invites.Invites {
ia = append(ia, invite["email"])
}
InviteMembers(c, team, user, ia)
w.Write([]byte(invites.ToJson()))
}
func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
params := model.MapFromJson(r.Body)
userId := params["user_id"]
if len(userId) != 26 {
c.SetInvalidParam("addUserToTeam", "user_id")
return
}
tchan := Srv.Store.Team().Get(c.TeamId)
uchan := Srv.Store.User().Get(userId)
var team *model.Team
if result := <-tchan; result.Err != nil {
c.Err = result.Err
return
} else {
team = result.Data.(*model.Team)
}
var user *model.User
if result := <-uchan; result.Err != nil {
c.Err = result.Err
return
} else {
user = result.Data.(*model.User)
}
if !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("addUserToTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return
}
err := JoinUserToTeam(team, user)
if err != nil {
c.Err = err
return
}
w.Write([]byte(model.MapToJson(params)))
}
func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) {
params := model.MapFromJson(r.Body)
hash := params["hash"]
data := params["data"]
inviteId := params["invite_id"]
teamId := ""
var team *model.Team
if len(hash) > 0 {
props := model.MapFromJson(strings.NewReader(data))
if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) {
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_invalid.app_error", nil, "")
return
}
t, err := strconv.ParseInt(props["time"], 10, 64)
if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_expired.app_error", nil, "")
return
}
teamId = props["id"]
// try to load the team to make sure it exists
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
c.Err = result.Err
return
} else {
team = result.Data.(*model.Team)
}
}
if len(inviteId) > 0 {
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
c.Err = result.Err
return
} else {
team = result.Data.(*model.Team)
teamId = team.Id
}
}
if len(teamId) == 0 {
c.Err = model.NewLocAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_invalid.app_error", nil, "")
return
}
uchan := Srv.Store.User().Get(c.Session.UserId)
var user *model.User
if result := <-uchan; result.Err != nil {
c.Err = result.Err
return
} else {
user = result.Data.(*model.User)
}
tm := c.Session.GetTeamByTeamId(teamId)
if tm == nil {
err := JoinUserToTeam(team, user)
if err != nil {
c.Err = err
return
}
}
team.Sanitize()
w.Write([]byte(team.ToJson()))
}
func FindTeamByName(name string) bool {
if result := <-Srv.Store.Team().GetByName(name); result.Err != nil {
return false
} else {
return true
}
}
func findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
m := model.MapFromJson(r.Body)
name := strings.ToLower(strings.TrimSpace(m["name"]))
found := FindTeamByName(name)
if found {
w.Write([]byte("true"))
} else {
w.Write([]byte("false"))
}
}
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 c.IsTeamAdmin() {
senderRole = c.T("api.team.invite_members.admin")
} else {
senderRole = c.T("api.team.invite_members.member")
}
subjectPage := utils.NewHTMLTemplate("invite_subject", c.Locale)
subjectPage.Props["Subject"] = c.T("api.templates.invite_subject",
map[string]interface{}{"SenderName": sender, "TeamDisplayName": team.DisplayName, "SiteName": utils.ClientCfg["SiteName"]})
bodyPage := utils.NewHTMLTemplate("invite_body", c.Locale)
bodyPage.Props["SiteURL"] = c.GetSiteURL()
bodyPage.Props["Title"] = c.T("api.templates.invite_body.title")
bodyPage.Html["Info"] = template.HTML(c.T("api.templates.invite_body.info",
map[string]interface{}{"SenderStatus": senderRole, "SenderName": sender, "TeamDisplayName": team.DisplayName}))
bodyPage.Props["Button"] = c.T("api.templates.invite_body.button")
bodyPage.Html["ExtraInfo"] = template.HTML(c.T("api.templates.invite_body.extra_info",
map[string]interface{}{"TeamDisplayName": team.DisplayName, "TeamURL": c.GetTeamURL()}))
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.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.EmailSettings.SendEmailNotifications {
l4g.Info(utils.T("api.team.invite_members.sending.info"), invite, bodyPage.Props["Link"])
}
if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil {
l4g.Error(utils.T("api.team.invite_members.send.error"), err)
}
}
}
}
func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
team := model.TeamFromJson(r.Body)
if team == nil {
c.SetInvalidParam("updateTeam", "team")
return
}
team.Id = c.TeamId
if !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("updateTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return
}
var oldTeam *model.Team
if result := <-Srv.Store.Team().Get(team.Id); result.Err != nil {
c.Err = result.Err
return
} else {
oldTeam = result.Data.(*model.Team)
}
oldTeam.DisplayName = team.DisplayName
oldTeam.InviteId = team.InviteId
oldTeam.AllowOpenInvite = team.AllowOpenInvite
oldTeam.CompanyName = team.CompanyName
oldTeam.AllowedDomains = team.AllowedDomains
//oldTeam.Type = team.Type
if result := <-Srv.Store.Team().Update(oldTeam); result.Err != nil {
c.Err = result.Err
return
}
oldTeam.Sanitize()
w.Write([]byte(oldTeam.ToJson()))
}
func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError {
l4g.Warn(utils.T("api.team.permanent_delete_team.attempting.warn"), team.Name, team.Id)
c.Path = "/teams/permanent_delete"
c.LogAuditWithUserId("", fmt.Sprintf("attempt teamId=%v", team.Id))
team.DeleteAt = model.GetMillis()
if result := <-Srv.Store.Team().Update(team); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil {
return result.Err
}
l4g.Warn(utils.T("api.team.permanent_delete_team.deleted.warn"), team.Name, team.Id)
c.LogAuditWithUserId("", fmt.Sprintf("success teamId=%v", team.Id))
return nil
}
func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
if len(c.TeamId) == 0 {
return
}
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else if HandleEtag(result.Data.(*model.Team).Etag(), w, r) {
return
} else {
w.Header().Set(model.HEADER_ETAG_SERVER, result.Data.(*model.Team).Etag())
w.Write([]byte(result.Data.(*model.Team).ToJson()))
return
}
}
func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasPermissionsToTeam(c.TeamId, "import") || !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.admin.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return
}
if err := r.ParseMultipartForm(10000000); err != nil {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.parse.app_error", nil, err.Error())
return
}
importFromArray, ok := r.MultipartForm.Value["importFrom"]
importFrom := importFromArray[0]
fileSizeStr, ok := r.MultipartForm.Value["filesize"]
if !ok {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.unavailable.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
fileSize, err := strconv.ParseInt(fileSizeStr[0], 10, 64)
if err != nil {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.integer.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
fileInfoArray, ok := r.MultipartForm.File["file"]
if !ok {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.no_file.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
if len(fileInfoArray) <= 0 {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.array.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
fileInfo := fileInfoArray[0]
fileData, err := fileInfo.Open()
defer fileData.Close()
if err != nil {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.open.app_error", nil, err.Error())
c.Err.StatusCode = http.StatusBadRequest
return
}
var log *bytes.Buffer
switch importFrom {
case "slack":
var err *model.AppError
if err, log = SlackImport(fileData, fileSize, c.TeamId); err != nil {
c.Err = err
c.Err.StatusCode = http.StatusBadRequest
}
}
w.Header().Set("Content-Disposition", "attachment; filename=MattermostImportLog.txt")
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.TeamId, "export") || !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("exportTeam", "api.team.export_team.admin.app_error", nil, "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)))
}
}
func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
m := model.MapFromJson(r.Body)
inviteId := m["invite_id"]
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
c.Err = result.Err
return
} else {
team := result.Data.(*model.Team)
if !(team.Type == model.TEAM_OPEN) {
c.Err = model.NewLocAppError("getInviteInfo", "api.team.get_invite_info.not_open_team", nil, "id="+inviteId)
return
}
result := map[string]string{}
result["display_name"] = team.DisplayName
result["name"] = team.Name
result["id"] = team.Id
w.Write([]byte(model.MapToJson(result)))
}
}
func getMembers(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["id"]
if c.Session.GetTeamByTeamId(id) == nil {
if !c.HasSystemAdminPermissions("getMembers") {
return
}
}
if result := <-Srv.Store.Team().GetMembers(id); result.Err != nil {
c.Err = result.Err
return
} else {
members := result.Data.([]*model.TeamMember)
w.Write([]byte(model.TeamMembersToJson(members)))
return
}
}