github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/api4/team.go (about)

     1  // Copyright (c) 2017-present Xenia, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/base64"
     9  	"encoding/json"
    10  	"fmt"
    11  	"io"
    12  	"io/ioutil"
    13  	"net/http"
    14  	"regexp"
    15  	"strconv"
    16  	"strings"
    17  
    18  	"github.com/xzl8028/xenia-server/model"
    19  )
    20  
    21  const (
    22  	MAX_ADD_MEMBERS_BATCH    = 20
    23  	MAXIMUM_BULK_IMPORT_SIZE = 10 * 1024 * 1024
    24  	groupIDsParamPattern     = "[^a-zA-Z0-9,]*"
    25  )
    26  
    27  var groupIDsQueryParamRegex *regexp.Regexp
    28  
    29  func init() {
    30  	groupIDsQueryParamRegex = regexp.MustCompile(groupIDsParamPattern)
    31  }
    32  
    33  func (api *API) InitTeam() {
    34  	api.BaseRoutes.Teams.Handle("", api.ApiSessionRequired(createTeam)).Methods("POST")
    35  	api.BaseRoutes.Teams.Handle("", api.ApiSessionRequired(getAllTeams)).Methods("GET")
    36  	api.BaseRoutes.Teams.Handle("/{team_id:[A-Za-z0-9]+}/scheme", api.ApiSessionRequired(updateTeamScheme)).Methods("PUT")
    37  	api.BaseRoutes.Teams.Handle("/search", api.ApiSessionRequired(searchTeams)).Methods("POST")
    38  	api.BaseRoutes.TeamsForUser.Handle("", api.ApiSessionRequired(getTeamsForUser)).Methods("GET")
    39  	api.BaseRoutes.TeamsForUser.Handle("/unread", api.ApiSessionRequired(getTeamsUnreadForUser)).Methods("GET")
    40  
    41  	api.BaseRoutes.Team.Handle("", api.ApiSessionRequired(getTeam)).Methods("GET")
    42  	api.BaseRoutes.Team.Handle("", api.ApiSessionRequired(updateTeam)).Methods("PUT")
    43  	api.BaseRoutes.Team.Handle("", api.ApiSessionRequired(deleteTeam)).Methods("DELETE")
    44  	api.BaseRoutes.Team.Handle("/patch", api.ApiSessionRequired(patchTeam)).Methods("PUT")
    45  	api.BaseRoutes.Team.Handle("/stats", api.ApiSessionRequired(getTeamStats)).Methods("GET")
    46  	api.BaseRoutes.Team.Handle("/regenerate_invite_id", api.ApiSessionRequired(regenerateTeamInviteId)).Methods("POST")
    47  
    48  	api.BaseRoutes.Team.Handle("/image", api.ApiSessionRequiredTrustRequester(getTeamIcon)).Methods("GET")
    49  	api.BaseRoutes.Team.Handle("/image", api.ApiSessionRequired(setTeamIcon)).Methods("POST")
    50  	api.BaseRoutes.Team.Handle("/image", api.ApiSessionRequired(removeTeamIcon)).Methods("DELETE")
    51  
    52  	api.BaseRoutes.TeamMembers.Handle("", api.ApiSessionRequired(getTeamMembers)).Methods("GET")
    53  	api.BaseRoutes.TeamMembers.Handle("/ids", api.ApiSessionRequired(getTeamMembersByIds)).Methods("POST")
    54  	api.BaseRoutes.TeamMembersForUser.Handle("", api.ApiSessionRequired(getTeamMembersForUser)).Methods("GET")
    55  	api.BaseRoutes.TeamMembers.Handle("", api.ApiSessionRequired(addTeamMember)).Methods("POST")
    56  	api.BaseRoutes.Teams.Handle("/members/invite", api.ApiSessionRequired(addUserToTeamFromInvite)).Methods("POST")
    57  	api.BaseRoutes.TeamMembers.Handle("/batch", api.ApiSessionRequired(addTeamMembers)).Methods("POST")
    58  	api.BaseRoutes.TeamMember.Handle("", api.ApiSessionRequired(removeTeamMember)).Methods("DELETE")
    59  
    60  	api.BaseRoutes.TeamForUser.Handle("/unread", api.ApiSessionRequired(getTeamUnread)).Methods("GET")
    61  
    62  	api.BaseRoutes.TeamByName.Handle("", api.ApiSessionRequired(getTeamByName)).Methods("GET")
    63  	api.BaseRoutes.TeamMember.Handle("", api.ApiSessionRequired(getTeamMember)).Methods("GET")
    64  	api.BaseRoutes.TeamByName.Handle("/exists", api.ApiSessionRequired(teamExists)).Methods("GET")
    65  	api.BaseRoutes.TeamMember.Handle("/roles", api.ApiSessionRequired(updateTeamMemberRoles)).Methods("PUT")
    66  	api.BaseRoutes.TeamMember.Handle("/schemeRoles", api.ApiSessionRequired(updateTeamMemberSchemeRoles)).Methods("PUT")
    67  	api.BaseRoutes.Team.Handle("/import", api.ApiSessionRequired(importTeam)).Methods("POST")
    68  	api.BaseRoutes.Team.Handle("/invite/email", api.ApiSessionRequired(inviteUsersToTeam)).Methods("POST")
    69  	api.BaseRoutes.Teams.Handle("/invites/email", api.ApiSessionRequired(invalidateAllEmailInvites)).Methods("DELETE")
    70  	api.BaseRoutes.Teams.Handle("/invite/{invite_id:[A-Za-z0-9]+}", api.ApiHandler(getInviteInfo)).Methods("GET")
    71  
    72  	api.BaseRoutes.Teams.Handle("/{team_id:[A-Za-z0-9]+}/members_minus_group_members", api.ApiSessionRequired(teamMembersMinusGroupMembers)).Methods("GET")
    73  }
    74  
    75  func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
    76  	team := model.TeamFromJson(r.Body)
    77  	if team == nil {
    78  		c.SetInvalidParam("team")
    79  		return
    80  	}
    81  
    82  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_CREATE_TEAM) {
    83  		c.Err = model.NewAppError("createTeam", "api.team.is_team_creation_allowed.disabled.app_error", nil, "", http.StatusForbidden)
    84  		return
    85  	}
    86  
    87  	rteam, err := c.App.CreateTeamWithUser(team, c.App.Session.UserId)
    88  	if err != nil {
    89  		c.Err = err
    90  		return
    91  	}
    92  
    93  	// Don't sanitize the team here since the user will be a team admin and their session won't reflect that yet
    94  
    95  	w.WriteHeader(http.StatusCreated)
    96  	w.Write([]byte(rteam.ToJson()))
    97  }
    98  
    99  func getTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   100  	c.RequireTeamId()
   101  	if c.Err != nil {
   102  		return
   103  	}
   104  
   105  	team, err := c.App.GetTeam(c.Params.TeamId)
   106  	if err != nil {
   107  		c.Err = err
   108  		return
   109  	}
   110  
   111  	if (!team.AllowOpenInvite || team.Type != model.TEAM_OPEN) && !c.App.SessionHasPermissionToTeam(c.App.Session, team.Id, model.PERMISSION_VIEW_TEAM) {
   112  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   113  		return
   114  	}
   115  
   116  	c.App.SanitizeTeam(c.App.Session, team)
   117  	w.Write([]byte(team.ToJson()))
   118  }
   119  
   120  func getTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
   121  	c.RequireTeamName()
   122  	if c.Err != nil {
   123  		return
   124  	}
   125  
   126  	team, err := c.App.GetTeamByName(c.Params.TeamName)
   127  	if err != nil {
   128  		c.Err = err
   129  		return
   130  	}
   131  
   132  	if (!team.AllowOpenInvite || team.Type != model.TEAM_OPEN) && !c.App.SessionHasPermissionToTeam(c.App.Session, team.Id, model.PERMISSION_VIEW_TEAM) {
   133  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   134  		return
   135  	}
   136  
   137  	c.App.SanitizeTeam(c.App.Session, team)
   138  	w.Write([]byte(team.ToJson()))
   139  }
   140  
   141  func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   142  	c.RequireTeamId()
   143  	if c.Err != nil {
   144  		return
   145  	}
   146  
   147  	team := model.TeamFromJson(r.Body)
   148  
   149  	if team == nil {
   150  		c.SetInvalidParam("team")
   151  		return
   152  	}
   153  
   154  	// The team being updated in the payload must be the same one as indicated in the URL.
   155  	if team.Id != c.Params.TeamId {
   156  		c.SetInvalidParam("id")
   157  		return
   158  	}
   159  
   160  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
   161  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
   162  		return
   163  	}
   164  
   165  	updatedTeam, err := c.App.UpdateTeam(team)
   166  	if err != nil {
   167  		c.Err = err
   168  		return
   169  	}
   170  
   171  	c.App.SanitizeTeam(c.App.Session, updatedTeam)
   172  	w.Write([]byte(updatedTeam.ToJson()))
   173  }
   174  
   175  func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   176  	c.RequireTeamId()
   177  	if c.Err != nil {
   178  		return
   179  	}
   180  
   181  	team := model.TeamPatchFromJson(r.Body)
   182  
   183  	if team == nil {
   184  		c.SetInvalidParam("team")
   185  		return
   186  	}
   187  
   188  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
   189  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
   190  		return
   191  	}
   192  
   193  	patchedTeam, err := c.App.PatchTeam(c.Params.TeamId, team)
   194  
   195  	if err != nil {
   196  		c.Err = err
   197  		return
   198  	}
   199  
   200  	c.App.SanitizeTeam(c.App.Session, patchedTeam)
   201  
   202  	c.LogAudit("")
   203  	w.Write([]byte(patchedTeam.ToJson()))
   204  }
   205  
   206  func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request) {
   207  	c.RequireTeamId()
   208  	if c.Err != nil {
   209  		return
   210  	}
   211  
   212  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
   213  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
   214  		return
   215  	}
   216  
   217  	patchedTeam, err := c.App.RegenerateTeamInviteId(c.Params.TeamId)
   218  	if err != nil {
   219  		c.Err = err
   220  		return
   221  	}
   222  
   223  	c.App.SanitizeTeam(c.App.Session, patchedTeam)
   224  
   225  	c.LogAudit("")
   226  	w.Write([]byte(patchedTeam.ToJson()))
   227  }
   228  
   229  func deleteTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   230  	c.RequireTeamId()
   231  	if c.Err != nil {
   232  		return
   233  	}
   234  
   235  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
   236  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
   237  		return
   238  	}
   239  
   240  	var err *model.AppError
   241  	if c.Params.Permanent && *c.App.Config().ServiceSettings.EnableAPITeamDeletion {
   242  		err = c.App.PermanentDeleteTeamId(c.Params.TeamId)
   243  	} else {
   244  		err = c.App.SoftDeleteTeam(c.Params.TeamId)
   245  	}
   246  
   247  	if err != nil {
   248  		c.Err = err
   249  		return
   250  	}
   251  
   252  	ReturnStatusOK(w)
   253  }
   254  
   255  func getTeamsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   256  	c.RequireUserId()
   257  	if c.Err != nil {
   258  		return
   259  	}
   260  
   261  	if c.App.Session.UserId != c.Params.UserId && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   262  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   263  		return
   264  	}
   265  
   266  	teams, err := c.App.GetTeamsForUser(c.Params.UserId)
   267  	if err != nil {
   268  		c.Err = err
   269  		return
   270  	}
   271  
   272  	c.App.SanitizeTeams(c.App.Session, teams)
   273  	w.Write([]byte(model.TeamListToJson(teams)))
   274  }
   275  
   276  func getTeamsUnreadForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   277  	c.RequireUserId()
   278  	if c.Err != nil {
   279  		return
   280  	}
   281  
   282  	if c.App.Session.UserId != c.Params.UserId && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   283  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   284  		return
   285  	}
   286  
   287  	// optional team id to be excluded from the result
   288  	teamId := r.URL.Query().Get("exclude_team")
   289  
   290  	unreadTeamsList, err := c.App.GetTeamsUnreadForUser(teamId, c.Params.UserId)
   291  	if err != nil {
   292  		c.Err = err
   293  		return
   294  	}
   295  
   296  	w.Write([]byte(model.TeamsUnreadToJson(unreadTeamsList)))
   297  }
   298  
   299  func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
   300  	c.RequireTeamId().RequireUserId()
   301  	if c.Err != nil {
   302  		return
   303  	}
   304  
   305  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) {
   306  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   307  		return
   308  	}
   309  
   310  	canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
   311  	if err != nil {
   312  		c.Err = err
   313  		return
   314  	}
   315  
   316  	if !canSee {
   317  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   318  		return
   319  	}
   320  
   321  	team, err := c.App.GetTeamMember(c.Params.TeamId, c.Params.UserId)
   322  	if err != nil {
   323  		c.Err = err
   324  		return
   325  	}
   326  
   327  	w.Write([]byte(team.ToJson()))
   328  }
   329  
   330  func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   331  	c.RequireTeamId()
   332  	if c.Err != nil {
   333  		return
   334  	}
   335  
   336  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) {
   337  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   338  		return
   339  	}
   340  
   341  	restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
   342  	if err != nil {
   343  		c.Err = err
   344  		return
   345  	}
   346  
   347  	members, err := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, restrictions)
   348  	if err != nil {
   349  		c.Err = err
   350  		return
   351  	}
   352  
   353  	w.Write([]byte(model.TeamMembersToJson(members)))
   354  }
   355  
   356  func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   357  	c.RequireUserId()
   358  	if c.Err != nil {
   359  		return
   360  	}
   361  
   362  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
   363  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   364  		return
   365  	}
   366  
   367  	canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
   368  	if err != nil {
   369  		c.Err = err
   370  		return
   371  	}
   372  
   373  	if !canSee {
   374  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   375  		return
   376  	}
   377  
   378  	members, err := c.App.GetTeamMembersForUser(c.Params.UserId)
   379  	if err != nil {
   380  		c.Err = err
   381  		return
   382  	}
   383  
   384  	w.Write([]byte(model.TeamMembersToJson(members)))
   385  }
   386  
   387  func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
   388  	c.RequireTeamId()
   389  	if c.Err != nil {
   390  		return
   391  	}
   392  
   393  	userIds := model.ArrayFromJson(r.Body)
   394  
   395  	if len(userIds) == 0 {
   396  		c.SetInvalidParam("user_ids")
   397  		return
   398  	}
   399  
   400  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) {
   401  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   402  		return
   403  	}
   404  
   405  	restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
   406  	if err != nil {
   407  		c.Err = err
   408  		return
   409  	}
   410  
   411  	members, err := c.App.GetTeamMembersByIds(c.Params.TeamId, userIds, restrictions)
   412  	if err != nil {
   413  		c.Err = err
   414  		return
   415  	}
   416  
   417  	w.Write([]byte(model.TeamMembersToJson(members)))
   418  }
   419  
   420  func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
   421  	c.RequireTeamId()
   422  	if c.Err != nil {
   423  		return
   424  	}
   425  
   426  	var err *model.AppError
   427  	member := model.TeamMemberFromJson(r.Body)
   428  	if member.TeamId != c.Params.TeamId {
   429  		c.SetInvalidParam("team_id")
   430  		return
   431  	}
   432  
   433  	if len(member.UserId) != 26 {
   434  		c.SetInvalidParam("user_id")
   435  		return
   436  	}
   437  
   438  	if member.UserId == c.App.Session.UserId {
   439  		var team *model.Team
   440  		team, err = c.App.GetTeam(member.TeamId)
   441  		if err != nil {
   442  			c.Err = err
   443  			return
   444  		}
   445  
   446  		if team.AllowOpenInvite && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_JOIN_PUBLIC_TEAMS) {
   447  			c.SetPermissionError(model.PERMISSION_JOIN_PUBLIC_TEAMS)
   448  			return
   449  		}
   450  		if !team.AllowOpenInvite && !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_JOIN_PRIVATE_TEAMS) {
   451  			c.SetPermissionError(model.PERMISSION_JOIN_PRIVATE_TEAMS)
   452  			return
   453  		}
   454  	} else {
   455  		if !c.App.SessionHasPermissionToTeam(c.App.Session, member.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
   456  			c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
   457  			return
   458  		}
   459  	}
   460  
   461  	team, err := c.App.GetTeam(member.TeamId)
   462  	if err != nil {
   463  		c.Err = err
   464  		return
   465  	}
   466  
   467  	if team.IsGroupConstrained() {
   468  		nonMembers, err := c.App.FilterNonGroupTeamMembers([]string{member.UserId}, team)
   469  		if err != nil {
   470  			if v, ok := err.(*model.AppError); ok {
   471  				c.Err = v
   472  			} else {
   473  				c.Err = model.NewAppError("addTeamMember", "api.team.add_members.error", nil, err.Error(), http.StatusBadRequest)
   474  			}
   475  			return
   476  		}
   477  		if len(nonMembers) > 0 {
   478  			c.Err = model.NewAppError("addTeamMember", "api.team.add_members.user_denied", map[string]interface{}{"UserIDs": nonMembers}, "", http.StatusBadRequest)
   479  			return
   480  		}
   481  	}
   482  
   483  	member, err = c.App.AddTeamMember(member.TeamId, member.UserId)
   484  
   485  	if err != nil {
   486  		c.Err = err
   487  		return
   488  	}
   489  
   490  	w.WriteHeader(http.StatusCreated)
   491  	w.Write([]byte(member.ToJson()))
   492  }
   493  
   494  func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) {
   495  	tokenId := r.URL.Query().Get("token")
   496  	inviteId := r.URL.Query().Get("invite_id")
   497  
   498  	var member *model.TeamMember
   499  	var err *model.AppError
   500  
   501  	if len(tokenId) > 0 {
   502  		member, err = c.App.AddTeamMemberByToken(c.App.Session.UserId, tokenId)
   503  	} else if len(inviteId) > 0 {
   504  		member, err = c.App.AddTeamMemberByInviteId(inviteId, c.App.Session.UserId)
   505  	} else {
   506  		err = model.NewAppError("addTeamMember", "api.team.add_user_to_team.missing_parameter.app_error", nil, "", http.StatusBadRequest)
   507  	}
   508  
   509  	if err != nil {
   510  		c.Err = err
   511  		return
   512  	}
   513  
   514  	w.WriteHeader(http.StatusCreated)
   515  	w.Write([]byte(member.ToJson()))
   516  }
   517  
   518  func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   519  	c.RequireTeamId()
   520  	if c.Err != nil {
   521  		return
   522  	}
   523  
   524  	var err *model.AppError
   525  	members := model.TeamMembersFromJson(r.Body)
   526  
   527  	if len(members) > MAX_ADD_MEMBERS_BATCH {
   528  		c.SetInvalidParam("too many members in batch")
   529  		return
   530  	}
   531  
   532  	if len(members) == 0 {
   533  		c.SetInvalidParam("no members in batch")
   534  		return
   535  	}
   536  
   537  	var memberIDs []string
   538  	for _, member := range members {
   539  		memberIDs = append(memberIDs, member.UserId)
   540  	}
   541  
   542  	team, err := c.App.GetTeam(c.Params.TeamId)
   543  	if err != nil {
   544  		c.Err = err
   545  		return
   546  	}
   547  
   548  	if team.IsGroupConstrained() {
   549  		nonMembers, err := c.App.FilterNonGroupTeamMembers(memberIDs, team)
   550  		if err != nil {
   551  			if v, ok := err.(*model.AppError); ok {
   552  				c.Err = v
   553  			} else {
   554  				c.Err = model.NewAppError("addTeamMembers", "api.team.add_members.error", nil, err.Error(), http.StatusBadRequest)
   555  			}
   556  			return
   557  		}
   558  		if len(nonMembers) > 0 {
   559  			c.Err = model.NewAppError("addTeamMembers", "api.team.add_members.user_denied", map[string]interface{}{"UserIDs": nonMembers}, "", http.StatusBadRequest)
   560  			return
   561  		}
   562  	}
   563  
   564  	var userIds []string
   565  	for _, member := range members {
   566  		if member.TeamId != c.Params.TeamId {
   567  			c.SetInvalidParam("team_id for member with user_id=" + member.UserId)
   568  			return
   569  		}
   570  
   571  		if len(member.UserId) != 26 {
   572  			c.SetInvalidParam("user_id")
   573  			return
   574  		}
   575  
   576  		userIds = append(userIds, member.UserId)
   577  	}
   578  
   579  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
   580  		c.SetPermissionError(model.PERMISSION_ADD_USER_TO_TEAM)
   581  		return
   582  	}
   583  
   584  	members, err = c.App.AddTeamMembers(c.Params.TeamId, userIds, c.App.Session.UserId)
   585  
   586  	if err != nil {
   587  		c.Err = err
   588  		return
   589  	}
   590  
   591  	w.WriteHeader(http.StatusCreated)
   592  	w.Write([]byte(model.TeamMembersToJson(members)))
   593  }
   594  
   595  func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
   596  	c.RequireTeamId().RequireUserId()
   597  	if c.Err != nil {
   598  		return
   599  	}
   600  
   601  	if c.App.Session.UserId != c.Params.UserId {
   602  		if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_REMOVE_USER_FROM_TEAM) {
   603  			c.SetPermissionError(model.PERMISSION_REMOVE_USER_FROM_TEAM)
   604  			return
   605  		}
   606  	}
   607  
   608  	team, err := c.App.GetTeam(c.Params.TeamId)
   609  	if err != nil {
   610  		c.Err = err
   611  		return
   612  	}
   613  
   614  	if team.IsGroupConstrained() && (c.Params.UserId != c.App.Session.UserId) {
   615  		c.Err = model.NewAppError("removeTeamMember", "api.team.remove_member.group_constrained.app_error", nil, "", http.StatusBadRequest)
   616  		return
   617  	}
   618  
   619  	if err := c.App.RemoveUserFromTeam(c.Params.TeamId, c.Params.UserId, c.App.Session.UserId); err != nil {
   620  		c.Err = err
   621  		return
   622  	}
   623  
   624  	ReturnStatusOK(w)
   625  }
   626  
   627  func getTeamUnread(c *Context, w http.ResponseWriter, r *http.Request) {
   628  	c.RequireTeamId().RequireUserId()
   629  	if c.Err != nil {
   630  		return
   631  	}
   632  
   633  	if !c.App.SessionHasPermissionToUser(c.App.Session, c.Params.UserId) {
   634  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   635  		return
   636  	}
   637  
   638  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) {
   639  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   640  		return
   641  	}
   642  
   643  	unreadTeam, err := c.App.GetTeamUnread(c.Params.TeamId, c.Params.UserId)
   644  	if err != nil {
   645  		c.Err = err
   646  		return
   647  	}
   648  
   649  	w.Write([]byte(unreadTeam.ToJson()))
   650  }
   651  
   652  func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) {
   653  	c.RequireTeamId()
   654  	if c.Err != nil {
   655  		return
   656  	}
   657  
   658  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) {
   659  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   660  		return
   661  	}
   662  
   663  	stats, err := c.App.GetTeamStats(c.Params.TeamId)
   664  	if err != nil {
   665  		c.Err = err
   666  		return
   667  	}
   668  
   669  	w.Write([]byte(stats.ToJson()))
   670  }
   671  
   672  func updateTeamMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   673  	c.RequireTeamId().RequireUserId()
   674  	if c.Err != nil {
   675  		return
   676  	}
   677  
   678  	props := model.MapFromJson(r.Body)
   679  
   680  	newRoles := props["roles"]
   681  	if !model.IsValidUserRoles(newRoles) {
   682  		c.SetInvalidParam("team_member_roles")
   683  		return
   684  	}
   685  
   686  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM_ROLES) {
   687  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM_ROLES)
   688  		return
   689  	}
   690  
   691  	if _, err := c.App.UpdateTeamMemberRoles(c.Params.TeamId, c.Params.UserId, newRoles); err != nil {
   692  		c.Err = err
   693  		return
   694  	}
   695  
   696  	ReturnStatusOK(w)
   697  }
   698  
   699  func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   700  	c.RequireTeamId().RequireUserId()
   701  	if c.Err != nil {
   702  		return
   703  	}
   704  
   705  	schemeRoles := model.SchemeRolesFromJson(r.Body)
   706  	if schemeRoles == nil {
   707  		c.SetInvalidParam("scheme_roles")
   708  		return
   709  	}
   710  
   711  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM_ROLES) {
   712  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM_ROLES)
   713  		return
   714  	}
   715  
   716  	if _, err := c.App.UpdateTeamMemberSchemeRoles(c.Params.TeamId, c.Params.UserId, schemeRoles.SchemeGuest, schemeRoles.SchemeUser, schemeRoles.SchemeAdmin); err != nil {
   717  		c.Err = err
   718  		return
   719  	}
   720  
   721  	ReturnStatusOK(w)
   722  }
   723  
   724  func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
   725  	var teams []*model.Team
   726  	var err *model.AppError
   727  	var teamsWithCount *model.TeamsWithCount
   728  
   729  	if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) && c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
   730  		if c.Params.IncludeTotalCount {
   731  			teamsWithCount, err = c.App.GetAllTeamsPageWithCount(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
   732  		} else {
   733  			teams, err = c.App.GetAllTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
   734  		}
   735  	} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) {
   736  		teams, err = c.App.GetAllPrivateTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
   737  	} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
   738  		teams, err = c.App.GetAllPublicTeamsPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
   739  	}
   740  
   741  	if err != nil {
   742  		c.Err = err
   743  		return
   744  	}
   745  
   746  	c.App.SanitizeTeams(c.App.Session, teams)
   747  
   748  	var resBody []byte
   749  
   750  	if c.Params.IncludeTotalCount {
   751  		resBody = model.TeamsWithCountToJson(teamsWithCount)
   752  	} else {
   753  		resBody = []byte(model.TeamListToJson(teams))
   754  	}
   755  
   756  	w.Write(resBody)
   757  }
   758  
   759  func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) {
   760  	props := model.TeamSearchFromJson(r.Body)
   761  	if props == nil {
   762  		c.SetInvalidParam("team_search")
   763  		return
   764  	}
   765  
   766  	if len(props.Term) == 0 {
   767  		c.SetInvalidParam("term")
   768  		return
   769  	}
   770  
   771  	var teams []*model.Team
   772  	var err *model.AppError
   773  
   774  	if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) && c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
   775  		teams, err = c.App.SearchAllTeams(props.Term)
   776  	} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PRIVATE_TEAMS) {
   777  		teams, err = c.App.SearchPrivateTeams(props.Term)
   778  	} else if c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_LIST_PUBLIC_TEAMS) {
   779  		teams, err = c.App.SearchPublicTeams(props.Term)
   780  	} else {
   781  		teams = []*model.Team{}
   782  	}
   783  
   784  	if err != nil {
   785  		c.Err = err
   786  		return
   787  	}
   788  
   789  	c.App.SanitizeTeams(c.App.Session, teams)
   790  
   791  	w.Write([]byte(model.TeamListToJson(teams)))
   792  }
   793  
   794  func teamExists(c *Context, w http.ResponseWriter, r *http.Request) {
   795  	c.RequireTeamName()
   796  	if c.Err != nil {
   797  		return
   798  	}
   799  
   800  	resp := make(map[string]bool)
   801  
   802  	if _, err := c.App.GetTeamByName(c.Params.TeamName); err != nil {
   803  		resp["exists"] = false
   804  	} else {
   805  		resp["exists"] = true
   806  	}
   807  
   808  	w.Write([]byte(model.MapBoolToJson(resp)))
   809  }
   810  
   811  func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   812  	c.RequireTeamId()
   813  	if c.Err != nil {
   814  		return
   815  	}
   816  
   817  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_IMPORT_TEAM) {
   818  		c.SetPermissionError(model.PERMISSION_IMPORT_TEAM)
   819  		return
   820  	}
   821  
   822  	if err := r.ParseMultipartForm(MAXIMUM_BULK_IMPORT_SIZE); err != nil {
   823  		c.Err = model.NewAppError("importTeam", "api.team.import_team.parse.app_error", nil, err.Error(), http.StatusInternalServerError)
   824  		return
   825  	}
   826  
   827  	importFromArray, ok := r.MultipartForm.Value["importFrom"]
   828  	if !ok || len(importFromArray) < 1 {
   829  		c.Err = model.NewAppError("importTeam", "api.team.import_team.no_import_from.app_error", nil, "", http.StatusBadRequest)
   830  		return
   831  	}
   832  	importFrom := importFromArray[0]
   833  
   834  	fileSizeStr, ok := r.MultipartForm.Value["filesize"]
   835  	if !ok || len(fileSizeStr) < 1 {
   836  		c.Err = model.NewAppError("importTeam", "api.team.import_team.unavailable.app_error", nil, "", http.StatusBadRequest)
   837  		return
   838  	}
   839  
   840  	fileSize, err := strconv.ParseInt(fileSizeStr[0], 10, 64)
   841  	if err != nil {
   842  		c.Err = model.NewAppError("importTeam", "api.team.import_team.integer.app_error", nil, "", http.StatusBadRequest)
   843  		return
   844  	}
   845  
   846  	fileInfoArray, ok := r.MultipartForm.File["file"]
   847  	if !ok {
   848  		c.Err = model.NewAppError("importTeam", "api.team.import_team.no_file.app_error", nil, "", http.StatusBadRequest)
   849  		return
   850  	}
   851  
   852  	if len(fileInfoArray) <= 0 {
   853  		c.Err = model.NewAppError("importTeam", "api.team.import_team.array.app_error", nil, "", http.StatusBadRequest)
   854  		return
   855  	}
   856  
   857  	fileInfo := fileInfoArray[0]
   858  
   859  	fileData, err := fileInfo.Open()
   860  	if err != nil {
   861  		c.Err = model.NewAppError("importTeam", "api.team.import_team.open.app_error", nil, err.Error(), http.StatusBadRequest)
   862  		return
   863  	}
   864  	defer fileData.Close()
   865  
   866  	var log *bytes.Buffer
   867  	switch importFrom {
   868  	case "slack":
   869  		var err *model.AppError
   870  		if err, log = c.App.SlackImport(fileData, fileSize, c.Params.TeamId); err != nil {
   871  			c.Err = err
   872  			c.Err.StatusCode = http.StatusBadRequest
   873  		}
   874  	}
   875  
   876  	data := map[string]string{}
   877  	data["results"] = base64.StdEncoding.EncodeToString([]byte(log.Bytes()))
   878  	if c.Err != nil {
   879  		w.WriteHeader(c.Err.StatusCode)
   880  	}
   881  	w.Write([]byte(model.MapToJson(data)))
   882  }
   883  
   884  func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
   885  	c.RequireTeamId()
   886  	if c.Err != nil {
   887  		return
   888  	}
   889  
   890  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_INVITE_USER) {
   891  		c.SetPermissionError(model.PERMISSION_INVITE_USER)
   892  		return
   893  	}
   894  
   895  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
   896  		c.SetPermissionError(model.PERMISSION_INVITE_USER)
   897  		return
   898  	}
   899  
   900  	emailList := model.ArrayFromJson(r.Body)
   901  
   902  	if len(emailList) == 0 {
   903  		c.SetInvalidParam("user_email")
   904  		return
   905  	}
   906  
   907  	err := c.App.InviteNewUsersToTeam(emailList, c.Params.TeamId, c.App.Session.UserId)
   908  	if err != nil {
   909  		c.Err = err
   910  		return
   911  	}
   912  
   913  	ReturnStatusOK(w)
   914  }
   915  
   916  func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
   917  	c.RequireInviteId()
   918  	if c.Err != nil {
   919  		return
   920  	}
   921  
   922  	team, err := c.App.GetTeamByInviteId(c.Params.InviteId)
   923  	if err != nil {
   924  		c.Err = err
   925  		return
   926  	}
   927  
   928  	if team.Type != model.TEAM_OPEN {
   929  		c.Err = model.NewAppError("getInviteInfo", "api.team.get_invite_info.not_open_team", nil, "id="+c.Params.InviteId, http.StatusForbidden)
   930  		return
   931  	}
   932  
   933  	result := map[string]string{}
   934  	result["display_name"] = team.DisplayName
   935  	result["description"] = team.Description
   936  	result["name"] = team.Name
   937  	result["id"] = team.Id
   938  	w.Write([]byte(model.MapToJson(result)))
   939  }
   940  
   941  func invalidateAllEmailInvites(c *Context, w http.ResponseWriter, r *http.Request) {
   942  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
   943  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   944  		return
   945  	}
   946  
   947  	if err := c.App.InvalidateAllEmailInvites(); err != nil {
   948  		c.Err = err
   949  		return
   950  	}
   951  
   952  	ReturnStatusOK(w)
   953  }
   954  
   955  func getTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
   956  	c.RequireTeamId()
   957  	if c.Err != nil {
   958  		return
   959  	}
   960  
   961  	team, err := c.App.GetTeam(c.Params.TeamId)
   962  
   963  	if err != nil {
   964  		c.Err = err
   965  		return
   966  	}
   967  
   968  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) &&
   969  		(team.Type != model.TEAM_OPEN || !team.AllowOpenInvite) {
   970  		c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
   971  		return
   972  	}
   973  
   974  	etag := strconv.FormatInt(team.LastTeamIconUpdate, 10)
   975  
   976  	if c.HandleEtag(etag, "Get Team Icon", w, r) {
   977  		return
   978  	}
   979  
   980  	img, err := c.App.GetTeamIcon(team)
   981  	if err != nil {
   982  		c.Err = err
   983  		return
   984  	}
   985  
   986  	w.Header().Set("Content-Type", "image/png")
   987  	w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs
   988  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   989  	w.Write(img)
   990  }
   991  
   992  func setTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
   993  	defer io.Copy(ioutil.Discard, r.Body)
   994  
   995  	c.RequireTeamId()
   996  	if c.Err != nil {
   997  		return
   998  	}
   999  
  1000  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
  1001  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
  1002  		return
  1003  	}
  1004  
  1005  	if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize {
  1006  		c.Err = model.NewAppError("setTeamIcon", "api.team.set_team_icon.too_large.app_error", nil, "", http.StatusBadRequest)
  1007  		return
  1008  	}
  1009  
  1010  	if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil {
  1011  		c.Err = model.NewAppError("setTeamIcon", "api.team.set_team_icon.parse.app_error", nil, err.Error(), http.StatusBadRequest)
  1012  		return
  1013  	}
  1014  
  1015  	m := r.MultipartForm
  1016  
  1017  	imageArray, ok := m.File["image"]
  1018  	if !ok {
  1019  		c.Err = model.NewAppError("setTeamIcon", "api.team.set_team_icon.no_file.app_error", nil, "", http.StatusBadRequest)
  1020  		return
  1021  	}
  1022  
  1023  	if len(imageArray) <= 0 {
  1024  		c.Err = model.NewAppError("setTeamIcon", "api.team.set_team_icon.array.app_error", nil, "", http.StatusBadRequest)
  1025  		return
  1026  	}
  1027  
  1028  	imageData := imageArray[0]
  1029  
  1030  	if err := c.App.SetTeamIcon(c.Params.TeamId, imageData); err != nil {
  1031  		c.Err = err
  1032  		return
  1033  	}
  1034  
  1035  	c.LogAudit("")
  1036  	ReturnStatusOK(w)
  1037  }
  1038  
  1039  func removeTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
  1040  	c.RequireTeamId()
  1041  	if c.Err != nil {
  1042  		return
  1043  	}
  1044  
  1045  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
  1046  		c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
  1047  		return
  1048  	}
  1049  
  1050  	if err := c.App.RemoveTeamIcon(c.Params.TeamId); err != nil {
  1051  		c.Err = err
  1052  		return
  1053  	}
  1054  
  1055  	c.LogAudit("")
  1056  	ReturnStatusOK(w)
  1057  }
  1058  
  1059  func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) {
  1060  	c.RequireTeamId()
  1061  	if c.Err != nil {
  1062  		return
  1063  	}
  1064  
  1065  	schemeID := model.SchemeIDFromJson(r.Body)
  1066  	if schemeID == nil || (len(*schemeID) != 26 && *schemeID != "") {
  1067  		c.SetInvalidParam("scheme_id")
  1068  		return
  1069  	}
  1070  
  1071  	if c.App.License() == nil {
  1072  		c.Err = model.NewAppError("Api4.UpdateTeamScheme", "api.team.update_team_scheme.license.error", nil, "", http.StatusNotImplemented)
  1073  		return
  1074  	}
  1075  
  1076  	if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_MANAGE_SYSTEM) {
  1077  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1078  		return
  1079  	}
  1080  
  1081  	if *schemeID != "" {
  1082  		scheme, err := c.App.GetScheme(*schemeID)
  1083  		if err != nil {
  1084  			c.Err = err
  1085  			return
  1086  		}
  1087  
  1088  		if scheme.Scope != model.SCHEME_SCOPE_TEAM {
  1089  			c.Err = model.NewAppError("Api4.UpdateTeamScheme", "api.team.update_team_scheme.scheme_scope.error", nil, "", http.StatusBadRequest)
  1090  			return
  1091  		}
  1092  	}
  1093  
  1094  	team, err := c.App.GetTeam(c.Params.TeamId)
  1095  	if err != nil {
  1096  		c.Err = err
  1097  		return
  1098  	}
  1099  
  1100  	team.SchemeId = schemeID
  1101  
  1102  	_, err = c.App.UpdateTeamScheme(team)
  1103  	if err != nil {
  1104  		c.Err = err
  1105  		return
  1106  	}
  1107  
  1108  	ReturnStatusOK(w)
  1109  }
  1110  
  1111  func teamMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
  1112  	c.RequireTeamId()
  1113  	if c.Err != nil {
  1114  		return
  1115  	}
  1116  
  1117  	groupIDsParam := groupIDsQueryParamRegex.ReplaceAllString(c.Params.GroupIDs, "")
  1118  
  1119  	if len(groupIDsParam) < 26 {
  1120  		c.SetInvalidParam("group_ids")
  1121  		return
  1122  	}
  1123  
  1124  	groupIDs := []string{}
  1125  	for _, gid := range strings.Split(c.Params.GroupIDs, ",") {
  1126  		if len(gid) != 26 {
  1127  			c.SetInvalidParam("group_ids")
  1128  			return
  1129  		}
  1130  		groupIDs = append(groupIDs, gid)
  1131  	}
  1132  
  1133  	if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_MANAGE_SYSTEM) {
  1134  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
  1135  		return
  1136  	}
  1137  
  1138  	users, totalCount, err := c.App.TeamMembersMinusGroupMembers(
  1139  		c.Params.TeamId,
  1140  		groupIDs,
  1141  		c.Params.Page,
  1142  		c.Params.PerPage,
  1143  	)
  1144  	if err != nil {
  1145  		c.Err = err
  1146  		return
  1147  	}
  1148  
  1149  	b, marshalErr := json.Marshal(&model.UsersWithGroupsAndCount{
  1150  		Users: users,
  1151  		Count: totalCount,
  1152  	})
  1153  	if marshalErr != nil {
  1154  		c.Err = model.NewAppError("Api4.teamMembersMinusGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
  1155  		return
  1156  	}
  1157  
  1158  	w.Write(b)
  1159  }