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