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 }