github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/app/team.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "bytes" 8 "fmt" 9 "image" 10 "image/png" 11 "mime/multipart" 12 "net/http" 13 "net/url" 14 "strings" 15 16 "github.com/disintegration/imaging" 17 18 "github.com/mattermost/mattermost-server/mlog" 19 "github.com/mattermost/mattermost-server/model" 20 "github.com/mattermost/mattermost-server/utils" 21 ) 22 23 func (a *App) CreateTeam(team *model.Team) (*model.Team, *model.AppError) { 24 if result := <-a.Srv.Store.Team().Save(team); result.Err != nil { 25 return nil, result.Err 26 } else { 27 rteam := result.Data.(*model.Team) 28 29 if _, err := a.CreateDefaultChannels(rteam.Id); err != nil { 30 return nil, err 31 } 32 33 return rteam, nil 34 } 35 } 36 37 func (a *App) CreateTeamWithUser(team *model.Team, userId string) (*model.Team, *model.AppError) { 38 var user *model.User 39 var err *model.AppError 40 if user, err = a.GetUser(userId); err != nil { 41 return nil, err 42 } else { 43 team.Email = user.Email 44 } 45 46 if !a.isTeamEmailAllowed(user) { 47 return nil, model.NewAppError("isTeamEmailAllowed", "api.team.is_team_creation_allowed.domain.app_error", nil, "", http.StatusBadRequest) 48 } 49 50 var rteam *model.Team 51 if rteam, err = a.CreateTeam(team); err != nil { 52 return nil, err 53 } 54 55 if err = a.JoinUserToTeam(rteam, user, ""); err != nil { 56 return nil, err 57 } 58 59 return rteam, nil 60 } 61 62 func (a *App) isTeamEmailAddressAllowed(email string) bool { 63 email = strings.ToLower(email) 64 // commas and @ signs are optional 65 // can be in the form of "@corp.mattermost.com, mattermost.com mattermost.org" -> corp.mattermost.com mattermost.com mattermost.org 66 domains := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(a.Config().TeamSettings.RestrictCreationToDomains, "@", " ", -1), ",", " ", -1)))) 67 68 matched := false 69 for _, d := range domains { 70 if strings.HasSuffix(email, "@"+d) { 71 matched = true 72 break 73 } 74 } 75 76 if len(a.Config().TeamSettings.RestrictCreationToDomains) > 0 && !matched { 77 return false 78 } 79 80 return true 81 } 82 83 func (a *App) isTeamEmailAllowed(user *model.User) bool { 84 email := strings.ToLower(user.Email) 85 86 if len(user.AuthService) > 0 && len(*user.AuthData) > 0 { 87 return true 88 } 89 90 return a.isTeamEmailAddressAllowed(email) 91 } 92 93 func (a *App) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) { 94 var oldTeam *model.Team 95 var err *model.AppError 96 if oldTeam, err = a.GetTeam(team.Id); err != nil { 97 return nil, err 98 } 99 100 oldTeam.DisplayName = team.DisplayName 101 oldTeam.Description = team.Description 102 oldTeam.InviteId = team.InviteId 103 oldTeam.AllowOpenInvite = team.AllowOpenInvite 104 oldTeam.CompanyName = team.CompanyName 105 oldTeam.AllowedDomains = team.AllowedDomains 106 oldTeam.LastTeamIconUpdate = team.LastTeamIconUpdate 107 108 if result := <-a.Srv.Store.Team().Update(oldTeam); result.Err != nil { 109 return nil, result.Err 110 } 111 112 a.sendTeamEvent(oldTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM) 113 114 return oldTeam, nil 115 } 116 117 func (a *App) PatchTeam(teamId string, patch *model.TeamPatch) (*model.Team, *model.AppError) { 118 team, err := a.GetTeam(teamId) 119 if err != nil { 120 return nil, err 121 } 122 123 team.Patch(patch) 124 125 updatedTeam, err := a.UpdateTeam(team) 126 if err != nil { 127 return nil, err 128 } 129 130 a.sendTeamEvent(updatedTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM) 131 132 return updatedTeam, nil 133 } 134 135 func (a *App) sendTeamEvent(team *model.Team, event string) { 136 sanitizedTeam := &model.Team{} 137 *sanitizedTeam = *team 138 sanitizedTeam.Sanitize() 139 140 message := model.NewWebSocketEvent(event, "", "", "", nil) 141 message.Add("team", sanitizedTeam.ToJson()) 142 a.Publish(message) 143 } 144 145 func (a *App) UpdateTeamMemberRoles(teamId string, userId string, newRoles string) (*model.TeamMember, *model.AppError) { 146 var member *model.TeamMember 147 if result := <-a.Srv.Store.Team().GetTeamsForUser(userId); result.Err != nil { 148 return nil, result.Err 149 } else { 150 members := result.Data.([]*model.TeamMember) 151 for _, m := range members { 152 if m.TeamId == teamId { 153 member = m 154 } 155 } 156 } 157 158 if member == nil { 159 err := model.NewAppError("UpdateTeamMemberRoles", "api.team.update_member_roles.not_a_member", nil, "userId="+userId+" teamId="+teamId, http.StatusBadRequest) 160 return nil, err 161 } 162 163 if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil { 164 return nil, err 165 } 166 167 member.Roles = newRoles 168 169 if result := <-a.Srv.Store.Team().UpdateMember(member); result.Err != nil { 170 return nil, result.Err 171 } 172 173 a.ClearSessionCacheForUser(userId) 174 175 a.sendUpdatedMemberRoleEvent(userId, member) 176 177 return member, nil 178 } 179 180 func (a *App) sendUpdatedMemberRoleEvent(userId string, member *model.TeamMember) { 181 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_MEMBERROLE_UPDATED, "", "", userId, nil) 182 message.Add("member", member.ToJson()) 183 a.Publish(message) 184 } 185 186 func (a *App) AddUserToTeam(teamId string, userId string, userRequestorId string) (*model.Team, *model.AppError) { 187 tchan := a.Srv.Store.Team().Get(teamId) 188 uchan := a.Srv.Store.User().Get(userId) 189 190 var team *model.Team 191 if result := <-tchan; result.Err != nil { 192 return nil, result.Err 193 } else { 194 team = result.Data.(*model.Team) 195 } 196 197 var user *model.User 198 if result := <-uchan; result.Err != nil { 199 return nil, result.Err 200 } else { 201 user = result.Data.(*model.User) 202 } 203 204 if err := a.JoinUserToTeam(team, user, userRequestorId); err != nil { 205 return nil, err 206 } 207 208 return team, nil 209 } 210 211 func (a *App) AddUserToTeamByTeamId(teamId string, user *model.User) *model.AppError { 212 if result := <-a.Srv.Store.Team().Get(teamId); result.Err != nil { 213 return result.Err 214 } else { 215 return a.JoinUserToTeam(result.Data.(*model.Team), user, "") 216 } 217 } 218 219 func (a *App) AddUserToTeamByToken(userId string, tokenId string) (*model.Team, *model.AppError) { 220 result := <-a.Srv.Store.Token().GetByToken(tokenId) 221 if result.Err != nil { 222 return nil, model.NewAppError("AddUserToTeamByToken", "api.user.create_user.signup_link_invalid.app_error", nil, result.Err.Error(), http.StatusBadRequest) 223 } 224 225 token := result.Data.(*model.Token) 226 if token.Type != TOKEN_TYPE_TEAM_INVITATION { 227 return nil, model.NewAppError("AddUserToTeamByToken", "api.user.create_user.signup_link_invalid.app_error", nil, "", http.StatusBadRequest) 228 } 229 230 if model.GetMillis()-token.CreateAt >= TEAM_INVITATION_EXPIRY_TIME { 231 a.DeleteToken(token) 232 return nil, model.NewAppError("AddUserToTeamByToken", "api.user.create_user.signup_link_expired.app_error", nil, "", http.StatusBadRequest) 233 } 234 235 tokenData := model.MapFromJson(strings.NewReader(token.Extra)) 236 237 tchan := a.Srv.Store.Team().Get(tokenData["teamId"]) 238 uchan := a.Srv.Store.User().Get(userId) 239 240 var team *model.Team 241 if result := <-tchan; result.Err != nil { 242 return nil, result.Err 243 } else { 244 team = result.Data.(*model.Team) 245 } 246 247 var user *model.User 248 if result := <-uchan; result.Err != nil { 249 return nil, result.Err 250 } else { 251 user = result.Data.(*model.User) 252 } 253 254 if err := a.JoinUserToTeam(team, user, ""); err != nil { 255 return nil, err 256 } 257 258 if err := a.DeleteToken(token); err != nil { 259 return nil, err 260 } 261 262 return team, nil 263 } 264 265 func (a *App) AddUserToTeamByInviteId(inviteId string, userId string) (*model.Team, *model.AppError) { 266 tchan := a.Srv.Store.Team().GetByInviteId(inviteId) 267 uchan := a.Srv.Store.User().Get(userId) 268 269 var team *model.Team 270 if result := <-tchan; result.Err != nil { 271 return nil, result.Err 272 } else { 273 team = result.Data.(*model.Team) 274 } 275 276 var user *model.User 277 if result := <-uchan; result.Err != nil { 278 return nil, result.Err 279 } else { 280 user = result.Data.(*model.User) 281 } 282 283 if err := a.JoinUserToTeam(team, user, ""); err != nil { 284 return nil, err 285 } 286 287 return team, nil 288 } 289 290 // Returns three values: 291 // 1. a pointer to the team member, if successful 292 // 2. a boolean: true if the user has a non-deleted team member for that team already, otherwise false. 293 // 3. a pointer to an AppError if something went wrong. 294 func (a *App) joinUserToTeam(team *model.Team, user *model.User) (*model.TeamMember, bool, *model.AppError) { 295 tm := &model.TeamMember{ 296 TeamId: team.Id, 297 UserId: user.Id, 298 Roles: model.TEAM_USER_ROLE_ID, 299 } 300 301 if team.Email == user.Email { 302 tm.Roles = model.TEAM_USER_ROLE_ID + " " + model.TEAM_ADMIN_ROLE_ID 303 } 304 305 if etmr := <-a.Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil { 306 // Membership already exists. Check if deleted and and update, otherwise do nothing 307 rtm := etmr.Data.(*model.TeamMember) 308 309 // Do nothing if already added 310 if rtm.DeleteAt == 0 { 311 return rtm, true, nil 312 } 313 314 if membersCount := <-a.Srv.Store.Team().GetActiveMemberCount(tm.TeamId); membersCount.Err != nil { 315 return nil, false, membersCount.Err 316 } else if membersCount.Data.(int64) >= int64(*a.Config().TeamSettings.MaxUsersPerTeam) { 317 return nil, false, model.NewAppError("joinUserToTeam", "app.team.join_user_to_team.max_accounts.app_error", nil, "teamId="+tm.TeamId, http.StatusBadRequest) 318 } else { 319 if tmr := <-a.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil { 320 return nil, false, tmr.Err 321 } else { 322 return tmr.Data.(*model.TeamMember), false, nil 323 } 324 } 325 } else { 326 // Membership appears to be missing. Lets try to add. 327 if tmr := <-a.Srv.Store.Team().SaveMember(tm, *a.Config().TeamSettings.MaxUsersPerTeam); tmr.Err != nil { 328 return nil, false, tmr.Err 329 } else { 330 return tmr.Data.(*model.TeamMember), false, nil 331 } 332 } 333 } 334 335 func (a *App) JoinUserToTeam(team *model.Team, user *model.User, userRequestorId string) *model.AppError { 336 if _, alreadyAdded, err := a.joinUserToTeam(team, user); err != nil { 337 return err 338 } else if alreadyAdded { 339 return nil 340 } 341 342 if uua := <-a.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil { 343 return uua.Err 344 } 345 346 channelRole := model.CHANNEL_USER_ROLE_ID 347 348 if team.Email == user.Email { 349 channelRole = model.CHANNEL_USER_ROLE_ID + " " + model.CHANNEL_ADMIN_ROLE_ID 350 } 351 352 // Soft error if there is an issue joining the default channels 353 if err := a.JoinDefaultChannels(team.Id, user, channelRole, userRequestorId); err != nil { 354 mlog.Error(fmt.Sprintf("Encountered an issue joining default channels user_id=%s, team_id=%s, err=%v", user.Id, team.Id, err), mlog.String("user_id", user.Id)) 355 } 356 357 a.ClearSessionCacheForUser(user.Id) 358 a.InvalidateCacheForUser(user.Id) 359 360 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", user.Id, nil) 361 message.Add("team_id", team.Id) 362 message.Add("user_id", user.Id) 363 a.Publish(message) 364 365 return nil 366 } 367 368 func (a *App) GetTeam(teamId string) (*model.Team, *model.AppError) { 369 if result := <-a.Srv.Store.Team().Get(teamId); result.Err != nil { 370 return nil, result.Err 371 } else { 372 return result.Data.(*model.Team), nil 373 } 374 } 375 376 func (a *App) GetTeamByName(name string) (*model.Team, *model.AppError) { 377 if result := <-a.Srv.Store.Team().GetByName(name); result.Err != nil { 378 result.Err.StatusCode = http.StatusNotFound 379 return nil, result.Err 380 } else { 381 return result.Data.(*model.Team), nil 382 } 383 } 384 385 func (a *App) GetTeamByInviteId(inviteId string) (*model.Team, *model.AppError) { 386 if result := <-a.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil { 387 return nil, result.Err 388 } else { 389 return result.Data.(*model.Team), nil 390 } 391 } 392 393 func (a *App) GetAllTeams() ([]*model.Team, *model.AppError) { 394 if result := <-a.Srv.Store.Team().GetAll(); result.Err != nil { 395 return nil, result.Err 396 } else { 397 return result.Data.([]*model.Team), nil 398 } 399 } 400 401 func (a *App) GetAllTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) { 402 if result := <-a.Srv.Store.Team().GetAllPage(offset, limit); result.Err != nil { 403 return nil, result.Err 404 } else { 405 return result.Data.([]*model.Team), nil 406 } 407 } 408 409 func (a *App) GetAllOpenTeams() ([]*model.Team, *model.AppError) { 410 if result := <-a.Srv.Store.Team().GetAllTeamListing(); result.Err != nil { 411 return nil, result.Err 412 } else { 413 return result.Data.([]*model.Team), nil 414 } 415 } 416 417 func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) { 418 if result := <-a.Srv.Store.Team().SearchAll(term); result.Err != nil { 419 return nil, result.Err 420 } else { 421 return result.Data.([]*model.Team), nil 422 } 423 } 424 425 func (a *App) SearchOpenTeams(term string) ([]*model.Team, *model.AppError) { 426 if result := <-a.Srv.Store.Team().SearchOpen(term); result.Err != nil { 427 return nil, result.Err 428 } else { 429 return result.Data.([]*model.Team), nil 430 } 431 } 432 433 func (a *App) GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) { 434 if result := <-a.Srv.Store.Team().GetAllTeamPageListing(offset, limit); result.Err != nil { 435 return nil, result.Err 436 } else { 437 return result.Data.([]*model.Team), nil 438 } 439 } 440 441 func (a *App) GetTeamsForUser(userId string) ([]*model.Team, *model.AppError) { 442 if result := <-a.Srv.Store.Team().GetTeamsByUserId(userId); result.Err != nil { 443 return nil, result.Err 444 } else { 445 return result.Data.([]*model.Team), nil 446 } 447 } 448 449 func (a *App) GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) { 450 if result := <-a.Srv.Store.Team().GetMember(teamId, userId); result.Err != nil { 451 return nil, result.Err 452 } else { 453 return result.Data.(*model.TeamMember), nil 454 } 455 } 456 457 func (a *App) GetTeamMembersForUser(userId string) ([]*model.TeamMember, *model.AppError) { 458 if result := <-a.Srv.Store.Team().GetTeamsForUser(userId); result.Err != nil { 459 return nil, result.Err 460 } else { 461 return result.Data.([]*model.TeamMember), nil 462 } 463 } 464 465 func (a *App) GetTeamMembers(teamId string, offset int, limit int) ([]*model.TeamMember, *model.AppError) { 466 if result := <-a.Srv.Store.Team().GetMembers(teamId, offset, limit); result.Err != nil { 467 return nil, result.Err 468 } else { 469 return result.Data.([]*model.TeamMember), nil 470 } 471 } 472 473 func (a *App) GetTeamMembersByIds(teamId string, userIds []string) ([]*model.TeamMember, *model.AppError) { 474 if result := <-a.Srv.Store.Team().GetMembersByIds(teamId, userIds); result.Err != nil { 475 return nil, result.Err 476 } else { 477 return result.Data.([]*model.TeamMember), nil 478 } 479 } 480 481 func (a *App) AddTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) { 482 if _, err := a.AddUserToTeam(teamId, userId, ""); err != nil { 483 return nil, err 484 } 485 486 var teamMember *model.TeamMember 487 var err *model.AppError 488 if teamMember, err = a.GetTeamMember(teamId, userId); err != nil { 489 return nil, err 490 } 491 492 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", userId, nil) 493 message.Add("team_id", teamId) 494 message.Add("user_id", userId) 495 a.Publish(message) 496 497 return teamMember, nil 498 } 499 500 func (a *App) AddTeamMembers(teamId string, userIds []string, userRequestorId string) ([]*model.TeamMember, *model.AppError) { 501 var members []*model.TeamMember 502 503 for _, userId := range userIds { 504 if _, err := a.AddUserToTeam(teamId, userId, userRequestorId); err != nil { 505 return nil, err 506 } 507 508 if teamMember, err := a.GetTeamMember(teamId, userId); err != nil { 509 return nil, err 510 } else { 511 members = append(members, teamMember) 512 } 513 514 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", userId, nil) 515 message.Add("team_id", teamId) 516 message.Add("user_id", userId) 517 a.Publish(message) 518 } 519 520 return members, nil 521 } 522 523 func (a *App) AddTeamMemberByToken(userId, tokenId string) (*model.TeamMember, *model.AppError) { 524 var team *model.Team 525 var err *model.AppError 526 527 if team, err = a.AddUserToTeamByToken(userId, tokenId); err != nil { 528 return nil, err 529 } 530 531 if teamMember, err := a.GetTeamMember(team.Id, userId); err != nil { 532 return nil, err 533 } else { 534 return teamMember, nil 535 } 536 } 537 538 func (a *App) AddTeamMemberByInviteId(inviteId, userId string) (*model.TeamMember, *model.AppError) { 539 var team *model.Team 540 var err *model.AppError 541 542 if team, err = a.AddUserToTeamByInviteId(inviteId, userId); err != nil { 543 return nil, err 544 } 545 546 if teamMember, err := a.GetTeamMember(team.Id, userId); err != nil { 547 return nil, err 548 } else { 549 return teamMember, nil 550 } 551 } 552 553 func (a *App) GetTeamUnread(teamId, userId string) (*model.TeamUnread, *model.AppError) { 554 result := <-a.Srv.Store.Team().GetChannelUnreadsForTeam(teamId, userId) 555 if result.Err != nil { 556 return nil, result.Err 557 } 558 559 channelUnreads := result.Data.([]*model.ChannelUnread) 560 var teamUnread = &model.TeamUnread{ 561 MsgCount: 0, 562 MentionCount: 0, 563 TeamId: teamId, 564 } 565 566 for _, cu := range channelUnreads { 567 teamUnread.MentionCount += cu.MentionCount 568 569 if cu.NotifyProps["mark_unread"] != model.CHANNEL_MARK_UNREAD_MENTION { 570 teamUnread.MsgCount += cu.MsgCount 571 } 572 } 573 574 return teamUnread, nil 575 } 576 577 func (a *App) RemoveUserFromTeam(teamId string, userId string, requestorId string) *model.AppError { 578 tchan := a.Srv.Store.Team().Get(teamId) 579 uchan := a.Srv.Store.User().Get(userId) 580 581 var team *model.Team 582 if result := <-tchan; result.Err != nil { 583 return result.Err 584 } else { 585 team = result.Data.(*model.Team) 586 } 587 588 var user *model.User 589 if result := <-uchan; result.Err != nil { 590 return result.Err 591 } else { 592 user = result.Data.(*model.User) 593 } 594 595 if err := a.LeaveTeam(team, user, requestorId); err != nil { 596 return err 597 } 598 599 return nil 600 } 601 602 func (a *App) LeaveTeam(team *model.Team, user *model.User, requestorId string) *model.AppError { 603 var teamMember *model.TeamMember 604 var err *model.AppError 605 606 if teamMember, err = a.GetTeamMember(team.Id, user.Id); err != nil { 607 return model.NewAppError("LeaveTeam", "api.team.remove_user_from_team.missing.app_error", nil, err.Error(), http.StatusBadRequest) 608 } 609 610 var channelList *model.ChannelList 611 612 if result := <-a.Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil { 613 if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" { 614 channelList = &model.ChannelList{} 615 } else { 616 return result.Err 617 } 618 619 } else { 620 channelList = result.Data.(*model.ChannelList) 621 } 622 623 for _, channel := range *channelList { 624 if !channel.IsGroupOrDirect() { 625 a.InvalidateCacheForChannelMembers(channel.Id) 626 if result := <-a.Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil { 627 return result.Err 628 } 629 } 630 } 631 632 var channel *model.Channel 633 if result := <-a.Srv.Store.Channel().GetByName(team.Id, model.DEFAULT_CHANNEL, false); result.Err != nil { 634 return result.Err 635 } else { 636 channel = result.Data.(*model.Channel) 637 } 638 639 if *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 640 if requestorId == user.Id { 641 if err := a.postLeaveTeamMessage(user, channel); err != nil { 642 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 643 } 644 } 645 } 646 647 // Send the websocket message before we actually do the remove so the user being removed gets it. 648 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_LEAVE_TEAM, team.Id, "", "", nil) 649 message.Add("user_id", user.Id) 650 message.Add("team_id", team.Id) 651 a.Publish(message) 652 653 teamMember.Roles = "" 654 teamMember.DeleteAt = model.GetMillis() 655 656 if result := <-a.Srv.Store.Team().UpdateMember(teamMember); result.Err != nil { 657 return result.Err 658 } 659 660 if uua := <-a.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil { 661 return uua.Err 662 } 663 664 // delete the preferences that set the last channel used in the team and other team specific preferences 665 if result := <-a.Srv.Store.Preference().DeleteCategory(user.Id, team.Id); result.Err != nil { 666 return result.Err 667 } 668 669 a.ClearSessionCacheForUser(user.Id) 670 a.InvalidateCacheForUser(user.Id) 671 672 return nil 673 } 674 675 func (a *App) postLeaveTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 676 post := &model.Post{ 677 ChannelId: channel.Id, 678 Message: fmt.Sprintf(utils.T("api.team.leave.left"), user.Username), 679 Type: model.POST_LEAVE_TEAM, 680 UserId: user.Id, 681 Props: model.StringInterface{ 682 "username": user.Username, 683 }, 684 } 685 686 if _, err := a.CreatePost(post, channel, false); err != nil { 687 return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 688 } 689 690 return nil 691 } 692 693 func (a *App) InviteNewUsersToTeam(emailList []string, teamId, senderId string) *model.AppError { 694 if len(emailList) == 0 { 695 err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.no_one.app_error", nil, "", http.StatusBadRequest) 696 return err 697 } 698 699 var invalidEmailList []string 700 701 for _, email := range emailList { 702 if !a.isTeamEmailAddressAllowed(email) { 703 invalidEmailList = append(invalidEmailList, email) 704 } 705 } 706 707 if len(invalidEmailList) > 0 { 708 s := strings.Join(invalidEmailList, ", ") 709 err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.invalid_email.app_error", map[string]interface{}{"Addresses": s}, "", http.StatusBadRequest) 710 return err 711 } 712 713 tchan := a.Srv.Store.Team().Get(teamId) 714 uchan := a.Srv.Store.User().Get(senderId) 715 716 var team *model.Team 717 if result := <-tchan; result.Err != nil { 718 return result.Err 719 } else { 720 team = result.Data.(*model.Team) 721 } 722 723 var user *model.User 724 if result := <-uchan; result.Err != nil { 725 return result.Err 726 } else { 727 user = result.Data.(*model.User) 728 } 729 730 nameFormat := *a.Config().TeamSettings.TeammateNameDisplay 731 a.SendInviteEmails(team, user.GetDisplayName(nameFormat), emailList, a.GetSiteURL()) 732 733 return nil 734 } 735 736 func (a *App) FindTeamByName(name string) bool { 737 if result := <-a.Srv.Store.Team().GetByName(name); result.Err != nil { 738 return false 739 } else { 740 return true 741 } 742 } 743 744 func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userId string) ([]*model.TeamUnread, *model.AppError) { 745 if result := <-a.Srv.Store.Team().GetChannelUnreadsForAllTeams(excludeTeamId, userId); result.Err != nil { 746 return nil, result.Err 747 } else { 748 data := result.Data.([]*model.ChannelUnread) 749 members := []*model.TeamUnread{} 750 membersMap := make(map[string]*model.TeamUnread) 751 752 unreads := func(cu *model.ChannelUnread, tu *model.TeamUnread) *model.TeamUnread { 753 tu.MentionCount += cu.MentionCount 754 755 if cu.NotifyProps["mark_unread"] != model.CHANNEL_MARK_UNREAD_MENTION { 756 tu.MsgCount += cu.MsgCount 757 } 758 759 return tu 760 } 761 762 for i := range data { 763 id := data[i].TeamId 764 if mu, ok := membersMap[id]; ok { 765 membersMap[id] = unreads(data[i], mu) 766 } else { 767 membersMap[id] = unreads(data[i], &model.TeamUnread{ 768 MsgCount: 0, 769 MentionCount: 0, 770 TeamId: id, 771 }) 772 } 773 } 774 775 for _, val := range membersMap { 776 members = append(members, val) 777 } 778 779 return members, nil 780 } 781 } 782 783 func (a *App) PermanentDeleteTeamId(teamId string) *model.AppError { 784 team, err := a.GetTeam(teamId) 785 if err != nil { 786 return err 787 } 788 789 return a.PermanentDeleteTeam(team) 790 } 791 792 func (a *App) PermanentDeleteTeam(team *model.Team) *model.AppError { 793 team.DeleteAt = model.GetMillis() 794 if result := <-a.Srv.Store.Team().Update(team); result.Err != nil { 795 return result.Err 796 } 797 798 if result := <-a.Srv.Store.Channel().GetTeamChannels(team.Id); result.Err != nil { 799 if result.Err.Id != "store.sql_channel.get_channels.not_found.app_error" { 800 return result.Err 801 } 802 } else { 803 channels := result.Data.(*model.ChannelList) 804 for _, c := range *channels { 805 a.PermanentDeleteChannel(c) 806 } 807 } 808 809 if result := <-a.Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil { 810 return result.Err 811 } 812 813 if result := <-a.Srv.Store.Command().PermanentDeleteByTeam(team.Id); result.Err != nil { 814 return result.Err 815 } 816 817 if result := <-a.Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil { 818 return result.Err 819 } 820 821 a.sendTeamEvent(team, model.WEBSOCKET_EVENT_DELETE_TEAM) 822 823 return nil 824 } 825 826 func (a *App) SoftDeleteTeam(teamId string) *model.AppError { 827 team, err := a.GetTeam(teamId) 828 if err != nil { 829 return err 830 } 831 832 team.DeleteAt = model.GetMillis() 833 if result := <-a.Srv.Store.Team().Update(team); result.Err != nil { 834 return result.Err 835 } 836 837 a.sendTeamEvent(team, model.WEBSOCKET_EVENT_DELETE_TEAM) 838 839 return nil 840 } 841 842 func (a *App) GetTeamStats(teamId string) (*model.TeamStats, *model.AppError) { 843 tchan := a.Srv.Store.Team().GetTotalMemberCount(teamId) 844 achan := a.Srv.Store.Team().GetActiveMemberCount(teamId) 845 846 stats := &model.TeamStats{} 847 stats.TeamId = teamId 848 849 if result := <-tchan; result.Err != nil { 850 return nil, result.Err 851 } else { 852 stats.TotalMemberCount = result.Data.(int64) 853 } 854 855 if result := <-achan; result.Err != nil { 856 return nil, result.Err 857 } else { 858 stats.ActiveMemberCount = result.Data.(int64) 859 } 860 861 return stats, nil 862 } 863 864 func (a *App) GetTeamIdFromQuery(query url.Values) (string, *model.AppError) { 865 tokenId := query.Get("t") 866 inviteId := query.Get("id") 867 868 if len(tokenId) > 0 { 869 result := <-a.Srv.Store.Token().GetByToken(tokenId) 870 if result.Err != nil { 871 return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "", http.StatusBadRequest) 872 } 873 874 token := result.Data.(*model.Token) 875 if token.Type != TOKEN_TYPE_TEAM_INVITATION { 876 return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "", http.StatusBadRequest) 877 } 878 879 if model.GetMillis()-token.CreateAt >= TEAM_INVITATION_EXPIRY_TIME { 880 a.DeleteToken(token) 881 return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.expired_link.app_error", nil, "", http.StatusBadRequest) 882 } 883 884 tokenData := model.MapFromJson(strings.NewReader(token.Extra)) 885 886 return tokenData["teamId"], nil 887 } else if len(inviteId) > 0 { 888 if result := <-a.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil { 889 // soft fail, so we still create user but don't auto-join team 890 mlog.Error(fmt.Sprintf("%v", result.Err)) 891 } else { 892 return result.Data.(*model.Team).Id, nil 893 } 894 } 895 896 return "", nil 897 } 898 899 func (a *App) SanitizeTeam(session model.Session, team *model.Team) *model.Team { 900 if !a.SessionHasPermissionToTeam(session, team.Id, model.PERMISSION_MANAGE_TEAM) { 901 team.Sanitize() 902 } 903 904 return team 905 } 906 907 func (a *App) SanitizeTeams(session model.Session, teams []*model.Team) []*model.Team { 908 for _, team := range teams { 909 a.SanitizeTeam(session, team) 910 } 911 912 return teams 913 } 914 915 func (a *App) GetTeamIcon(team *model.Team) ([]byte, *model.AppError) { 916 if len(*a.Config().FileSettings.DriverName) == 0 { 917 return nil, model.NewAppError("GetTeamIcon", "api.team.get_team_icon.filesettings_no_driver.app_error", nil, "", http.StatusNotImplemented) 918 } else { 919 path := "teams/" + team.Id + "/teamIcon.png" 920 if data, err := a.ReadFile(path); err != nil { 921 return nil, model.NewAppError("GetTeamIcon", "api.team.get_team_icon.read_file.app_error", nil, err.Error(), http.StatusNotFound) 922 } else { 923 return data, nil 924 } 925 } 926 } 927 928 func (a *App) SetTeamIcon(teamId string, imageData *multipart.FileHeader) *model.AppError { 929 file, err := imageData.Open() 930 if err != nil { 931 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.open.app_error", nil, err.Error(), http.StatusBadRequest) 932 } 933 defer file.Close() 934 return a.SetTeamIconFromFile(teamId, file) 935 } 936 937 func (a *App) SetTeamIconFromFile(teamId string, file multipart.File) *model.AppError { 938 939 team, getTeamErr := a.GetTeam(teamId) 940 941 if getTeamErr != nil { 942 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.get_team.app_error", nil, getTeamErr.Error(), http.StatusBadRequest) 943 } 944 945 if len(*a.Config().FileSettings.DriverName) == 0 { 946 return model.NewAppError("setTeamIcon", "api.team.set_team_icon.storage.app_error", nil, "", http.StatusNotImplemented) 947 } 948 949 // Decode image config first to check dimensions before loading the whole thing into memory later on 950 config, _, err := image.DecodeConfig(file) 951 if err != nil { 952 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.decode_config.app_error", nil, err.Error(), http.StatusBadRequest) 953 } else if config.Width*config.Height > model.MaxImageSize { 954 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.too_large.app_error", nil, err.Error(), http.StatusBadRequest) 955 } 956 957 file.Seek(0, 0) 958 959 // Decode image into Image object 960 img, _, err := image.Decode(file) 961 if err != nil { 962 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.decode.app_error", nil, err.Error(), http.StatusBadRequest) 963 } 964 965 file.Seek(0, 0) 966 967 orientation, _ := getImageOrientation(file) 968 img = makeImageUpright(img, orientation) 969 970 // Scale team icon 971 teamIconWidthAndHeight := 128 972 img = imaging.Fill(img, teamIconWidthAndHeight, teamIconWidthAndHeight, imaging.Center, imaging.Lanczos) 973 974 buf := new(bytes.Buffer) 975 err = png.Encode(buf, img) 976 if err != nil { 977 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.encode.app_error", nil, err.Error(), http.StatusInternalServerError) 978 } 979 980 path := "teams/" + teamId + "/teamIcon.png" 981 982 if _, err := a.WriteFile(buf, path); err != nil { 983 return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.write_file.app_error", nil, "", http.StatusInternalServerError) 984 } 985 986 curTime := model.GetMillis() 987 988 if result := <-a.Srv.Store.Team().UpdateLastTeamIconUpdate(teamId, curTime); result.Err != nil { 989 return model.NewAppError("SetTeamIcon", "api.team.team_icon.update.app_error", nil, result.Err.Error(), http.StatusBadRequest) 990 } 991 992 // manually set time to avoid possible cluster inconsistencies 993 team.LastTeamIconUpdate = curTime 994 995 a.sendTeamEvent(team, model.WEBSOCKET_EVENT_UPDATE_TEAM) 996 997 return nil 998 } 999 1000 func (a *App) RemoveTeamIcon(teamId string) *model.AppError { 1001 team, err := a.GetTeam(teamId) 1002 if err != nil { 1003 return model.NewAppError("RemoveTeamIcon", "api.team.remove_team_icon.get_team.app_error", nil, err.Error(), http.StatusBadRequest) 1004 } 1005 1006 if result := <-a.Srv.Store.Team().UpdateLastTeamIconUpdate(teamId, 0); result.Err != nil { 1007 return model.NewAppError("RemoveTeamIcon", "api.team.team_icon.update.app_error", nil, result.Err.Error(), http.StatusBadRequest) 1008 } 1009 1010 team.LastTeamIconUpdate = 0 1011 1012 a.sendTeamEvent(team, model.WEBSOCKET_EVENT_UPDATE_TEAM) 1013 1014 return nil 1015 }