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 }