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 }