github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/api/team.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api
     5  
     6  import (
     7  	"bytes"
     8  	"io"
     9  	"net/http"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"github.com/gorilla/mux"
    14  
    15  	"github.com/mattermost/mattermost-server/model"
    16  )
    17  
    18  func (api *API) InitTeam() {
    19  	api.BaseRoutes.Teams.Handle("/create", api.ApiUserRequired(createTeam)).Methods("POST")
    20  	api.BaseRoutes.Teams.Handle("/all", api.ApiUserRequired(getAll)).Methods("GET")
    21  	api.BaseRoutes.Teams.Handle("/all_team_listings", api.ApiUserRequired(GetAllTeamListings)).Methods("GET")
    22  	api.BaseRoutes.Teams.Handle("/get_invite_info", api.ApiAppHandler(getInviteInfo)).Methods("POST")
    23  	api.BaseRoutes.Teams.Handle("/find_team_by_name", api.ApiUserRequired(findTeamByName)).Methods("POST")
    24  	api.BaseRoutes.Teams.Handle("/name/{team_name:[A-Za-z0-9\\-]+}", api.ApiUserRequired(getTeamByName)).Methods("GET")
    25  	api.BaseRoutes.Teams.Handle("/members", api.ApiUserRequired(getMyTeamMembers)).Methods("GET")
    26  	api.BaseRoutes.Teams.Handle("/unread", api.ApiUserRequired(getMyTeamsUnread)).Methods("GET")
    27  
    28  	api.BaseRoutes.NeedTeam.Handle("/me", api.ApiUserRequired(getMyTeam)).Methods("GET")
    29  	api.BaseRoutes.NeedTeam.Handle("/stats", api.ApiUserRequired(getTeamStats)).Methods("GET")
    30  	api.BaseRoutes.NeedTeam.Handle("/members/{offset:[0-9]+}/{limit:[0-9]+}", api.ApiUserRequired(getTeamMembers)).Methods("GET")
    31  	api.BaseRoutes.NeedTeam.Handle("/members/ids", api.ApiUserRequired(getTeamMembersByIds)).Methods("POST")
    32  	api.BaseRoutes.NeedTeam.Handle("/members/{user_id:[A-Za-z0-9]+}", api.ApiUserRequired(getTeamMember)).Methods("GET")
    33  	api.BaseRoutes.NeedTeam.Handle("/update", api.ApiUserRequired(updateTeam)).Methods("POST")
    34  	api.BaseRoutes.NeedTeam.Handle("/update_member_roles", api.ApiUserRequired(updateMemberRoles)).Methods("POST")
    35  
    36  	api.BaseRoutes.NeedTeam.Handle("/invite_members", api.ApiUserRequired(inviteMembers)).Methods("POST")
    37  
    38  	api.BaseRoutes.NeedTeam.Handle("/add_user_to_team", api.ApiUserRequired(addUserToTeam)).Methods("POST")
    39  	api.BaseRoutes.NeedTeam.Handle("/remove_user_from_team", api.ApiUserRequired(removeUserFromTeam)).Methods("POST")
    40  
    41  	// These should be moved to the global admin console
    42  	api.BaseRoutes.NeedTeam.Handle("/import_team", api.ApiUserRequired(importTeam)).Methods("POST")
    43  	api.BaseRoutes.Teams.Handle("/add_user_to_team_from_invite", api.ApiUserRequiredMfa(addUserToTeamFromInvite)).Methods("POST")
    44  }
    45  
    46  func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
    47  	team := model.TeamFromJson(r.Body)
    48  
    49  	if team == nil {
    50  		c.SetInvalidParam("createTeam", "team")
    51  		return
    52  	}
    53  
    54  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_CREATE_TEAM) {
    55  		c.Err = model.NewAppError("createTeam", "api.team.is_team_creation_allowed.disabled.app_error", nil, "", http.StatusForbidden)
    56  		return
    57  	}
    58  
    59  	rteam, err := c.App.CreateTeamWithUser(team, c.Session.UserId)
    60  	if err != nil {
    61  		c.Err = err
    62  		return
    63  	}
    64  
    65  	// Don't sanitize the team here since the user will be a team admin and their session won't reflect that yet
    66  
    67  	w.Write([]byte(rteam.ToJson()))
    68  }
    69  
    70  func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
    71  	var teams []*model.Team
    72  	var err *model.AppError
    73  
    74  	if teams, err = c.App.GetAllOpenTeams(); err != nil {
    75  		c.Err = err
    76  		return
    77  	}
    78  
    79  	m := make(map[string]*model.Team)
    80  	for _, v := range teams {
    81  		m[v.Id] = v
    82  	}
    83  
    84  	sanitizeTeamMap(c, m)
    85  
    86  	w.Write([]byte(model.TeamMapToJson(m)))
    87  }
    88  
    89  // Gets all teams which the current user can has access to. If the user is a System Admin, this will be all teams
    90  // on the server. Otherwise, it will only be the teams of which the user is a member.
    91  func getAll(c *Context, w http.ResponseWriter, r *http.Request) {
    92  	var teams []*model.Team
    93  	var err *model.AppError
    94  
    95  	if c.App.HasPermissionTo(c.Session.UserId, model.PERMISSION_MANAGE_SYSTEM) {
    96  		teams, err = c.App.GetAllTeams()
    97  	} else {
    98  		teams, err = c.App.GetTeamsForUser(c.Session.UserId)
    99  	}
   100  
   101  	if err != nil {
   102  		c.Err = err
   103  		return
   104  	}
   105  
   106  	m := make(map[string]*model.Team)
   107  	for _, v := range teams {
   108  		m[v.Id] = v
   109  	}
   110  
   111  	sanitizeTeamMap(c, m)
   112  
   113  	w.Write([]byte(model.TeamMapToJson(m)))
   114  }
   115  
   116  func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   117  	invites := model.InvitesFromJson(r.Body)
   118  
   119  	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_INVITE_USER) {
   120  		c.SetPermissionError(model.PERMISSION_INVITE_USER)
   121  		return
   122  	}
   123  
   124  	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
   125  		c.SetPermissionError(model.PERMISSION_INVITE_USER)
   126  		return
   127  	}
   128  
   129  	if err := c.App.InviteNewUsersToTeam(invites.ToEmailList(), c.TeamId, c.Session.UserId); err != nil {
   130  		c.Err = err
   131  		return
   132  	}
   133  
   134  	w.Write([]byte(invites.ToJson()))
   135  }
   136  
   137  func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   138  	params := model.MapFromJson(r.Body)
   139  	userId := params["user_id"]
   140  
   141  	if len(userId) != 26 {
   142  		c.SetInvalidParam("addUserToTeam", "user_id")
   143  		return
   144  	}
   145  
   146  	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
   147  		c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
   148  		return
   149  	}
   150  
   151  	if _, err := c.App.AddUserToTeam(c.TeamId, userId, ""); err != nil {
   152  		c.Err = err
   153  		return
   154  	}
   155  
   156  	w.Write([]byte(model.MapToJson(params)))
   157  }
   158  
   159  func removeUserFromTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   160  	params := model.MapFromJson(r.Body)
   161  	userId := params["user_id"]
   162  
   163  	if len(userId) != 26 {
   164  		c.SetInvalidParam("removeUserFromTeam", "user_id")
   165  		return
   166  	}
   167  
   168  	if c.Session.UserId != userId {
   169  		if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_REMOVE_USER_FROM_TEAM) {
   170  			c.SetPermissionError(model.PERMISSION_REMOVE_USER_FROM_TEAM)
   171  			return
   172  		}
   173  	}
   174  
   175  	if err := c.App.RemoveUserFromTeam(c.TeamId, userId, c.Session.UserId); err != nil {
   176  		c.Err = err
   177  		return
   178  	}
   179  
   180  	w.Write([]byte(model.MapToJson(params)))
   181  }
   182  
   183  func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) {
   184  	params := model.MapFromJson(r.Body)
   185  	tokenId := params["token"]
   186  	inviteId := params["invite_id"]
   187  
   188  	var team *model.Team
   189  	var err *model.AppError
   190  
   191  	if len(tokenId) > 0 {
   192  		team, err = c.App.AddUserToTeamByToken(c.Session.UserId, tokenId)
   193  	} else if len(inviteId) > 0 {
   194  		team, err = c.App.AddUserToTeamByInviteId(inviteId, c.Session.UserId)
   195  	} else {
   196  		c.Err = model.NewAppError("addUserToTeamFromInvite", "api.user.create_user.signup_link_invalid.app_error", nil, "", http.StatusBadRequest)
   197  		return
   198  	}
   199  
   200  	if err != nil {
   201  		c.Err = err
   202  		return
   203  	}
   204  
   205  	c.App.SanitizeTeam(c.Session, team)
   206  
   207  	w.Write([]byte(team.ToJson()))
   208  }
   209  
   210  func findTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
   211  
   212  	m := model.MapFromJson(r.Body)
   213  	name := strings.ToLower(strings.TrimSpace(m["name"]))
   214  
   215  	found := c.App.FindTeamByName(name)
   216  
   217  	if found {
   218  		w.Write([]byte("true"))
   219  	} else {
   220  		w.Write([]byte("false"))
   221  	}
   222  }
   223  
   224  func getTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
   225  	params := mux.Vars(r)
   226  	teamname := params["team_name"]
   227  
   228  	if team, err := c.App.GetTeamByName(teamname); err != nil {
   229  		c.Err = err
   230  		return
   231  	} else {
   232  		if (!team.AllowOpenInvite || team.Type != model.TEAM_OPEN) && c.Session.GetTeamByTeamId(team.Id) == nil {
   233  			if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   234  				c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   235  				return
   236  			}
   237  		}
   238  
   239  		c.App.SanitizeTeam(c.Session, team)
   240  
   241  		w.Write([]byte(team.ToJson()))
   242  		return
   243  	}
   244  }
   245  
   246  func getMyTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   247  	if len(c.Session.TeamMembers) > 0 {
   248  		w.Write([]byte(model.TeamMembersToJson(c.Session.TeamMembers)))
   249  	} else {
   250  		if members, err := c.App.GetTeamMembersForUser(c.Session.UserId); err != nil {
   251  			c.Err = err
   252  			return
   253  		} else {
   254  			w.Write([]byte(model.TeamMembersToJson(members)))
   255  		}
   256  	}
   257  }
   258  
   259  func getMyTeamsUnread(c *Context, w http.ResponseWriter, r *http.Request) {
   260  	teamId := r.URL.Query().Get("id")
   261  
   262  	if unreads, err := c.App.GetTeamsUnreadForUser(teamId, c.Session.UserId); err != nil {
   263  		c.Err = err
   264  		return
   265  	} else {
   266  		w.Write([]byte(model.TeamsUnreadToJson(unreads)))
   267  	}
   268  }
   269  
   270  func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   271  
   272  	team := model.TeamFromJson(r.Body)
   273  	if team == nil {
   274  		c.SetInvalidParam("updateTeam", "team")
   275  		return
   276  	}
   277  
   278  	team.Id = c.TeamId
   279  
   280  	if !c.App.SessionHasPermissionToTeam(c.Session, team.Id, model.PERMISSION_MANAGE_TEAM) {
   281  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
   282  		return
   283  	}
   284  
   285  	var err *model.AppError
   286  	var updatedTeam *model.Team
   287  
   288  	updatedTeam, err = c.App.UpdateTeam(team)
   289  	if err != nil {
   290  		c.Err = err
   291  		return
   292  	}
   293  
   294  	c.App.SanitizeTeam(c.Session, updatedTeam)
   295  
   296  	w.Write([]byte(updatedTeam.ToJson()))
   297  }
   298  
   299  func updateMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   300  	props := model.MapFromJson(r.Body)
   301  
   302  	userId := props["user_id"]
   303  	if len(userId) != 26 {
   304  		c.SetInvalidParam("updateMemberRoles", "user_id")
   305  		return
   306  	}
   307  
   308  	teamId := c.TeamId
   309  
   310  	newRoles := props["new_roles"]
   311  	if !(model.IsValidUserRoles(newRoles)) {
   312  		c.SetInvalidParam("updateMemberRoles", "new_roles")
   313  		return
   314  	}
   315  
   316  	if !c.App.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_TEAM_ROLES) {
   317  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM_ROLES)
   318  		return
   319  	}
   320  
   321  	if _, err := c.App.UpdateTeamMemberRoles(teamId, userId, newRoles); err != nil {
   322  		c.Err = err
   323  		return
   324  	}
   325  
   326  	rdata := map[string]string{}
   327  	rdata["status"] = "ok"
   328  	w.Write([]byte(model.MapToJson(rdata)))
   329  }
   330  
   331  func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   332  
   333  	if len(c.TeamId) == 0 {
   334  		return
   335  	}
   336  
   337  	if team, err := c.App.GetTeam(c.TeamId); err != nil {
   338  		c.Err = err
   339  		return
   340  	} else if c.HandleEtag(team.Etag(), "Get My Team", w, r) {
   341  		return
   342  	} else {
   343  		w.Header().Set(model.HEADER_ETAG_SERVER, team.Etag())
   344  
   345  		c.App.SanitizeTeam(c.Session, team)
   346  
   347  		w.Write([]byte(team.ToJson()))
   348  		return
   349  	}
   350  }
   351  
   352  func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) {
   353  	if c.Session.GetTeamByTeamId(c.TeamId) == nil {
   354  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
   355  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   356  			return
   357  		}
   358  	}
   359  
   360  	stats, err := c.App.GetTeamStats(c.TeamId)
   361  	if err != nil {
   362  		c.Err = err
   363  		return
   364  	}
   365  
   366  	w.Write([]byte(stats.ToJson()))
   367  }
   368  
   369  func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   370  	if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_IMPORT_TEAM) {
   371  		c.SetPermissionError(model.PERMISSION_IMPORT_TEAM)
   372  		return
   373  	}
   374  
   375  	if err := r.ParseMultipartForm(10000000); err != nil {
   376  		c.Err = model.NewAppError("importTeam", "api.team.import_team.parse.app_error", nil, err.Error(), http.StatusBadRequest)
   377  		return
   378  	}
   379  
   380  	importFromArray, ok := r.MultipartForm.Value["importFrom"]
   381  	if !ok || len(importFromArray) < 1 {
   382  		c.Err = model.NewAppError("importTeam", "api.team.import_team.no_import_from.app_error", nil, "", http.StatusBadRequest)
   383  		return
   384  	}
   385  	importFrom := importFromArray[0]
   386  
   387  	fileSizeStr, ok := r.MultipartForm.Value["filesize"]
   388  	if !ok || len(fileSizeStr) < 1 {
   389  		c.Err = model.NewAppError("importTeam", "api.team.import_team.unavailable.app_error", nil, "", http.StatusBadRequest)
   390  		return
   391  	}
   392  
   393  	fileSize, err := strconv.ParseInt(fileSizeStr[0], 10, 64)
   394  	if err != nil {
   395  		c.Err = model.NewAppError("importTeam", "api.team.import_team.integer.app_error", nil, "", http.StatusBadRequest)
   396  		return
   397  	}
   398  
   399  	fileInfoArray, ok := r.MultipartForm.File["file"]
   400  	if !ok {
   401  		c.Err = model.NewAppError("importTeam", "api.team.import_team.no_file.app_error", nil, "", http.StatusBadRequest)
   402  		return
   403  	}
   404  
   405  	if len(fileInfoArray) <= 0 {
   406  		c.Err = model.NewAppError("importTeam", "api.team.import_team.array.app_error", nil, "", http.StatusBadRequest)
   407  		return
   408  	}
   409  
   410  	fileInfo := fileInfoArray[0]
   411  
   412  	fileData, err := fileInfo.Open()
   413  	if err != nil {
   414  		c.Err = model.NewAppError("importTeam", "api.team.import_team.open.app_error", nil, err.Error(), http.StatusBadRequest)
   415  		return
   416  	}
   417  	defer fileData.Close()
   418  
   419  	var log *bytes.Buffer
   420  	switch importFrom {
   421  	case "slack":
   422  		var err *model.AppError
   423  		if err, log = c.App.SlackImport(fileData, fileSize, c.TeamId); err != nil {
   424  			c.Err = err
   425  			c.Err.StatusCode = http.StatusBadRequest
   426  		}
   427  	}
   428  
   429  	w.Header().Set("Content-Disposition", "attachment; filename=MattermostImportLog.txt")
   430  	w.Header().Set("Content-Type", "application/octet-stream")
   431  	if c.Err != nil {
   432  		w.WriteHeader(c.Err.StatusCode)
   433  	}
   434  	io.Copy(w, bytes.NewReader(log.Bytes()))
   435  	//http.ServeContent(w, r, "MattermostImportLog.txt", time.Now(), bytes.NewReader(log.Bytes()))
   436  }
   437  
   438  func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
   439  	m := model.MapFromJson(r.Body)
   440  	inviteId := m["invite_id"]
   441  
   442  	if team, err := c.App.GetTeamByInviteId(inviteId); err != nil {
   443  		c.Err = err
   444  		return
   445  	} else {
   446  		if !(team.Type == model.TEAM_OPEN) {
   447  			c.Err = model.NewAppError("getInviteInfo", "api.team.get_invite_info.not_open_team", nil, "id="+inviteId, http.StatusBadRequest)
   448  			return
   449  		}
   450  
   451  		result := map[string]string{}
   452  		result["display_name"] = team.DisplayName
   453  		result["description"] = team.Description
   454  		result["name"] = team.Name
   455  		result["id"] = team.Id
   456  		w.Write([]byte(model.MapToJson(result)))
   457  	}
   458  }
   459  
   460  func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   461  	params := mux.Vars(r)
   462  
   463  	offset, err := strconv.Atoi(params["offset"])
   464  	if err != nil {
   465  		c.SetInvalidParam("getTeamMembers", "offset")
   466  		return
   467  	}
   468  
   469  	limit, err := strconv.Atoi(params["limit"])
   470  	if err != nil {
   471  		c.SetInvalidParam("getTeamMembers", "limit")
   472  		return
   473  	}
   474  
   475  	if c.Session.GetTeamByTeamId(c.TeamId) == nil {
   476  		if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SYSTEM) {
   477  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   478  			return
   479  		}
   480  	}
   481  
   482  	if members, err := c.App.GetTeamMembers(c.TeamId, offset, limit); err != nil {
   483  		c.Err = err
   484  		return
   485  	} else {
   486  		w.Write([]byte(model.TeamMembersToJson(members)))
   487  		return
   488  	}
   489  }
   490  
   491  func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
   492  	params := mux.Vars(r)
   493  
   494  	userId := params["user_id"]
   495  	if len(userId) < 26 {
   496  		c.SetInvalidParam("getTeamMember", "user_id")
   497  		return
   498  	}
   499  
   500  	if c.Session.GetTeamByTeamId(c.TeamId) == nil {
   501  		if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SYSTEM) {
   502  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   503  			return
   504  		}
   505  	}
   506  
   507  	if member, err := c.App.GetTeamMember(c.TeamId, userId); err != nil {
   508  		c.Err = err
   509  		return
   510  	} else {
   511  		w.Write([]byte(member.ToJson()))
   512  		return
   513  	}
   514  }
   515  
   516  func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
   517  	userIds := model.ArrayFromJson(r.Body)
   518  	if len(userIds) == 0 {
   519  		c.SetInvalidParam("getTeamMembersByIds", "user_ids")
   520  		return
   521  	}
   522  
   523  	if c.Session.GetTeamByTeamId(c.TeamId) == nil {
   524  		if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SYSTEM) {
   525  			c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   526  			return
   527  		}
   528  	}
   529  
   530  	if members, err := c.App.GetTeamMembersByIds(c.TeamId, userIds); err != nil {
   531  		c.Err = err
   532  		return
   533  	} else {
   534  		w.Write([]byte(model.TeamMembersToJson(members)))
   535  		return
   536  	}
   537  }
   538  
   539  func sanitizeTeamMap(c *Context, teams map[string]*model.Team) {
   540  	for _, team := range teams {
   541  		c.App.SanitizeTeam(c.Session, team)
   542  	}
   543  }