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