github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/sqlstore/team_store.go (about) 1 // Copyright (c) 2015-present Xenia, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "database/sql" 8 "fmt" 9 "net/http" 10 "strconv" 11 "strings" 12 13 sq "github.com/Masterminds/squirrel" 14 "github.com/xzl8028/gorp" 15 "github.com/xzl8028/xenia-server/einterfaces" 16 "github.com/xzl8028/xenia-server/model" 17 "github.com/xzl8028/xenia-server/store" 18 "github.com/xzl8028/xenia-server/utils" 19 ) 20 21 const ( 22 TEAM_MEMBER_EXISTS_ERROR = "store.sql_team.save_member.exists.app_error" 23 ALL_TEAM_IDS_FOR_USER_CACHE_SIZE = model.SESSION_CACHE_SIZE 24 ALL_TEAM_IDS_FOR_USER_CACHE_SEC = 1800 // 30 mins 25 ) 26 27 type SqlTeamStore struct { 28 SqlStore 29 metrics einterfaces.MetricsInterface 30 } 31 32 type teamMember struct { 33 TeamId string 34 UserId string 35 Roles string 36 DeleteAt int64 37 SchemeGuest sql.NullBool 38 SchemeUser sql.NullBool 39 SchemeAdmin sql.NullBool 40 } 41 42 func NewTeamMemberFromModel(tm *model.TeamMember) *teamMember { 43 return &teamMember{ 44 TeamId: tm.TeamId, 45 UserId: tm.UserId, 46 Roles: tm.ExplicitRoles, 47 DeleteAt: tm.DeleteAt, 48 SchemeGuest: sql.NullBool{Valid: true, Bool: tm.SchemeGuest}, 49 SchemeUser: sql.NullBool{Valid: true, Bool: tm.SchemeUser}, 50 SchemeAdmin: sql.NullBool{Valid: true, Bool: tm.SchemeAdmin}, 51 } 52 } 53 54 type teamMemberWithSchemeRoles struct { 55 TeamId string 56 UserId string 57 Roles string 58 DeleteAt int64 59 SchemeGuest sql.NullBool 60 SchemeUser sql.NullBool 61 SchemeAdmin sql.NullBool 62 TeamSchemeDefaultGuestRole sql.NullString 63 TeamSchemeDefaultUserRole sql.NullString 64 TeamSchemeDefaultAdminRole sql.NullString 65 } 66 67 type teamMemberWithSchemeRolesList []teamMemberWithSchemeRoles 68 69 func (db teamMemberWithSchemeRoles) ToModel() *model.TeamMember { 70 var roles []string 71 var explicitRoles []string 72 73 // Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude 74 // them from ExplicitRoles field. 75 schemeGuest := db.SchemeGuest.Valid && db.SchemeGuest.Bool 76 schemeUser := db.SchemeUser.Valid && db.SchemeUser.Bool 77 schemeAdmin := db.SchemeAdmin.Valid && db.SchemeAdmin.Bool 78 for _, role := range strings.Fields(db.Roles) { 79 isImplicit := false 80 if role == model.TEAM_GUEST_ROLE_ID { 81 // We have an implicit role via the system scheme. Override the "schemeGuest" field to true. 82 schemeGuest = true 83 isImplicit = true 84 } else if role == model.TEAM_USER_ROLE_ID { 85 // We have an implicit role via the system scheme. Override the "schemeUser" field to true. 86 schemeUser = true 87 isImplicit = true 88 } else if role == model.TEAM_ADMIN_ROLE_ID { 89 // We have an implicit role via the system scheme. 90 schemeAdmin = true 91 isImplicit = true 92 } 93 94 if !isImplicit { 95 explicitRoles = append(explicitRoles, role) 96 } 97 roles = append(roles, role) 98 } 99 100 // Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add 101 // them to the Roles field for backwards compatibility reasons. 102 var schemeImpliedRoles []string 103 if db.SchemeGuest.Valid && db.SchemeGuest.Bool { 104 if db.TeamSchemeDefaultGuestRole.Valid && db.TeamSchemeDefaultGuestRole.String != "" { 105 schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultGuestRole.String) 106 } else { 107 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_GUEST_ROLE_ID) 108 } 109 } 110 if db.SchemeUser.Valid && db.SchemeUser.Bool { 111 if db.TeamSchemeDefaultUserRole.Valid && db.TeamSchemeDefaultUserRole.String != "" { 112 schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultUserRole.String) 113 } else { 114 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_USER_ROLE_ID) 115 } 116 } 117 if db.SchemeAdmin.Valid && db.SchemeAdmin.Bool { 118 if db.TeamSchemeDefaultAdminRole.Valid && db.TeamSchemeDefaultAdminRole.String != "" { 119 schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultAdminRole.String) 120 } else { 121 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_ADMIN_ROLE_ID) 122 } 123 } 124 for _, impliedRole := range schemeImpliedRoles { 125 alreadyThere := false 126 for _, role := range roles { 127 if role == impliedRole { 128 alreadyThere = true 129 } 130 } 131 if !alreadyThere { 132 roles = append(roles, impliedRole) 133 } 134 } 135 136 tm := &model.TeamMember{ 137 TeamId: db.TeamId, 138 UserId: db.UserId, 139 Roles: strings.Join(roles, " "), 140 DeleteAt: db.DeleteAt, 141 SchemeGuest: schemeGuest, 142 SchemeUser: schemeUser, 143 SchemeAdmin: schemeAdmin, 144 ExplicitRoles: strings.Join(explicitRoles, " "), 145 } 146 return tm 147 } 148 149 func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember { 150 tms := make([]*model.TeamMember, 0) 151 152 for _, tm := range db { 153 tms = append(tms, tm.ToModel()) 154 } 155 156 return tms 157 } 158 159 func NewSqlTeamStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.TeamStore { 160 s := &SqlTeamStore{ 161 sqlStore, 162 metrics, 163 } 164 165 for _, db := range sqlStore.GetAllConns() { 166 table := db.AddTableWithName(model.Team{}, "Teams").SetKeys(false, "Id") 167 table.ColMap("Id").SetMaxSize(26) 168 table.ColMap("DisplayName").SetMaxSize(64) 169 table.ColMap("Name").SetMaxSize(64).SetUnique(true) 170 table.ColMap("Description").SetMaxSize(255) 171 table.ColMap("Email").SetMaxSize(128) 172 table.ColMap("CompanyName").SetMaxSize(64) 173 table.ColMap("AllowedDomains").SetMaxSize(1000) 174 table.ColMap("InviteId").SetMaxSize(32) 175 176 tablem := db.AddTableWithName(teamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId") 177 tablem.ColMap("TeamId").SetMaxSize(26) 178 tablem.ColMap("UserId").SetMaxSize(26) 179 tablem.ColMap("Roles").SetMaxSize(64) 180 } 181 182 return s 183 } 184 185 func (s SqlTeamStore) CreateIndexesIfNotExists() { 186 s.CreateIndexIfNotExists("idx_teams_name", "Teams", "Name") 187 s.RemoveIndexIfExists("idx_teams_description", "Teams") 188 s.CreateIndexIfNotExists("idx_teams_invite_id", "Teams", "InviteId") 189 s.CreateIndexIfNotExists("idx_teams_update_at", "Teams", "UpdateAt") 190 s.CreateIndexIfNotExists("idx_teams_create_at", "Teams", "CreateAt") 191 s.CreateIndexIfNotExists("idx_teams_delete_at", "Teams", "DeleteAt") 192 193 s.CreateIndexIfNotExists("idx_teammembers_team_id", "TeamMembers", "TeamId") 194 s.CreateIndexIfNotExists("idx_teammembers_user_id", "TeamMembers", "UserId") 195 s.CreateIndexIfNotExists("idx_teammembers_delete_at", "TeamMembers", "DeleteAt") 196 } 197 198 func (s SqlTeamStore) Save(team *model.Team) (*model.Team, *model.AppError) { 199 if len(team.Id) > 0 { 200 return nil, model.NewAppError("SqlTeamStore.Save", 201 "store.sql_team.save.existing.app_error", nil, "id="+team.Id, http.StatusBadRequest) 202 } 203 204 team.PreSave() 205 206 if err := team.IsValid(); err != nil { 207 return nil, err 208 } 209 210 if err := s.GetMaster().Insert(team); err != nil { 211 if IsUniqueConstraintError(err, []string{"Name", "teams_name_key"}) { 212 return nil, model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.domain_exists.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusBadRequest) 213 } 214 return nil, model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 215 } 216 return team, nil 217 } 218 219 func (s SqlTeamStore) Update(team *model.Team) (*model.Team, *model.AppError) { 220 221 team.PreUpdate() 222 223 if err := team.IsValid(); err != nil { 224 return nil, err 225 } 226 227 oldResult, err := s.GetMaster().Get(model.Team{}, team.Id) 228 if err != nil { 229 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.finding.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 230 231 } 232 233 if oldResult == nil { 234 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.find.app_error", nil, "id="+team.Id, http.StatusBadRequest) 235 } 236 237 oldTeam := oldResult.(*model.Team) 238 team.CreateAt = oldTeam.CreateAt 239 team.UpdateAt = model.GetMillis() 240 241 count, err := s.GetMaster().Update(team) 242 if err != nil { 243 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.updating.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 244 } 245 if count != 1 { 246 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.app_error", nil, "id="+team.Id, http.StatusInternalServerError) 247 } 248 249 if oldTeam.DeleteAt == 0 && team.DeleteAt != 0 { 250 // Invalidate this cache after any team deletion 251 allTeamIdsForUserCache.Purge() 252 } 253 254 return team, nil 255 } 256 257 func (s SqlTeamStore) UpdateDisplayName(name string, teamId string) *model.AppError { 258 if _, err := s.GetMaster().Exec("UPDATE Teams SET DisplayName = :Name WHERE Id = :Id", map[string]interface{}{"Name": name, "Id": teamId}); err != nil { 259 return model.NewAppError("SqlTeamStore.UpdateName", "store.sql_team.update_display_name.app_error", nil, "team_id="+teamId, http.StatusInternalServerError) 260 } 261 262 return nil 263 } 264 265 func (s SqlTeamStore) Get(id string) (*model.Team, *model.AppError) { 266 obj, err := s.GetReplica().Get(model.Team{}, id) 267 if err != nil { 268 return nil, model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.finding.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 269 } 270 if obj == nil { 271 return nil, model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.find.app_error", nil, "id="+id, http.StatusNotFound) 272 } 273 274 return obj.(*model.Team), nil 275 } 276 277 func (s SqlTeamStore) GetByInviteId(inviteId string) (*model.Team, *model.AppError) { 278 team := model.Team{} 279 280 err := s.GetReplica().SelectOne(&team, "SELECT * FROM Teams WHERE InviteId = :InviteId", map[string]interface{}{"InviteId": inviteId}) 281 if err != nil { 282 return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.finding.app_error", nil, "inviteId="+inviteId+", "+err.Error(), http.StatusNotFound) 283 } 284 285 if len(inviteId) == 0 || team.InviteId != inviteId { 286 return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.find.app_error", nil, "inviteId="+inviteId, http.StatusNotFound) 287 } 288 return &team, nil 289 } 290 291 func (s SqlTeamStore) GetByName(name string) (*model.Team, *model.AppError) { 292 293 team := model.Team{} 294 295 err := s.GetReplica().SelectOne(&team, "SELECT * FROM Teams WHERE Name = :Name", map[string]interface{}{"Name": name}) 296 if err != nil { 297 return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) 298 } 299 return &team, nil 300 } 301 302 func (s SqlTeamStore) SearchByName(name string) ([]*model.Team, *model.AppError) { 303 var teams []*model.Team 304 305 if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Name LIKE :Name", map[string]interface{}{"Name": name + "%"}); err != nil { 306 return nil, model.NewAppError("SqlTeamStore.SearchByName", "store.sql_team.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) 307 } 308 309 return teams, nil 310 } 311 312 func (s SqlTeamStore) SearchAll(term string) ([]*model.Team, *model.AppError) { 313 var teams []*model.Team 314 315 if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Name LIKE :Term OR DisplayName LIKE :Term", map[string]interface{}{"Term": term + "%"}); err != nil { 316 return nil, model.NewAppError("SqlTeamStore.SearchAll", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 317 } 318 319 return teams, nil 320 } 321 322 func (s SqlTeamStore) SearchOpen(term string) ([]*model.Team, *model.AppError) { 323 var teams []*model.Team 324 325 if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Type = 'O' AND AllowOpenInvite = true AND (Name LIKE :Term OR DisplayName LIKE :Term)", map[string]interface{}{"Term": term + "%"}); err != nil { 326 return nil, model.NewAppError("SqlTeamStore.SearchOpen", "store.sql_team.search_open_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 327 } 328 329 return teams, nil 330 } 331 332 func (s SqlTeamStore) SearchPrivate(term string) ([]*model.Team, *model.AppError) { 333 var teams []*model.Team 334 335 query := 336 `SELECT * 337 FROM 338 Teams 339 WHERE 340 (Type != 'O' OR AllowOpenInvite = false) AND 341 (Name LIKE :Term OR DisplayName LIKE :Term)` 342 if _, err := s.GetReplica().Select(&teams, query, map[string]interface{}{"Term": term + "%"}); err != nil { 343 return nil, model.NewAppError("SqlTeamStore.SearchPrivate", "store.sql_team.search_private_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 344 } 345 return teams, nil 346 } 347 348 func (s SqlTeamStore) GetAll() ([]*model.Team, *model.AppError) { 349 var teams []*model.Team 350 351 _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams ORDER BY DisplayName") 352 if err != nil { 353 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 354 } 355 return teams, nil 356 } 357 358 func (s SqlTeamStore) GetAllPage(offset int, limit int) ([]*model.Team, *model.AppError) { 359 var teams []*model.Team 360 361 if _, err := s.GetReplica().Select(&teams, 362 `SELECT 363 * 364 FROM 365 Teams 366 ORDER BY 367 DisplayName 368 LIMIT 369 :Limit 370 OFFSET 371 :Offset`, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 372 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", 373 "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 374 } 375 376 return teams, nil 377 } 378 379 func (s SqlTeamStore) GetTeamsByUserId(userId string) store.StoreChannel { 380 return store.Do(func(result *store.StoreResult) { 381 var data []*model.Team 382 if _, err := s.GetReplica().Select(&data, "SELECT Teams.* FROM Teams, TeamMembers WHERE TeamMembers.TeamId = Teams.Id AND TeamMembers.UserId = :UserId AND TeamMembers.DeleteAt = 0 AND Teams.DeleteAt = 0", map[string]interface{}{"UserId": userId}); err != nil { 383 result.Err = model.NewAppError("SqlTeamStore.GetTeamsByUserId", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 384 return 385 } 386 387 result.Data = data 388 }) 389 } 390 391 func (s SqlTeamStore) GetAllPrivateTeamListing() store.StoreChannel { 392 return store.Do(func(result *store.StoreResult) { 393 query := "SELECT * FROM Teams WHERE AllowOpenInvite = 0 ORDER BY DisplayName" 394 395 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 396 query = "SELECT * FROM Teams WHERE AllowOpenInvite = false ORDER BY DisplayName" 397 } 398 399 var data []*model.Team 400 if _, err := s.GetReplica().Select(&data, query); err != nil { 401 result.Err = model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 402 return 403 } 404 405 result.Data = data 406 }) 407 } 408 409 func (s SqlTeamStore) GetAllPrivateTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { 410 query := "SELECT * FROM Teams WHERE AllowOpenInvite = 0 ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" 411 412 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 413 query = "SELECT * FROM Teams WHERE AllowOpenInvite = false ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" 414 } 415 416 var data []*model.Team 417 if _, err := s.GetReplica().Select(&data, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 418 return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 419 } 420 421 return data, nil 422 } 423 424 func (s SqlTeamStore) GetAllTeamListing() store.StoreChannel { 425 return store.Do(func(result *store.StoreResult) { 426 query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 ORDER BY DisplayName" 427 428 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 429 query = "SELECT * FROM Teams WHERE AllowOpenInvite = true ORDER BY DisplayName" 430 } 431 432 var data []*model.Team 433 if _, err := s.GetReplica().Select(&data, query); err != nil { 434 result.Err = model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 435 return 436 } 437 438 result.Data = data 439 }) 440 } 441 442 func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { 443 query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" 444 445 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 446 query = "SELECT * FROM Teams WHERE AllowOpenInvite = true ORDER BY DisplayName LIMIT :Limit OFFSET :Offset" 447 } 448 449 var teams []*model.Team 450 if _, err := s.GetReplica().Select(&teams, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 451 return nil, model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 452 } 453 454 return teams, nil 455 } 456 457 func (s SqlTeamStore) PermanentDelete(teamId string) *model.AppError { 458 if _, err := s.GetMaster().Exec("DELETE FROM Teams WHERE Id = :TeamId", map[string]interface{}{"TeamId": teamId}); err != nil { 459 return model.NewAppError("SqlTeamStore.Delete", "store.sql_team.permanent_delete.app_error", nil, "teamId="+teamId+", "+err.Error(), http.StatusInternalServerError) 460 } 461 return nil 462 } 463 464 func (s SqlTeamStore) AnalyticsTeamCount() (int64, *model.AppError) { 465 c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0", map[string]interface{}{}) 466 467 if err != nil { 468 return int64(0), model.NewAppError("SqlTeamStore.AnalyticsTeamCount", "store.sql_team.analytics_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) 469 } 470 471 return c, nil 472 } 473 474 func (s SqlTeamStore) getTeamMembersWithSchemeSelectQuery() sq.SelectBuilder { 475 return s.getQueryBuilder(). 476 Select( 477 "TeamMembers.*", 478 "TeamScheme.DefaultTeamGuestRole TeamSchemeDefaultGuestRole", 479 "TeamScheme.DefaultTeamUserRole TeamSchemeDefaultUserRole", 480 "TeamScheme.DefaultTeamAdminRole TeamSchemeDefaultAdminRole", 481 ). 482 From("TeamMembers"). 483 LeftJoin("Teams ON TeamMembers.TeamId = Teams.Id"). 484 LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id") 485 } 486 487 func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) store.StoreChannel { 488 return store.Do(func(result *store.StoreResult) { 489 defer s.InvalidateAllTeamIdsForUser(member.UserId) 490 if result.Err = member.IsValid(); result.Err != nil { 491 return 492 } 493 494 dbMember := NewTeamMemberFromModel(member) 495 496 if maxUsersPerTeam >= 0 { 497 count, err := s.GetMaster().SelectInt( 498 `SELECT 499 COUNT(0) 500 FROM 501 TeamMembers 502 INNER JOIN 503 Users 504 ON 505 TeamMembers.UserId = Users.Id 506 WHERE 507 TeamId = :TeamId 508 AND TeamMembers.DeleteAt = 0 509 AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": member.TeamId}) 510 511 if err != nil { 512 result.Err = model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, "teamId="+member.TeamId+", "+err.Error(), http.StatusInternalServerError) 513 return 514 } 515 516 if count >= int64(maxUsersPerTeam) { 517 result.Err = model.NewAppError("SqlUserStore.Save", "store.sql_user.save.max_accounts.app_error", nil, "teamId="+member.TeamId, http.StatusBadRequest) 518 return 519 } 520 } 521 522 if err := s.GetMaster().Insert(dbMember); err != nil { 523 if IsUniqueConstraintError(err, []string{"TeamId", "teammembers_pkey", "PRIMARY"}) { 524 result.Err = model.NewAppError("SqlTeamStore.SaveMember", TEAM_MEMBER_EXISTS_ERROR, nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest) 525 return 526 } 527 result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.save.app_error", nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError) 528 return 529 } 530 531 query := s.getTeamMembersWithSchemeSelectQuery(). 532 Where(sq.Eq{"TeamMembers.TeamId": dbMember.TeamId}). 533 Where(sq.Eq{"TeamMembers.UserId": dbMember.UserId}) 534 535 queryString, args, err := query.ToSql() 536 if err != nil { 537 result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.app_error", nil, err.Error(), http.StatusInternalServerError) 538 return 539 } 540 541 var retrievedMember teamMemberWithSchemeRoles 542 if err := s.GetMaster().SelectOne(&retrievedMember, queryString, args...); err != nil { 543 if err == sql.ErrNoRows { 544 result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.missing.app_error", nil, "team_id="+dbMember.TeamId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusNotFound) 545 return 546 } 547 result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.app_error", nil, "team_id="+dbMember.TeamId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusInternalServerError) 548 return 549 } 550 result.Data = retrievedMember.ToModel() 551 }) 552 } 553 554 func (s SqlTeamStore) UpdateMember(member *model.TeamMember) (*model.TeamMember, *model.AppError) { 555 member.PreUpdate() 556 557 if err := member.IsValid(); err != nil { 558 return nil, err 559 } 560 561 if _, err := s.GetMaster().Update(NewTeamMemberFromModel(member)); err != nil { 562 return nil, model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError) 563 } 564 565 query := s.getTeamMembersWithSchemeSelectQuery(). 566 Where(sq.Eq{"TeamMembers.TeamId": member.TeamId}). 567 Where(sq.Eq{"TeamMembers.UserId": member.UserId}) 568 569 queryString, args, err := query.ToSql() 570 if err != nil { 571 return nil, model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.app_error", nil, err.Error(), http.StatusInternalServerError) 572 } 573 574 var retrievedMember teamMemberWithSchemeRoles 575 if err := s.GetMaster().SelectOne(&retrievedMember, queryString, args...); err != nil { 576 if err == sql.ErrNoRows { 577 return nil, model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.missing.app_error", nil, "team_id="+member.TeamId+"user_id="+member.UserId+","+err.Error(), http.StatusNotFound) 578 } 579 return nil, model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.app_error", nil, "team_id="+member.TeamId+"user_id="+member.UserId+","+err.Error(), http.StatusInternalServerError) 580 } 581 582 return retrievedMember.ToModel(), nil 583 } 584 585 func (s SqlTeamStore) GetMember(teamId string, userId string) (*model.TeamMember, *model.AppError) { 586 query := s.getTeamMembersWithSchemeSelectQuery(). 587 Where(sq.Eq{"TeamMembers.TeamId": teamId}). 588 Where(sq.Eq{"TeamMembers.UserId": userId}) 589 590 queryString, args, err := query.ToSql() 591 if err != nil { 592 return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, err.Error(), http.StatusInternalServerError) 593 } 594 595 var dbMember teamMemberWithSchemeRoles 596 err = s.GetReplica().SelectOne(&dbMember, queryString, args...) 597 if err != nil { 598 if err == sql.ErrNoRows { 599 return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound) 600 } 601 return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusInternalServerError) 602 } 603 604 return dbMember.ToModel(), nil 605 } 606 607 func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError) { 608 query := s.getTeamMembersWithSchemeSelectQuery(). 609 Where(sq.Eq{"TeamMembers.TeamId": teamId}). 610 Where(sq.Eq{"TeamMembers.DeleteAt": 0}). 611 Limit(uint64(limit)). 612 Offset(uint64(offset)) 613 614 query = applyTeamMemberViewRestrictionsFilter(query, teamId, restrictions) 615 616 queryString, args, err := query.ToSql() 617 if err != nil { 618 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 619 } 620 621 var dbMembers teamMemberWithSchemeRolesList 622 _, err = s.GetReplica().Select(&dbMembers, queryString, args...) 623 if err != nil { 624 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 625 } 626 627 return dbMembers.ToModel(), nil 628 } 629 630 func (s SqlTeamStore) GetTotalMemberCount(teamId string) (int64, *model.AppError) { 631 count, err := s.GetReplica().SelectInt(` 632 SELECT 633 count(*) 634 FROM 635 TeamMembers, 636 Users 637 WHERE 638 TeamMembers.UserId = Users.Id 639 AND TeamMembers.TeamId = :TeamId 640 AND TeamMembers.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) 641 if err != nil { 642 return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 643 } 644 return count, nil 645 } 646 647 func (s SqlTeamStore) GetActiveMemberCount(teamId string) (int64, *model.AppError) { 648 count, err := s.GetReplica().SelectInt(` 649 SELECT 650 count(*) 651 FROM 652 TeamMembers, 653 Users 654 WHERE 655 TeamMembers.UserId = Users.Id 656 AND TeamMembers.TeamId = :TeamId 657 AND TeamMembers.DeleteAt = 0 658 AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) 659 if err != nil { 660 return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_active_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 661 } 662 663 return count, nil 664 } 665 666 func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError) { 667 if len(userIds) == 0 { 668 return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "Invalid list of user ids", http.StatusInternalServerError) 669 } 670 671 query := s.getTeamMembersWithSchemeSelectQuery(). 672 Where(sq.Eq{"TeamMembers.TeamId": teamId}). 673 Where(sq.Eq{"TeamMembers.UserId": userIds}). 674 Where(sq.Eq{"TeamMembers.DeleteAt": 0}) 675 676 query = applyTeamMemberViewRestrictionsFilter(query, teamId, restrictions) 677 678 queryString, args, err := query.ToSql() 679 if err != nil { 680 return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, err.Error(), http.StatusInternalServerError) 681 } 682 683 var dbMembers teamMemberWithSchemeRolesList 684 if _, err := s.GetReplica().Select(&dbMembers, queryString, args...); err != nil { 685 return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 686 } 687 return dbMembers.ToModel(), nil 688 } 689 690 func (s SqlTeamStore) GetTeamsForUser(userId string) ([]*model.TeamMember, *model.AppError) { 691 query := s.getTeamMembersWithSchemeSelectQuery(). 692 Where(sq.Eq{"TeamMembers.UserId": userId}) 693 694 queryString, args, err := query.ToSql() 695 if err != nil { 696 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 697 } 698 699 var dbMembers teamMemberWithSchemeRolesList 700 _, err = s.GetReplica().Select(&dbMembers, queryString, args...) 701 if err != nil { 702 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 703 } 704 705 return dbMembers.ToModel(), nil 706 } 707 708 func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage int) ([]*model.TeamMember, *model.AppError) { 709 query := s.getTeamMembersWithSchemeSelectQuery(). 710 Where(sq.Eq{"TeamMembers.UserId": userId}). 711 Limit(uint64(perPage)). 712 Offset(uint64(page * perPage)) 713 714 queryString, args, err := query.ToSql() 715 if err != nil { 716 return nil, model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 717 } 718 719 var dbMembers teamMemberWithSchemeRolesList 720 _, err = s.GetReplica().Select(&dbMembers, queryString, args...) 721 if err != nil { 722 return nil, model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 723 } 724 725 return dbMembers.ToModel(), nil 726 } 727 728 func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) ([]*model.ChannelUnread, *model.AppError) { 729 var data []*model.ChannelUnread 730 _, err := s.GetReplica().Select(&data, 731 `SELECT 732 Channels.TeamId TeamId, Channels.Id ChannelId, (Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount, ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps 733 FROM 734 Channels, ChannelMembers 735 WHERE 736 Id = ChannelId 737 AND UserId = :UserId 738 AND DeleteAt = 0 739 AND TeamId != :TeamId`, 740 map[string]interface{}{"UserId": userId, "TeamId": excludeTeamId}) 741 742 if err != nil { 743 return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForAllTeams", "store.sql_team.get_unread.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 744 } 745 746 return data, nil 747 } 748 749 func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) ([]*model.ChannelUnread, *model.AppError) { 750 query := ` 751 SELECT 752 Channels.TeamId TeamId, Channels.Id ChannelId, (Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount, ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps 753 FROM 754 Channels, ChannelMembers 755 WHERE 756 Id = ChannelId 757 AND UserId = :UserId 758 AND TeamId = :TeamId 759 AND DeleteAt = 0` 760 761 var channels []*model.ChannelUnread 762 _, err := s.GetReplica().Select(&channels, query, map[string]interface{}{"TeamId": teamId, "UserId": userId}) 763 764 if err != nil { 765 return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForTeam", "store.sql_team.get_unread.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 766 } 767 return channels, nil 768 } 769 770 func (s SqlTeamStore) RemoveMember(teamId string, userId string) store.StoreChannel { 771 return store.Do(func(result *store.StoreResult) { 772 _, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId AND UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId}) 773 if err != nil { 774 result.Err = model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", user_id="+userId+", "+err.Error(), http.StatusInternalServerError) 775 } 776 }) 777 } 778 779 func (s SqlTeamStore) RemoveAllMembersByTeam(teamId string) store.StoreChannel { 780 return store.Do(func(result *store.StoreResult) { 781 _, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId}) 782 if err != nil { 783 result.Err = model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError) 784 } 785 }) 786 } 787 788 func (s SqlTeamStore) RemoveAllMembersByUser(userId string) store.StoreChannel { 789 return store.Do(func(result *store.StoreResult) { 790 _, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}) 791 if err != nil { 792 result.Err = model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError) 793 } 794 }) 795 } 796 797 func (us SqlTeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) store.StoreChannel { 798 return store.Do(func(result *store.StoreResult) { 799 if _, err := us.GetMaster().Exec("UPDATE Teams SET LastTeamIconUpdate = :Time, UpdateAt = :Time WHERE Id = :teamId", map[string]interface{}{"Time": curTime, "teamId": teamId}); err != nil { 800 result.Err = model.NewAppError("SqlTeamStore.UpdateLastTeamIconUpdate", "store.sql_team.update_last_team_icon_update.app_error", nil, "team_id="+teamId, http.StatusInternalServerError) 801 return 802 } 803 result.Data = teamId 804 }) 805 } 806 807 func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) store.StoreChannel { 808 return store.Do(func(result *store.StoreResult) { 809 var teams []*model.Team 810 _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE SchemeId = :SchemeId ORDER BY DisplayName LIMIT :Limit OFFSET :Offset", map[string]interface{}{"SchemeId": schemeId, "Offset": offset, "Limit": limit}) 811 if err != nil { 812 result.Err = model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql_team.get_by_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError) 813 return 814 } 815 result.Data = teams 816 }) 817 } 818 819 // This function does the Advanced Permissions Phase 2 migration for TeamMember objects. It performs the migration 820 // in batches as a single transaction per batch to ensure consistency but to also minimise execution time to avoid 821 // causing unnecessary table locks. **THIS FUNCTION SHOULD NOT BE USED FOR ANY OTHER PURPOSE.** Executing this function 822 // *after* the new Schemes functionality has been used on an installation will have unintended consequences. 823 func (s SqlTeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) store.StoreChannel { 824 return store.Do(func(result *store.StoreResult) { 825 var transaction *gorp.Transaction 826 var err error 827 828 if transaction, err = s.GetMaster().Begin(); err != nil { 829 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 830 return 831 } 832 defer finalizeTransaction(transaction) 833 834 var teamMembers []teamMember 835 if _, err := transaction.Select(&teamMembers, "SELECT * from TeamMembers WHERE (TeamId, UserId) > (:FromTeamId, :FromUserId) ORDER BY TeamId, UserId LIMIT 100", map[string]interface{}{"FromTeamId": fromTeamId, "FromUserId": fromUserId}); err != nil { 836 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.select.app_error", nil, err.Error(), http.StatusInternalServerError) 837 return 838 } 839 840 if len(teamMembers) == 0 { 841 // No more team members in query result means that the migration has finished. 842 return 843 } 844 845 for _, member := range teamMembers { 846 roles := strings.Fields(member.Roles) 847 var newRoles []string 848 if !member.SchemeAdmin.Valid { 849 member.SchemeAdmin = sql.NullBool{Bool: false, Valid: true} 850 } 851 if !member.SchemeUser.Valid { 852 member.SchemeUser = sql.NullBool{Bool: false, Valid: true} 853 } 854 if !member.SchemeGuest.Valid { 855 member.SchemeGuest = sql.NullBool{Bool: false, Valid: true} 856 } 857 for _, role := range roles { 858 if role == model.TEAM_ADMIN_ROLE_ID { 859 member.SchemeAdmin = sql.NullBool{Bool: true, Valid: true} 860 } else if role == model.TEAM_USER_ROLE_ID { 861 member.SchemeUser = sql.NullBool{Bool: true, Valid: true} 862 } else if role == model.TEAM_GUEST_ROLE_ID { 863 member.SchemeGuest = sql.NullBool{Bool: true, Valid: true} 864 } else { 865 newRoles = append(newRoles, role) 866 } 867 } 868 member.Roles = strings.Join(newRoles, " ") 869 870 if _, err := transaction.Update(&member); err != nil { 871 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.update.app_error", nil, err.Error(), http.StatusInternalServerError) 872 return 873 } 874 875 } 876 877 if err := transaction.Commit(); err != nil { 878 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 879 return 880 } 881 882 data := make(map[string]string) 883 data["TeamId"] = teamMembers[len(teamMembers)-1].TeamId 884 data["UserId"] = teamMembers[len(teamMembers)-1].UserId 885 result.Data = data 886 }) 887 } 888 889 func (s SqlTeamStore) ResetAllTeamSchemes() store.StoreChannel { 890 return store.Do(func(result *store.StoreResult) { 891 if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId=''"); err != nil { 892 result.Err = model.NewAppError("SqlTeamStore.ResetAllTeamSchemes", "store.sql_team.reset_all_team_schemes.app_error", nil, err.Error(), http.StatusInternalServerError) 893 } 894 }) 895 } 896 897 var allTeamIdsForUserCache = utils.NewLru(ALL_TEAM_IDS_FOR_USER_CACHE_SIZE) 898 899 func (s SqlTeamStore) ClearCaches() { 900 allTeamIdsForUserCache.Purge() 901 if s.metrics != nil { 902 s.metrics.IncrementMemCacheInvalidationCounter("All Team Ids for User - Purge") 903 } 904 } 905 906 func (s SqlTeamStore) InvalidateAllTeamIdsForUser(userId string) { 907 allTeamIdsForUserCache.Remove(userId) 908 if s.metrics != nil { 909 s.metrics.IncrementMemCacheInvalidationCounter("All Team Ids for User - Remove by UserId") 910 } 911 } 912 913 func (s SqlTeamStore) ClearAllCustomRoleAssignments() store.StoreChannel { 914 return store.Do(func(result *store.StoreResult) { 915 builtInRoles := model.MakeDefaultRoles() 916 lastUserId := strings.Repeat("0", 26) 917 lastTeamId := strings.Repeat("0", 26) 918 919 for { 920 var transaction *gorp.Transaction 921 var err error 922 923 if transaction, err = s.GetMaster().Begin(); err != nil { 924 result.Err = model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 925 return 926 } 927 defer finalizeTransaction(transaction) 928 929 var teamMembers []*teamMember 930 if _, err := transaction.Select(&teamMembers, "SELECT * from TeamMembers WHERE (TeamId, UserId) > (:TeamId, :UserId) ORDER BY TeamId, UserId LIMIT 1000", map[string]interface{}{"TeamId": lastTeamId, "UserId": lastUserId}); err != nil { 931 result.Err = model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.select.app_error", nil, err.Error(), http.StatusInternalServerError) 932 return 933 } 934 935 if len(teamMembers) == 0 { 936 break 937 } 938 939 for _, member := range teamMembers { 940 lastUserId = member.UserId 941 lastTeamId = member.TeamId 942 943 var newRoles []string 944 945 for _, role := range strings.Fields(member.Roles) { 946 for name := range builtInRoles { 947 if name == role { 948 newRoles = append(newRoles, role) 949 break 950 } 951 } 952 } 953 954 newRolesString := strings.Join(newRoles, " ") 955 if newRolesString != member.Roles { 956 if _, err := transaction.Exec("UPDATE TeamMembers SET Roles = :Roles WHERE UserId = :UserId AND TeamId = :TeamId", map[string]interface{}{"Roles": newRolesString, "TeamId": member.TeamId, "UserId": member.UserId}); err != nil { 957 result.Err = model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.update.app_error", nil, err.Error(), http.StatusInternalServerError) 958 return 959 } 960 } 961 } 962 963 if err := transaction.Commit(); err != nil { 964 result.Err = model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 965 return 966 } 967 } 968 }) 969 } 970 971 func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) store.StoreChannel { 972 return store.Do(func(result *store.StoreResult) { 973 count, err := s.GetReplica().SelectInt("SELECT count(*) FROM Teams WHERE SchemeId = :SchemeId AND DeleteAt = 0", map[string]interface{}{"SchemeId": schemeId}) 974 if err != nil { 975 result.Err = model.NewAppError("SqlTeamStore.AnalyticsGetTeamCountForScheme", "store.sql_team.analytics_get_team_count_for_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError) 976 return 977 } 978 result.Data = count 979 }) 980 } 981 982 func (s SqlTeamStore) GetAllForExportAfter(limit int, afterId string) store.StoreChannel { 983 return store.Do(func(result *store.StoreResult) { 984 var data []*model.TeamForExport 985 if _, err := s.GetReplica().Select(&data, ` 986 SELECT 987 Teams.*, 988 Schemes.Name as SchemeName 989 FROM 990 Teams 991 LEFT JOIN 992 Schemes ON Teams.SchemeId = Schemes.Id 993 WHERE 994 Teams.Id > :AfterId 995 ORDER BY 996 Id 997 LIMIT 998 :Limit`, 999 map[string]interface{}{"AfterId": afterId, "Limit": limit}); err != nil { 1000 result.Err = model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 1001 return 1002 } 1003 1004 result.Data = data 1005 }) 1006 } 1007 1008 func (s SqlTeamStore) GetUserTeamIds(userId string, allowFromCache bool) store.StoreChannel { 1009 return store.Do(func(result *store.StoreResult) { 1010 if allowFromCache { 1011 if cacheItem, ok := allTeamIdsForUserCache.Get(userId); ok { 1012 if s.metrics != nil { 1013 s.metrics.IncrementMemCacheHitCounter("All Team Ids for User") 1014 } 1015 result.Data = cacheItem.([]string) 1016 return 1017 } 1018 } 1019 1020 if s.metrics != nil { 1021 s.metrics.IncrementMemCacheMissCounter("All Team Ids for User") 1022 } 1023 1024 var teamIds []string 1025 _, err := s.GetReplica().Select(&teamIds, ` 1026 SELECT 1027 TeamId 1028 FROM 1029 TeamMembers 1030 INNER JOIN 1031 Teams ON TeamMembers.TeamId = Teams.Id 1032 WHERE 1033 TeamMembers.UserId = :UserId 1034 AND TeamMembers.DeleteAt = 0 1035 AND Teams.DeleteAt = 0`, 1036 map[string]interface{}{"UserId": userId}) 1037 if err != nil { 1038 result.Err = model.NewAppError("SqlTeamStore.GetUserTeamIds", "store.sql_team.get_user_team_ids.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1039 return 1040 } 1041 1042 result.Data = teamIds 1043 1044 if allowFromCache { 1045 allTeamIdsForUserCache.AddWithExpiresInSecs(userId, teamIds, ALL_TEAM_IDS_FOR_USER_CACHE_SEC) 1046 } 1047 }) 1048 } 1049 1050 func (s SqlTeamStore) GetTeamMembersForExport(userId string) store.StoreChannel { 1051 return store.Do(func(result *store.StoreResult) { 1052 var members []*model.TeamMemberForExport 1053 _, err := s.GetReplica().Select(&members, ` 1054 SELECT 1055 TeamMembers.TeamId, 1056 TeamMembers.UserId, 1057 TeamMembers.Roles, 1058 TeamMembers.DeleteAt, 1059 (TeamMembers.SchemeGuest IS NOT NULL AND TeamMembers.SchemeGuest) as SchemeGuest, 1060 TeamMembers.SchemeUser, 1061 TeamMembers.SchemeAdmin, 1062 Teams.Name as TeamName 1063 FROM 1064 TeamMembers 1065 INNER JOIN 1066 Teams ON TeamMembers.TeamId = Teams.Id 1067 WHERE 1068 TeamMembers.UserId = :UserId 1069 AND Teams.DeleteAt = 0`, 1070 map[string]interface{}{"UserId": userId}) 1071 if err != nil { 1072 result.Err = model.NewAppError("SqlTeamStore.GetTeamMembersForExport", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1073 return 1074 } 1075 1076 result.Data = members 1077 }) 1078 } 1079 1080 func (s SqlTeamStore) UserBelongsToTeams(userId string, teamIds []string) store.StoreChannel { 1081 return store.Do(func(result *store.StoreResult) { 1082 props := make(map[string]interface{}) 1083 props["UserId"] = userId 1084 idQuery := "" 1085 1086 for index, teamId := range teamIds { 1087 if len(idQuery) > 0 { 1088 idQuery += ", " 1089 } 1090 1091 props["teamId"+strconv.Itoa(index)] = teamId 1092 idQuery += ":teamId" + strconv.Itoa(index) 1093 } 1094 c, err := s.GetReplica().SelectInt("SELECT Count(*) FROM TeamMembers WHERE UserId = :UserId AND TeamId IN ("+idQuery+") AND DeleteAt = 0", props) 1095 if err != nil { 1096 result.Err = model.NewAppError("SqlTeamStore.UserBelongsToTeams", "store.sql_team.user_belongs_to_teams.app_error", nil, err.Error(), http.StatusInternalServerError) 1097 return 1098 } 1099 result.Data = c > 0 1100 }) 1101 } 1102 1103 func applyTeamMemberViewRestrictionsFilter(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder { 1104 if restrictions == nil { 1105 return query 1106 } 1107 1108 // If you have no access to teams or channels, return and empty result. 1109 if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 { 1110 return query.Where("1 = 0") 1111 } 1112 1113 teams := make([]interface{}, len(restrictions.Teams)) 1114 for i, v := range restrictions.Teams { 1115 teams[i] = v 1116 } 1117 channels := make([]interface{}, len(restrictions.Channels)) 1118 for i, v := range restrictions.Channels { 1119 channels[i] = v 1120 } 1121 1122 resultQuery := query.Join("Users ru ON (TeamMembers.UserId = ru.Id)") 1123 if restrictions.Teams != nil && len(restrictions.Teams) > 0 { 1124 resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = ru.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...) 1125 } 1126 if restrictions.Channels != nil && len(restrictions.Channels) > 0 { 1127 resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = ru.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...) 1128 } 1129 1130 return resultQuery.Distinct() 1131 }