github.com/dschalla/mattermost-server@v4.8.1-rc1+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.sendTeamEvent(oldTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM) 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.sendTeamEvent(updatedTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM) 126 127 return updatedTeam, nil 128 } 129 130 func (a *App) sendTeamEvent(team *model.Team, event string) { 131 sanitizedTeam := &model.Team{} 132 *sanitizedTeam = *team 133 sanitizedTeam.Sanitize() 134 135 message := model.NewWebSocketEvent(event, "", "", "", 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 membersCount := <-a.Srv.Store.Team().GetActiveMemberCount(tm.TeamId); membersCount.Err != nil { 301 return nil, false, membersCount.Err 302 } else if membersCount.Data.(int64) >= int64(*a.Config().TeamSettings.MaxUsersPerTeam) { 303 return nil, false, model.NewAppError("joinUserToTeam", "app.team.join_user_to_team.max_accounts.app_error", nil, "teamId="+tm.TeamId, http.StatusBadRequest) 304 } else { 305 if tmr := <-a.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil { 306 return nil, false, tmr.Err 307 } else { 308 return tmr.Data.(*model.TeamMember), false, nil 309 } 310 } 311 } else { 312 // Membership appears to be missing. Lets try to add. 313 if tmr := <-a.Srv.Store.Team().SaveMember(tm, *a.Config().TeamSettings.MaxUsersPerTeam); tmr.Err != nil { 314 return nil, false, tmr.Err 315 } else { 316 return tmr.Data.(*model.TeamMember), false, nil 317 } 318 } 319 } 320 321 func (a *App) JoinUserToTeam(team *model.Team, user *model.User, userRequestorId string) *model.AppError { 322 if _, alreadyAdded, err := a.joinUserToTeam(team, user); err != nil { 323 return err 324 } else if alreadyAdded { 325 return nil 326 } 327 328 if uua := <-a.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil { 329 return uua.Err 330 } 331 332 channelRole := model.CHANNEL_USER_ROLE_ID 333 334 if team.Email == user.Email { 335 channelRole = model.CHANNEL_USER_ROLE_ID + " " + model.CHANNEL_ADMIN_ROLE_ID 336 } 337 338 // Soft error if there is an issue joining the default channels 339 if err := a.JoinDefaultChannels(team.Id, user, channelRole, userRequestorId); err != nil { 340 l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err) 341 } 342 343 a.ClearSessionCacheForUser(user.Id) 344 a.InvalidateCacheForUser(user.Id) 345 346 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", user.Id, nil) 347 message.Add("team_id", team.Id) 348 message.Add("user_id", user.Id) 349 a.Publish(message) 350 351 return nil 352 } 353 354 func (a *App) GetTeam(teamId string) (*model.Team, *model.AppError) { 355 if result := <-a.Srv.Store.Team().Get(teamId); result.Err != nil { 356 return nil, result.Err 357 } else { 358 return result.Data.(*model.Team), nil 359 } 360 } 361 362 func (a *App) GetTeamByName(name string) (*model.Team, *model.AppError) { 363 if result := <-a.Srv.Store.Team().GetByName(name); result.Err != nil { 364 result.Err.StatusCode = http.StatusNotFound 365 return nil, result.Err 366 } else { 367 return result.Data.(*model.Team), nil 368 } 369 } 370 371 func (a *App) GetTeamByInviteId(inviteId string) (*model.Team, *model.AppError) { 372 if result := <-a.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil { 373 return nil, result.Err 374 } else { 375 return result.Data.(*model.Team), nil 376 } 377 } 378 379 func (a *App) GetAllTeams() ([]*model.Team, *model.AppError) { 380 if result := <-a.Srv.Store.Team().GetAll(); result.Err != nil { 381 return nil, result.Err 382 } else { 383 return result.Data.([]*model.Team), nil 384 } 385 } 386 387 func (a *App) GetAllTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) { 388 if result := <-a.Srv.Store.Team().GetAllPage(offset, limit); result.Err != nil { 389 return nil, result.Err 390 } else { 391 return result.Data.([]*model.Team), nil 392 } 393 } 394 395 func (a *App) GetAllOpenTeams() ([]*model.Team, *model.AppError) { 396 if result := <-a.Srv.Store.Team().GetAllTeamListing(); result.Err != nil { 397 return nil, result.Err 398 } else { 399 return result.Data.([]*model.Team), nil 400 } 401 } 402 403 func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) { 404 if result := <-a.Srv.Store.Team().SearchAll(term); result.Err != nil { 405 return nil, result.Err 406 } else { 407 return result.Data.([]*model.Team), nil 408 } 409 } 410 411 func (a *App) SearchOpenTeams(term string) ([]*model.Team, *model.AppError) { 412 if result := <-a.Srv.Store.Team().SearchOpen(term); result.Err != nil { 413 return nil, result.Err 414 } else { 415 return result.Data.([]*model.Team), nil 416 } 417 } 418 419 func (a *App) GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) { 420 if result := <-a.Srv.Store.Team().GetAllTeamPageListing(offset, limit); result.Err != nil { 421 return nil, result.Err 422 } else { 423 return result.Data.([]*model.Team), nil 424 } 425 } 426 427 func (a *App) GetTeamsForUser(userId string) ([]*model.Team, *model.AppError) { 428 if result := <-a.Srv.Store.Team().GetTeamsByUserId(userId); result.Err != nil { 429 return nil, result.Err 430 } else { 431 return result.Data.([]*model.Team), nil 432 } 433 } 434 435 func (a *App) GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) { 436 if result := <-a.Srv.Store.Team().GetMember(teamId, userId); result.Err != nil { 437 return nil, result.Err 438 } else { 439 return result.Data.(*model.TeamMember), nil 440 } 441 } 442 443 func (a *App) GetTeamMembersForUser(userId string) ([]*model.TeamMember, *model.AppError) { 444 if result := <-a.Srv.Store.Team().GetTeamsForUser(userId); result.Err != nil { 445 return nil, result.Err 446 } else { 447 return result.Data.([]*model.TeamMember), nil 448 } 449 } 450 451 func (a *App) GetTeamMembers(teamId string, offset int, limit int) ([]*model.TeamMember, *model.AppError) { 452 if result := <-a.Srv.Store.Team().GetMembers(teamId, offset, limit); result.Err != nil { 453 return nil, result.Err 454 } else { 455 return result.Data.([]*model.TeamMember), nil 456 } 457 } 458 459 func (a *App) GetTeamMembersByIds(teamId string, userIds []string) ([]*model.TeamMember, *model.AppError) { 460 if result := <-a.Srv.Store.Team().GetMembersByIds(teamId, userIds); result.Err != nil { 461 return nil, result.Err 462 } else { 463 return result.Data.([]*model.TeamMember), nil 464 } 465 } 466 467 func (a *App) AddTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) { 468 if _, err := a.AddUserToTeam(teamId, userId, ""); err != nil { 469 return nil, err 470 } 471 472 var teamMember *model.TeamMember 473 var err *model.AppError 474 if teamMember, err = a.GetTeamMember(teamId, userId); err != nil { 475 return nil, err 476 } 477 478 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", userId, nil) 479 message.Add("team_id", teamId) 480 message.Add("user_id", userId) 481 a.Publish(message) 482 483 return teamMember, nil 484 } 485 486 func (a *App) AddTeamMembers(teamId string, userIds []string, userRequestorId string) ([]*model.TeamMember, *model.AppError) { 487 var members []*model.TeamMember 488 489 for _, userId := range userIds { 490 if _, err := a.AddUserToTeam(teamId, userId, userRequestorId); err != nil { 491 return nil, err 492 } 493 494 if teamMember, err := a.GetTeamMember(teamId, userId); err != nil { 495 return nil, err 496 } else { 497 members = append(members, teamMember) 498 } 499 500 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", userId, nil) 501 message.Add("team_id", teamId) 502 message.Add("user_id", userId) 503 a.Publish(message) 504 } 505 506 return members, nil 507 } 508 509 func (a *App) AddTeamMemberByHash(userId, hash, data string) (*model.TeamMember, *model.AppError) { 510 var team *model.Team 511 var err *model.AppError 512 513 if team, err = a.AddUserToTeamByHash(userId, hash, data); err != nil { 514 return nil, err 515 } 516 517 if teamMember, err := a.GetTeamMember(team.Id, userId); err != nil { 518 return nil, err 519 } else { 520 return teamMember, nil 521 } 522 } 523 524 func (a *App) AddTeamMemberByInviteId(inviteId, userId string) (*model.TeamMember, *model.AppError) { 525 var team *model.Team 526 var err *model.AppError 527 528 if team, err = a.AddUserToTeamByInviteId(inviteId, userId); err != nil { 529 return nil, err 530 } 531 532 if teamMember, err := a.GetTeamMember(team.Id, userId); err != nil { 533 return nil, err 534 } else { 535 return teamMember, nil 536 } 537 } 538 539 func (a *App) GetTeamUnread(teamId, userId string) (*model.TeamUnread, *model.AppError) { 540 result := <-a.Srv.Store.Team().GetChannelUnreadsForTeam(teamId, userId) 541 if result.Err != nil { 542 return nil, result.Err 543 } 544 545 channelUnreads := result.Data.([]*model.ChannelUnread) 546 var teamUnread = &model.TeamUnread{ 547 MsgCount: 0, 548 MentionCount: 0, 549 TeamId: teamId, 550 } 551 552 for _, cu := range channelUnreads { 553 teamUnread.MentionCount += cu.MentionCount 554 555 if cu.NotifyProps["mark_unread"] != model.CHANNEL_MARK_UNREAD_MENTION { 556 teamUnread.MsgCount += cu.MsgCount 557 } 558 } 559 560 return teamUnread, nil 561 } 562 563 func (a *App) RemoveUserFromTeam(teamId string, userId string, requestorId string) *model.AppError { 564 tchan := a.Srv.Store.Team().Get(teamId) 565 uchan := a.Srv.Store.User().Get(userId) 566 567 var team *model.Team 568 if result := <-tchan; result.Err != nil { 569 return result.Err 570 } else { 571 team = result.Data.(*model.Team) 572 } 573 574 var user *model.User 575 if result := <-uchan; result.Err != nil { 576 return result.Err 577 } else { 578 user = result.Data.(*model.User) 579 } 580 581 if err := a.LeaveTeam(team, user, requestorId); err != nil { 582 return err 583 } 584 585 return nil 586 } 587 588 func (a *App) LeaveTeam(team *model.Team, user *model.User, requestorId string) *model.AppError { 589 var teamMember *model.TeamMember 590 var err *model.AppError 591 592 if teamMember, err = a.GetTeamMember(team.Id, user.Id); err != nil { 593 return model.NewAppError("LeaveTeam", "api.team.remove_user_from_team.missing.app_error", nil, err.Error(), http.StatusBadRequest) 594 } 595 596 var channelList *model.ChannelList 597 598 if result := <-a.Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil { 599 if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" { 600 channelList = &model.ChannelList{} 601 } else { 602 return result.Err 603 } 604 605 } else { 606 channelList = result.Data.(*model.ChannelList) 607 } 608 609 for _, channel := range *channelList { 610 if !channel.IsGroupOrDirect() { 611 a.InvalidateCacheForChannelMembers(channel.Id) 612 if result := <-a.Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil { 613 return result.Err 614 } 615 } 616 } 617 618 var channel *model.Channel 619 if result := <-a.Srv.Store.Channel().GetByName(team.Id, model.DEFAULT_CHANNEL, false); result.Err != nil { 620 return result.Err 621 } else { 622 channel = result.Data.(*model.Channel) 623 } 624 625 if *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 626 if requestorId == user.Id { 627 if err := a.postLeaveTeamMessage(user, channel); err != nil { 628 l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) 629 } 630 } else { 631 if err := a.postRemoveFromTeamMessage(user, channel); err != nil { 632 l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) 633 } 634 } 635 } 636 637 // Send the websocket message before we actually do the remove so the user being removed gets it. 638 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_LEAVE_TEAM, team.Id, "", "", nil) 639 message.Add("user_id", user.Id) 640 message.Add("team_id", team.Id) 641 a.Publish(message) 642 643 teamMember.Roles = "" 644 teamMember.DeleteAt = model.GetMillis() 645 646 if result := <-a.Srv.Store.Team().UpdateMember(teamMember); result.Err != nil { 647 return result.Err 648 } 649 650 if uua := <-a.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil { 651 return uua.Err 652 } 653 654 // delete the preferences that set the last channel used in the team and other team specific preferences 655 if result := <-a.Srv.Store.Preference().DeleteCategory(user.Id, team.Id); result.Err != nil { 656 return result.Err 657 } 658 659 a.ClearSessionCacheForUser(user.Id) 660 a.InvalidateCacheForUser(user.Id) 661 662 return nil 663 } 664 665 func (a *App) postLeaveTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 666 post := &model.Post{ 667 ChannelId: channel.Id, 668 Message: fmt.Sprintf(utils.T("api.team.leave.left"), user.Username), 669 Type: model.POST_LEAVE_TEAM, 670 UserId: user.Id, 671 Props: model.StringInterface{ 672 "username": user.Username, 673 }, 674 } 675 676 if _, err := a.CreatePost(post, channel, false); err != nil { 677 return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 678 } 679 680 return nil 681 } 682 683 func (a *App) postRemoveFromTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 684 post := &model.Post{ 685 ChannelId: channel.Id, 686 Message: fmt.Sprintf(utils.T("api.team.remove_user_from_team.removed"), user.Username), 687 Type: model.POST_REMOVE_FROM_TEAM, 688 UserId: user.Id, 689 Props: model.StringInterface{ 690 "username": user.Username, 691 }, 692 } 693 694 if _, err := a.CreatePost(post, channel, false); err != nil { 695 return model.NewAppError("postRemoveFromTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 696 } 697 698 return nil 699 } 700 701 func (a *App) InviteNewUsersToTeam(emailList []string, teamId, senderId string) *model.AppError { 702 if len(emailList) == 0 { 703 err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.no_one.app_error", nil, "", http.StatusBadRequest) 704 return err 705 } 706 707 var invalidEmailList []string 708 709 for _, email := range emailList { 710 if !a.isTeamEmailAddressAllowed(email) { 711 invalidEmailList = append(invalidEmailList, email) 712 } 713 } 714 715 if len(invalidEmailList) > 0 { 716 s := strings.Join(invalidEmailList, ", ") 717 err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.invalid_email.app_error", map[string]interface{}{"Addresses": s}, "", http.StatusBadRequest) 718 return err 719 } 720 721 tchan := a.Srv.Store.Team().Get(teamId) 722 uchan := a.Srv.Store.User().Get(senderId) 723 724 var team *model.Team 725 if result := <-tchan; result.Err != nil { 726 return result.Err 727 } else { 728 team = result.Data.(*model.Team) 729 } 730 731 var user *model.User 732 if result := <-uchan; result.Err != nil { 733 return result.Err 734 } else { 735 user = result.Data.(*model.User) 736 } 737 738 nameFormat := *a.Config().TeamSettings.TeammateNameDisplay 739 a.SendInviteEmails(team, user.GetDisplayName(nameFormat), emailList, a.GetSiteURL()) 740 741 return nil 742 } 743 744 func (a *App) FindTeamByName(name string) bool { 745 if result := <-a.Srv.Store.Team().GetByName(name); result.Err != nil { 746 return false 747 } else { 748 return true 749 } 750 } 751 752 func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userId string) ([]*model.TeamUnread, *model.AppError) { 753 if result := <-a.Srv.Store.Team().GetChannelUnreadsForAllTeams(excludeTeamId, userId); result.Err != nil { 754 return nil, result.Err 755 } else { 756 data := result.Data.([]*model.ChannelUnread) 757 members := []*model.TeamUnread{} 758 membersMap := make(map[string]*model.TeamUnread) 759 760 unreads := func(cu *model.ChannelUnread, tu *model.TeamUnread) *model.TeamUnread { 761 tu.MentionCount += cu.MentionCount 762 763 if cu.NotifyProps["mark_unread"] != model.CHANNEL_MARK_UNREAD_MENTION { 764 tu.MsgCount += cu.MsgCount 765 } 766 767 return tu 768 } 769 770 for i := range data { 771 id := data[i].TeamId 772 if mu, ok := membersMap[id]; ok { 773 membersMap[id] = unreads(data[i], mu) 774 } else { 775 membersMap[id] = unreads(data[i], &model.TeamUnread{ 776 MsgCount: 0, 777 MentionCount: 0, 778 TeamId: id, 779 }) 780 } 781 } 782 783 for _, val := range membersMap { 784 members = append(members, val) 785 } 786 787 return members, nil 788 } 789 } 790 791 func (a *App) PermanentDeleteTeamId(teamId string) *model.AppError { 792 team, err := a.GetTeam(teamId) 793 if err != nil { 794 return err 795 } 796 797 return a.PermanentDeleteTeam(team) 798 } 799 800 func (a *App) PermanentDeleteTeam(team *model.Team) *model.AppError { 801 team.DeleteAt = model.GetMillis() 802 if result := <-a.Srv.Store.Team().Update(team); result.Err != nil { 803 return result.Err 804 } 805 806 if result := <-a.Srv.Store.Channel().GetTeamChannels(team.Id); result.Err != nil { 807 if result.Err.Id != "store.sql_channel.get_channels.not_found.app_error" { 808 return result.Err 809 } 810 } else { 811 channels := result.Data.(*model.ChannelList) 812 for _, c := range *channels { 813 a.PermanentDeleteChannel(c) 814 } 815 } 816 817 if result := <-a.Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil { 818 return result.Err 819 } 820 821 if result := <-a.Srv.Store.Command().PermanentDeleteByTeam(team.Id); result.Err != nil { 822 return result.Err 823 } 824 825 if result := <-a.Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil { 826 return result.Err 827 } 828 829 a.sendTeamEvent(team, model.WEBSOCKET_EVENT_DELETE_TEAM) 830 831 return nil 832 } 833 834 func (a *App) SoftDeleteTeam(teamId string) *model.AppError { 835 team, err := a.GetTeam(teamId) 836 if err != nil { 837 return err 838 } 839 840 team.DeleteAt = model.GetMillis() 841 if result := <-a.Srv.Store.Team().Update(team); result.Err != nil { 842 return result.Err 843 } 844 845 a.sendTeamEvent(team, model.WEBSOCKET_EVENT_DELETE_TEAM) 846 847 return nil 848 } 849 850 func (a *App) GetTeamStats(teamId string) (*model.TeamStats, *model.AppError) { 851 tchan := a.Srv.Store.Team().GetTotalMemberCount(teamId) 852 achan := a.Srv.Store.Team().GetActiveMemberCount(teamId) 853 854 stats := &model.TeamStats{} 855 stats.TeamId = teamId 856 857 if result := <-tchan; result.Err != nil { 858 return nil, result.Err 859 } else { 860 stats.TotalMemberCount = result.Data.(int64) 861 } 862 863 if result := <-achan; result.Err != nil { 864 return nil, result.Err 865 } else { 866 stats.ActiveMemberCount = result.Data.(int64) 867 } 868 869 return stats, nil 870 } 871 872 func (a *App) GetTeamIdFromQuery(query url.Values) (string, *model.AppError) { 873 hash := query.Get("h") 874 inviteId := query.Get("id") 875 876 if len(hash) > 0 { 877 data := query.Get("d") 878 props := model.MapFromJson(strings.NewReader(data)) 879 880 if hash != utils.HashSha256(fmt.Sprintf("%v:%v", data, a.Config().EmailSettings.InviteSalt)) { 881 return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "", http.StatusBadRequest) 882 } 883 884 t, err := strconv.ParseInt(props["time"], 10, 64) 885 if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours 886 return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.expired_link.app_error", nil, "", http.StatusBadRequest) 887 } 888 889 return props["id"], nil 890 } else if len(inviteId) > 0 { 891 if result := <-a.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil { 892 // soft fail, so we still create user but don't auto-join team 893 l4g.Error("%v", result.Err) 894 } else { 895 return result.Data.(*model.Team).Id, nil 896 } 897 } 898 899 return "", nil 900 } 901 902 func (a *App) SanitizeTeam(session model.Session, team *model.Team) *model.Team { 903 if !a.SessionHasPermissionToTeam(session, team.Id, model.PERMISSION_MANAGE_TEAM) { 904 team.Sanitize() 905 } 906 907 return team 908 } 909 910 func (a *App) SanitizeTeams(session model.Session, teams []*model.Team) []*model.Team { 911 for _, team := range teams { 912 a.SanitizeTeam(session, team) 913 } 914 915 return teams 916 }