github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/sqlstore/team_store.go (about) 1 // Copyright (c) 2015-present Mattermost, 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 "strings" 11 12 sq "github.com/Masterminds/squirrel" 13 14 "github.com/mattermost/gorp" 15 "github.com/mattermost/mattermost-server/v5/model" 16 "github.com/mattermost/mattermost-server/v5/store" 17 "github.com/mattermost/mattermost-server/v5/utils" 18 ) 19 20 const ( 21 TEAM_MEMBER_EXISTS_ERROR = "store.sql_team.save_member.exists.app_error" 22 ) 23 24 type SqlTeamStore struct { 25 SqlStore 26 27 teamsQuery sq.SelectBuilder 28 } 29 30 type teamMember struct { 31 TeamId string 32 UserId string 33 Roles string 34 DeleteAt int64 35 SchemeUser sql.NullBool 36 SchemeAdmin sql.NullBool 37 SchemeGuest sql.NullBool 38 } 39 40 func NewTeamMemberFromModel(tm *model.TeamMember) *teamMember { 41 return &teamMember{ 42 TeamId: tm.TeamId, 43 UserId: tm.UserId, 44 Roles: tm.ExplicitRoles, 45 DeleteAt: tm.DeleteAt, 46 SchemeGuest: sql.NullBool{Valid: true, Bool: tm.SchemeGuest}, 47 SchemeUser: sql.NullBool{Valid: true, Bool: tm.SchemeUser}, 48 SchemeAdmin: sql.NullBool{Valid: true, Bool: tm.SchemeAdmin}, 49 } 50 } 51 52 type teamMemberWithSchemeRoles struct { 53 TeamId string 54 UserId string 55 Roles string 56 DeleteAt int64 57 SchemeGuest sql.NullBool 58 SchemeUser sql.NullBool 59 SchemeAdmin sql.NullBool 60 TeamSchemeDefaultGuestRole sql.NullString 61 TeamSchemeDefaultUserRole sql.NullString 62 TeamSchemeDefaultAdminRole sql.NullString 63 } 64 65 type teamMemberWithSchemeRolesList []teamMemberWithSchemeRoles 66 67 func teamMemberSliceColumns() []string { 68 return []string{"TeamId", "UserId", "Roles", "DeleteAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"} 69 } 70 71 func teamMemberToSlice(member *model.TeamMember) []interface{} { 72 resultSlice := []interface{}{} 73 resultSlice = append(resultSlice, member.TeamId) 74 resultSlice = append(resultSlice, member.UserId) 75 resultSlice = append(resultSlice, member.ExplicitRoles) 76 resultSlice = append(resultSlice, member.DeleteAt) 77 resultSlice = append(resultSlice, member.SchemeUser) 78 resultSlice = append(resultSlice, member.SchemeAdmin) 79 resultSlice = append(resultSlice, member.SchemeGuest) 80 return resultSlice 81 } 82 83 func wildcardSearchTerm(term string) string { 84 return strings.ToLower("%" + term + "%") 85 } 86 87 type rolesInfo struct { 88 roles []string 89 explicitRoles []string 90 schemeGuest bool 91 schemeUser bool 92 schemeAdmin bool 93 } 94 95 func getTeamRoles(schemeGuest, schemeUser, schemeAdmin bool, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole string, roles []string) rolesInfo { 96 result := rolesInfo{ 97 roles: []string{}, 98 explicitRoles: []string{}, 99 schemeGuest: schemeGuest, 100 schemeUser: schemeUser, 101 schemeAdmin: schemeAdmin, 102 } 103 // Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude 104 // them from ExplicitRoles field. 105 for _, role := range roles { 106 switch role { 107 case model.TEAM_GUEST_ROLE_ID: 108 result.schemeGuest = true 109 case model.TEAM_USER_ROLE_ID: 110 result.schemeUser = true 111 case model.TEAM_ADMIN_ROLE_ID: 112 result.schemeAdmin = true 113 default: 114 result.explicitRoles = append(result.explicitRoles, role) 115 result.roles = append(result.roles, role) 116 } 117 } 118 119 // Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add 120 // them to the Roles field for backwards compatibility reasons. 121 var schemeImpliedRoles []string 122 if result.schemeGuest { 123 if defaultTeamGuestRole != "" { 124 schemeImpliedRoles = append(schemeImpliedRoles, defaultTeamGuestRole) 125 } else { 126 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_GUEST_ROLE_ID) 127 } 128 } 129 if result.schemeUser { 130 if defaultTeamUserRole != "" { 131 schemeImpliedRoles = append(schemeImpliedRoles, defaultTeamUserRole) 132 } else { 133 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_USER_ROLE_ID) 134 } 135 } 136 if result.schemeAdmin { 137 if defaultTeamAdminRole != "" { 138 schemeImpliedRoles = append(schemeImpliedRoles, defaultTeamAdminRole) 139 } else { 140 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_ADMIN_ROLE_ID) 141 } 142 } 143 for _, impliedRole := range schemeImpliedRoles { 144 alreadyThere := false 145 for _, role := range result.roles { 146 if role == impliedRole { 147 alreadyThere = true 148 } 149 } 150 if !alreadyThere { 151 result.roles = append(result.roles, impliedRole) 152 } 153 } 154 return result 155 } 156 157 func (db teamMemberWithSchemeRoles) ToModel() *model.TeamMember { 158 // Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude 159 // them from ExplicitRoles field. 160 schemeGuest := db.SchemeGuest.Valid && db.SchemeGuest.Bool 161 schemeUser := db.SchemeUser.Valid && db.SchemeUser.Bool 162 schemeAdmin := db.SchemeAdmin.Valid && db.SchemeAdmin.Bool 163 164 defaultTeamGuestRole := "" 165 if db.TeamSchemeDefaultGuestRole.Valid { 166 defaultTeamGuestRole = db.TeamSchemeDefaultGuestRole.String 167 } 168 169 defaultTeamUserRole := "" 170 if db.TeamSchemeDefaultUserRole.Valid { 171 defaultTeamUserRole = db.TeamSchemeDefaultUserRole.String 172 } 173 174 defaultTeamAdminRole := "" 175 if db.TeamSchemeDefaultAdminRole.Valid { 176 defaultTeamAdminRole = db.TeamSchemeDefaultAdminRole.String 177 } 178 179 rolesResult := getTeamRoles(schemeGuest, schemeUser, schemeAdmin, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, strings.Fields(db.Roles)) 180 181 tm := &model.TeamMember{ 182 TeamId: db.TeamId, 183 UserId: db.UserId, 184 Roles: strings.Join(rolesResult.roles, " "), 185 DeleteAt: db.DeleteAt, 186 SchemeGuest: rolesResult.schemeGuest, 187 SchemeUser: rolesResult.schemeUser, 188 SchemeAdmin: rolesResult.schemeAdmin, 189 ExplicitRoles: strings.Join(rolesResult.explicitRoles, " "), 190 } 191 return tm 192 } 193 194 func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember { 195 tms := make([]*model.TeamMember, 0) 196 197 for _, tm := range db { 198 tms = append(tms, tm.ToModel()) 199 } 200 201 return tms 202 } 203 204 func newSqlTeamStore(sqlStore SqlStore) store.TeamStore { 205 s := &SqlTeamStore{ 206 SqlStore: sqlStore, 207 } 208 209 s.teamsQuery = s.getQueryBuilder(). 210 Select("Teams.*"). 211 From("Teams") 212 213 for _, db := range sqlStore.GetAllConns() { 214 table := db.AddTableWithName(model.Team{}, "Teams").SetKeys(false, "Id") 215 table.ColMap("Id").SetMaxSize(26) 216 table.ColMap("DisplayName").SetMaxSize(64) 217 table.ColMap("Name").SetMaxSize(64).SetUnique(true) 218 table.ColMap("Description").SetMaxSize(255) 219 table.ColMap("Email").SetMaxSize(128) 220 table.ColMap("CompanyName").SetMaxSize(64) 221 table.ColMap("AllowedDomains").SetMaxSize(1000) 222 table.ColMap("InviteId").SetMaxSize(32) 223 224 tablem := db.AddTableWithName(teamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId") 225 tablem.ColMap("TeamId").SetMaxSize(26) 226 tablem.ColMap("UserId").SetMaxSize(26) 227 tablem.ColMap("Roles").SetMaxSize(64) 228 } 229 230 return s 231 } 232 233 func (s SqlTeamStore) createIndexesIfNotExists() { 234 s.CreateIndexIfNotExists("idx_teams_name", "Teams", "Name") 235 s.RemoveIndexIfExists("idx_teams_description", "Teams") 236 s.CreateIndexIfNotExists("idx_teams_invite_id", "Teams", "InviteId") 237 s.CreateIndexIfNotExists("idx_teams_update_at", "Teams", "UpdateAt") 238 s.CreateIndexIfNotExists("idx_teams_create_at", "Teams", "CreateAt") 239 s.CreateIndexIfNotExists("idx_teams_delete_at", "Teams", "DeleteAt") 240 s.CreateIndexIfNotExists("idx_teams_scheme_id", "Teams", "SchemeId") 241 242 s.CreateIndexIfNotExists("idx_teammembers_team_id", "TeamMembers", "TeamId") 243 s.CreateIndexIfNotExists("idx_teammembers_user_id", "TeamMembers", "UserId") 244 s.CreateIndexIfNotExists("idx_teammembers_delete_at", "TeamMembers", "DeleteAt") 245 } 246 247 // Save adds the team to the database if a team with the same name does not already 248 // exist in the database. It returns the team added if the operation is successful. 249 func (s SqlTeamStore) Save(team *model.Team) (*model.Team, *model.AppError) { 250 if len(team.Id) > 0 { 251 return nil, model.NewAppError("SqlTeamStore.Save", 252 "store.sql_team.save.existing.app_error", nil, "id="+team.Id, http.StatusBadRequest) 253 } 254 255 team.PreSave() 256 257 if err := team.IsValid(); err != nil { 258 return nil, err 259 } 260 261 if err := s.GetMaster().Insert(team); err != nil { 262 if IsUniqueConstraintError(err, []string{"Name", "teams_name_key"}) { 263 return nil, model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.domain_exists.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusBadRequest) 264 } 265 return nil, model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 266 } 267 return team, nil 268 } 269 270 // Update updates the details of the team passed as the parameter using the team Id 271 // if the team exists in the database. 272 // It returns the updated team if the operation is successful. 273 func (s SqlTeamStore) Update(team *model.Team) (*model.Team, *model.AppError) { 274 275 team.PreUpdate() 276 277 if err := team.IsValid(); err != nil { 278 return nil, err 279 } 280 281 oldResult, err := s.GetMaster().Get(model.Team{}, team.Id) 282 if err != nil { 283 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.finding.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 284 285 } 286 287 if oldResult == nil { 288 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.find.app_error", nil, "id="+team.Id, http.StatusBadRequest) 289 } 290 291 oldTeam := oldResult.(*model.Team) 292 team.CreateAt = oldTeam.CreateAt 293 team.UpdateAt = model.GetMillis() 294 295 count, err := s.GetMaster().Update(team) 296 if err != nil { 297 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.updating.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 298 } 299 if count != 1 { 300 return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.app_error", nil, "id="+team.Id, http.StatusInternalServerError) 301 } 302 303 return team, nil 304 } 305 306 // Get returns from the database the team that matches the id provided as parameter. 307 // If the team doesn't exist it returns a model.AppError with a 308 // http.StatusNotFound in the StatusCode field. 309 func (s SqlTeamStore) Get(id string) (*model.Team, *model.AppError) { 310 obj, err := s.GetReplica().Get(model.Team{}, id) 311 if err != nil { 312 return nil, model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.finding.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 313 } 314 if obj == nil { 315 return nil, model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.find.app_error", nil, "id="+id, http.StatusNotFound) 316 } 317 318 return obj.(*model.Team), nil 319 } 320 321 // GetByInviteId returns from the database the team that matches the inviteId provided as parameter. 322 // If the parameter provided is empty or if there is no match in the database, it returns a model.AppError 323 // with a http.StatusNotFound in the StatusCode field. 324 func (s SqlTeamStore) GetByInviteId(inviteId string) (*model.Team, *model.AppError) { 325 team := model.Team{} 326 327 query, args, err := s.teamsQuery.Where(sq.Eq{"InviteId": inviteId}).ToSql() 328 if err != nil { 329 return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 330 } 331 err = s.GetReplica().SelectOne(&team, query, args...) 332 if err != nil { 333 return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.finding.app_error", nil, "inviteId="+inviteId+", "+err.Error(), http.StatusNotFound) 334 } 335 336 if len(inviteId) == 0 || team.InviteId != inviteId { 337 return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.find.app_error", nil, "inviteId="+inviteId, http.StatusNotFound) 338 } 339 return &team, nil 340 } 341 342 // GetByName returns from the database the team that matches the name provided as parameter. 343 // If there is no match in the database, it returns a model.AppError with a 344 // http.StatusNotFound in the StatusCode field. 345 func (s SqlTeamStore) GetByName(name string) (*model.Team, *model.AppError) { 346 347 team := model.Team{} 348 query, args, err := s.teamsQuery.Where(sq.Eq{"Name": name}).ToSql() 349 if err != nil { 350 return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 351 } 352 err = s.GetReplica().SelectOne(&team, query, args...) 353 if err != nil { 354 if err == sql.ErrNoRows { 355 return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.missing.app_error", nil, "name="+name+","+err.Error(), http.StatusNotFound) 356 } 357 return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) 358 } 359 return &team, nil 360 } 361 362 func (s SqlTeamStore) GetByNames(names []string) ([]*model.Team, *model.AppError) { 363 uniqueNames := utils.RemoveDuplicatesFromStringArray(names) 364 365 query, args, err := s.teamsQuery.Where(sq.Eq{"Name": uniqueNames}).ToSql() 366 367 if err != nil { 368 return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 369 } 370 371 teams := []*model.Team{} 372 _, err = s.GetReplica().Select(&teams, query, args...) 373 if err != nil { 374 if err == sql.ErrNoRows { 375 return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql_team.get_by_names.missing.app_error", nil, err.Error(), http.StatusNotFound) 376 } 377 return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql_team.get_by_names.app_error", nil, err.Error(), http.StatusInternalServerError) 378 } 379 if len(teams) != len(uniqueNames) { 380 return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql_team.get_by_names.missing.app_error", nil, "", http.StatusNotFound) 381 } 382 return teams, nil 383 } 384 385 func (s SqlTeamStore) teamSearchQuery(term string, opts *model.TeamSearch, countQuery bool) sq.SelectBuilder { 386 var selectStr string 387 if countQuery { 388 selectStr = "count(*)" 389 } else { 390 selectStr = "*" 391 } 392 393 query := s.getQueryBuilder(). 394 Select(selectStr). 395 From("Teams as t") 396 397 // Don't order or limit if getting count 398 if !countQuery { 399 query = query.OrderBy("t.DisplayName") 400 401 if opts.IsPaginated() { 402 query = query.Limit(uint64(*opts.PerPage)).Offset(uint64(*opts.Page * *opts.PerPage)) 403 } 404 } 405 406 if len(term) > 0 { 407 term = sanitizeSearchTerm(term, "\\") 408 term = wildcardSearchTerm(term) 409 410 operatorKeyword := "ILIKE" 411 if s.DriverName() == model.DATABASE_DRIVER_MYSQL { 412 operatorKeyword = "LIKE" 413 } 414 415 query = query.Where(fmt.Sprintf("(Name %[1]s ? OR DisplayName %[1]s ?)", operatorKeyword), term, term) 416 } 417 418 var teamFilters sq.Sqlizer 419 var openInviteFilter sq.Sqlizer 420 if opts.AllowOpenInvite != nil { 421 if *opts.AllowOpenInvite { 422 openInviteFilter = sq.Eq{"AllowOpenInvite": true} 423 } else { 424 openInviteFilter = sq.And{ 425 sq.Or{ 426 sq.NotEq{"AllowOpenInvite": true}, 427 sq.Eq{"AllowOpenInvite": nil}, 428 }, 429 sq.Or{ 430 sq.NotEq{"GroupConstrained": true}, 431 sq.Eq{"GroupConstrained": nil}, 432 }, 433 } 434 } 435 436 teamFilters = openInviteFilter 437 } 438 439 var groupConstrainedFilter sq.Sqlizer 440 if opts.GroupConstrained != nil { 441 if *opts.GroupConstrained { 442 groupConstrainedFilter = sq.Eq{"GroupConstrained": true} 443 } else { 444 groupConstrainedFilter = sq.Or{ 445 sq.NotEq{"GroupConstrained": true}, 446 sq.Eq{"GroupConstrained": nil}, 447 } 448 } 449 450 if teamFilters == nil { 451 teamFilters = groupConstrainedFilter 452 } else { 453 teamFilters = sq.Or{teamFilters, groupConstrainedFilter} 454 } 455 } 456 457 query = query.Where(teamFilters) 458 459 return query 460 } 461 462 // SearchAll returns from the database a list of teams that match the Name or DisplayName 463 // passed as the term search parameter. 464 func (s SqlTeamStore) SearchAll(term string, opts *model.TeamSearch) ([]*model.Team, *model.AppError) { 465 var teams []*model.Team 466 467 queryString, args, err := s.teamSearchQuery(term, opts, false).ToSql() 468 if err != nil { 469 return nil, model.NewAppError("SqlTeamStore.SearchAll", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 470 } 471 472 if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil { 473 return nil, model.NewAppError("SqlTeamStore.SearchAll", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 474 } 475 476 return teams, nil 477 } 478 479 // SearchAllPaged returns a teams list and the total count of teams that matched the search. 480 func (s SqlTeamStore) SearchAllPaged(term string, opts *model.TeamSearch) ([]*model.Team, int64, *model.AppError) { 481 var teams []*model.Team 482 var totalCount int64 483 484 queryString, args, err := s.teamSearchQuery(term, opts, false).ToSql() 485 if err != nil { 486 return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 487 } 488 if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil { 489 return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 490 } 491 492 queryString, args, err = s.teamSearchQuery(term, opts, true).ToSql() 493 if err != nil { 494 return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 495 } 496 totalCount, err = s.GetReplica().SelectInt(queryString, args...) 497 if err != nil { 498 return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 499 } 500 501 return teams, totalCount, nil 502 } 503 504 // SearchOpen returns from the database a list of public teams that match the Name or DisplayName 505 // passed as the term search parameter. 506 func (s SqlTeamStore) SearchOpen(term string) ([]*model.Team, *model.AppError) { 507 var teams []*model.Team 508 509 term = sanitizeSearchTerm(term, "\\") 510 term = wildcardSearchTerm(term) 511 query := s.teamsQuery.Where(sq.Eq{"Type": "O", "AllowOpenInvite": true}) 512 if s.DriverName() == model.DATABASE_DRIVER_MYSQL { 513 query = query.Where(sq.Or{sq.Like{"Name": term}, sq.Like{"DisplayName": term}}) 514 } else { 515 query = query.Where(sq.Or{sq.ILike{"Name": term}, sq.ILike{"DisplayName": term}}) 516 } 517 518 queryString, args, err := query.ToSql() 519 if err != nil { 520 return nil, model.NewAppError("SqlTeamStore.SearchOpen", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 521 } 522 523 if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil { 524 return nil, model.NewAppError("SqlTeamStore.SearchOpen", "store.sql_team.search_open_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 525 } 526 527 return teams, nil 528 } 529 530 // SearchPrivate returns from the database a list of private teams that match the Name or DisplayName 531 // passed as the term search parameter. 532 func (s SqlTeamStore) SearchPrivate(term string) ([]*model.Team, *model.AppError) { 533 var teams []*model.Team 534 535 term = sanitizeSearchTerm(term, "\\") 536 term = wildcardSearchTerm(term) 537 query := s.teamsQuery.Where(sq.Eq{"Type": "O", "AllowOpenInvite": false}) 538 if s.DriverName() == model.DATABASE_DRIVER_MYSQL { 539 query = query.Where(sq.Or{sq.Like{"Name": term}, sq.Like{"DisplayName": term}}) 540 } else { 541 query = query.Where(sq.Or{sq.ILike{"Name": term}, sq.ILike{"DisplayName": term}}) 542 } 543 544 queryString, args, err := query.ToSql() 545 if err != nil { 546 return nil, model.NewAppError("SqlTeamStore.SearchPrivate", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 547 } 548 549 if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil { 550 return nil, model.NewAppError("SqlTeamStore.SearchPrivate", "store.sql_team.search_private_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 551 } 552 return teams, nil 553 } 554 555 // GetAll returns all teams 556 func (s SqlTeamStore) GetAll() ([]*model.Team, *model.AppError) { 557 var teams []*model.Team 558 559 query, args, err := s.teamsQuery.OrderBy("DisplayName").ToSql() 560 561 if err != nil { 562 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 563 } 564 565 _, err = s.GetReplica().Select(&teams, query, args...) 566 if err != nil { 567 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 568 } 569 return teams, nil 570 } 571 572 // GetAllPage returns teams, up to a total limit passed as parameter and paginated by offset number passed as parameter. 573 func (s SqlTeamStore) GetAllPage(offset int, limit int) ([]*model.Team, *model.AppError) { 574 var teams []*model.Team 575 576 query, args, err := s.teamsQuery. 577 OrderBy("DisplayName"). 578 Limit(uint64(limit)). 579 Offset(uint64(offset)).ToSql() 580 581 if err != nil { 582 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 583 } 584 if _, err = s.GetReplica().Select(&teams, query, args...); err != nil { 585 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", 586 "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 587 } 588 589 return teams, nil 590 } 591 592 // GetTeamsByUserId returns from the database all teams that userId belongs to. 593 func (s SqlTeamStore) GetTeamsByUserId(userId string) ([]*model.Team, *model.AppError) { 594 var teams []*model.Team 595 query, args, err := s.teamsQuery. 596 Join("TeamMembers ON TeamMembers.TeamId = Teams.Id"). 597 Where(sq.Eq{"TeamMembers.UserId": userId, "TeamMembers.DeleteAt": 0, "Teams.DeleteAt": 0}).ToSql() 598 599 if err != nil { 600 return nil, model.NewAppError("SqlTeamStore.GetTeamsByUserId", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 601 } 602 603 if _, err = s.GetReplica().Select(&teams, query, args...); err != nil { 604 return nil, model.NewAppError("SqlTeamStore.GetTeamsByUserId", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 605 } 606 607 return teams, nil 608 } 609 610 // GetAllPrivateTeamListing returns all private teams. 611 func (s SqlTeamStore) GetAllPrivateTeamListing() ([]*model.Team, *model.AppError) { 612 query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": false}). 613 OrderBy("DisplayName").ToSql() 614 if err != nil { 615 return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 616 } 617 var data []*model.Team 618 if _, err = s.GetReplica().Select(&data, query, args...); err != nil { 619 return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 620 } 621 return data, nil 622 } 623 624 // GetAllPublicTeamPageListing returns public teams, up to a total limit passed as parameter and paginated by offset number passed as parameter. 625 func (s SqlTeamStore) GetAllPublicTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { 626 query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": true}). 627 OrderBy("DisplayName"). 628 Limit(uint64(limit)). 629 Offset(uint64(offset)).ToSql() 630 if err != nil { 631 return nil, model.NewAppError("SqlTeamStore.GetAllPublicTeamPageListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 632 } 633 634 var data []*model.Team 635 if _, err = s.GetReplica().Select(&data, query, args...); err != nil { 636 return nil, model.NewAppError("SqlTeamStore.GetAllPublicTeamPageListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 637 } 638 639 return data, nil 640 } 641 642 // GetAllPrivateTeamPageListing returns private teams, up to a total limit passed as paramater and paginated by offset number passed as parameter. 643 func (s SqlTeamStore) GetAllPrivateTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { 644 query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": false}). 645 OrderBy("DisplayName"). 646 Limit(uint64(limit)). 647 Offset(uint64(offset)).ToSql() 648 649 if err != nil { 650 return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamPageListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 651 } 652 653 var data []*model.Team 654 if _, err = s.GetReplica().Select(&data, query, args...); err != nil { 655 return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamPageListing", "store.sql_team.get_all_private_team_page_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 656 } 657 658 return data, nil 659 } 660 661 // GetAllTeamListing returns all public teams. 662 func (s SqlTeamStore) GetAllTeamListing() ([]*model.Team, *model.AppError) { 663 query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": true}). 664 OrderBy("DisplayName").ToSql() 665 666 if err != nil { 667 return nil, model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 668 } 669 670 var data []*model.Team 671 if _, err = s.GetReplica().Select(&data, query, args...); err != nil { 672 return nil, model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 673 } 674 675 return data, nil 676 } 677 678 // GetAllTeamPageListing returns public teams, up to a total limit passed as parameter and paginated by offset number passed as parameter. 679 func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) { 680 query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": true}). 681 OrderBy("DisplayName"). 682 Limit(uint64(limit)). 683 Offset(uint64(offset)).ToSql() 684 685 if err != nil { 686 return nil, model.NewAppError("SqlTeamStore.GetAllTeamPageListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 687 } 688 689 var teams []*model.Team 690 if _, err = s.GetReplica().Select(&teams, query, args...); err != nil { 691 return nil, model.NewAppError("SqlTeamStore.GetAllTeamPageListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 692 } 693 694 return teams, nil 695 } 696 697 // PermanentDelete permanently deletes from the database the team entry that matches the teamId passed as parameter. 698 // To soft-delete the team you can Update it with the DeleteAt field set to the current millisecond using model.GetMillis() 699 func (s SqlTeamStore) PermanentDelete(teamId string) *model.AppError { 700 sql, args, err := s.getQueryBuilder(). 701 Delete("Teams"). 702 Where(sq.Eq{"Id": teamId}).ToSql() 703 if err != nil { 704 return model.NewAppError("SqlTeamStore.Delete", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 705 } 706 if _, err = s.GetMaster().Exec(sql, args...); err != nil { 707 return model.NewAppError("SqlTeamStore.Delete", "store.sql_team.permanent_delete.app_error", nil, "teamId="+teamId+", "+err.Error(), http.StatusInternalServerError) 708 } 709 return nil 710 } 711 712 // AnalyticsPublicTeamCount returns the number of active public teams. 713 func (s SqlTeamStore) AnalyticsPublicTeamCount() (int64, *model.AppError) { 714 query, args, err := s.getQueryBuilder(). 715 Select("COUNT(*) FROM Teams"). 716 Where(sq.Eq{"DeleteAt": 0, "AllowOpenInvite": true}).ToSql() 717 718 if err != nil { 719 return 0, model.NewAppError("SqlTeamStore.AnalyticsPublicTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 720 } 721 722 c, err := s.GetReplica().SelectInt(query, args...) 723 724 if err != nil { 725 return int64(0), model.NewAppError("SqlTeamStore.AnalyticsPublicTeamCount", "store.sql_team.analytics_public_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) 726 } 727 728 return c, nil 729 } 730 731 // AnalyticsPrivateTeamCount returns the number of active private teams. 732 func (s SqlTeamStore) AnalyticsPrivateTeamCount() (int64, *model.AppError) { 733 query, args, err := s.getQueryBuilder(). 734 Select("COUNT(*) FROM Teams"). 735 Where(sq.Eq{"DeleteAt": 0, "AllowOpenInvite": false}).ToSql() 736 737 if err != nil { 738 return 0, model.NewAppError("SqlTeamStore.AnalyticsPrivateTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 739 } 740 c, err := s.GetReplica().SelectInt(query, args...) 741 742 if err != nil { 743 return int64(0), model.NewAppError("SqlTeamStore.AnalyticsPrivateTeamCount", "store.sql_team.analytics_private_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) 744 } 745 746 return c, nil 747 } 748 749 // AnalyticsTeamCount returns the total number of teams including deleted teams if parameter passed is set to 'true'. 750 func (s SqlTeamStore) AnalyticsTeamCount(includeDeleted bool) (int64, *model.AppError) { 751 query := s.getQueryBuilder().Select("COUNT(*) FROM Teams") 752 if !includeDeleted { 753 query = query.Where(sq.Eq{"DeleteAt": 0}) 754 } 755 756 queryString, args, err := query.ToSql() 757 if err != nil { 758 return 0, model.NewAppError("SqlTeamStore.AnalyticsTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 759 } 760 761 c, err := s.GetReplica().SelectInt(queryString, args...) 762 763 if err != nil { 764 return int64(0), model.NewAppError("SqlTeamStore.AnalyticsTeamCount", "store.sql_team.analytics_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) 765 } 766 767 return c, nil 768 } 769 770 func (s SqlTeamStore) getTeamMembersWithSchemeSelectQuery() sq.SelectBuilder { 771 return s.getQueryBuilder(). 772 Select( 773 "TeamMembers.*", 774 "TeamScheme.DefaultTeamGuestRole TeamSchemeDefaultGuestRole", 775 "TeamScheme.DefaultTeamUserRole TeamSchemeDefaultUserRole", 776 "TeamScheme.DefaultTeamAdminRole TeamSchemeDefaultAdminRole", 777 ). 778 From("TeamMembers"). 779 LeftJoin("Teams ON TeamMembers.TeamId = Teams.Id"). 780 LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id") 781 } 782 783 func (s SqlTeamStore) SaveMultipleMembers(members []*model.TeamMember, maxUsersPerTeam int) ([]*model.TeamMember, *model.AppError) { 784 newTeamMembers := map[string]int{} 785 users := map[string]bool{} 786 for _, member := range members { 787 newTeamMembers[member.TeamId] = 0 788 } 789 790 for _, member := range members { 791 newTeamMembers[member.TeamId]++ 792 users[member.UserId] = true 793 794 if err := member.IsValid(); err != nil { 795 return nil, err 796 } 797 } 798 799 teams := []string{} 800 for team := range newTeamMembers { 801 teams = append(teams, team) 802 } 803 804 defaultTeamRolesByTeam := map[string]struct { 805 Id string 806 Guest sql.NullString 807 User sql.NullString 808 Admin sql.NullString 809 }{} 810 811 queryRoles := s.getQueryBuilder(). 812 Select( 813 "Teams.Id as Id", 814 "TeamScheme.DefaultTeamGuestRole as Guest", 815 "TeamScheme.DefaultTeamUserRole as User", 816 "TeamScheme.DefaultTeamAdminRole as Admin", 817 ). 818 From("Teams"). 819 LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id"). 820 Where(sq.Eq{"Teams.Id": teams}) 821 822 sqlRolesQuery, argsRoles, err := queryRoles.ToSql() 823 if err != nil { 824 return nil, model.NewAppError("SqlUserStore.Save", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 825 } 826 var defaultTeamsRoles []struct { 827 Id string 828 Guest sql.NullString 829 User sql.NullString 830 Admin sql.NullString 831 } 832 _, err = s.GetMaster().Select(&defaultTeamsRoles, sqlRolesQuery, argsRoles...) 833 if err != nil { 834 return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, err.Error(), http.StatusInternalServerError) 835 } 836 837 for _, defaultRoles := range defaultTeamsRoles { 838 defaultTeamRolesByTeam[defaultRoles.Id] = defaultRoles 839 } 840 841 if maxUsersPerTeam >= 0 { 842 queryCount := s.getQueryBuilder(). 843 Select( 844 "COUNT(0) as Count, TeamMembers.TeamId as TeamId", 845 ). 846 From("TeamMembers"). 847 Join("Users ON TeamMembers.UserId = Users.Id"). 848 Where(sq.Eq{"TeamMembers.TeamId": teams}). 849 Where(sq.Eq{"TeamMembers.DeleteAt": 0}). 850 Where(sq.Eq{"Users.DeleteAt": 0}). 851 GroupBy("TeamMembers.TeamId") 852 853 sqlCountQuery, argsCount, errCount := queryCount.ToSql() 854 if errCount != nil { 855 return nil, model.NewAppError("SqlUserStore.Save", "store.sql.build_query.app_error", nil, errCount.Error(), http.StatusInternalServerError) 856 } 857 858 var counters []struct { 859 Count int `db:"Count"` 860 TeamId string `db:"TeamId"` 861 } 862 863 _, err = s.GetMaster().Select(&counters, sqlCountQuery, argsCount...) 864 if err != nil { 865 return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, err.Error(), http.StatusInternalServerError) 866 } 867 868 for teamId, newMembers := range newTeamMembers { 869 existingMembers := 0 870 for _, counter := range counters { 871 if counter.TeamId == teamId { 872 existingMembers = counter.Count 873 } 874 } 875 if existingMembers+newMembers > maxUsersPerTeam { 876 return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.max_accounts.app_error", nil, "", http.StatusBadRequest) 877 } 878 } 879 } 880 881 query := s.getQueryBuilder().Insert("TeamMembers").Columns(teamMemberSliceColumns()...) 882 for _, member := range members { 883 query = query.Values(teamMemberToSlice(member)...) 884 } 885 886 sql, args, err := query.ToSql() 887 if err != nil { 888 return nil, model.NewAppError("SqlTeamStore.SaveMember", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 889 } 890 891 if _, err = s.GetMaster().Exec(sql, args...); err != nil { 892 if IsUniqueConstraintError(err, []string{"TeamId", "teammembers_pkey", "PRIMARY"}) { 893 return nil, model.NewAppError("SqlTeamStore.SaveMember", TEAM_MEMBER_EXISTS_ERROR, nil, err.Error(), http.StatusBadRequest) 894 } 895 return nil, model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError) 896 } 897 898 newMembers := []*model.TeamMember{} 899 for _, member := range members { 900 s.InvalidateAllTeamIdsForUser(member.UserId) 901 defaultTeamGuestRole := defaultTeamRolesByTeam[member.TeamId].Guest.String 902 defaultTeamUserRole := defaultTeamRolesByTeam[member.TeamId].User.String 903 defaultTeamAdminRole := defaultTeamRolesByTeam[member.TeamId].Admin.String 904 rolesResult := getTeamRoles(member.SchemeGuest, member.SchemeUser, member.SchemeAdmin, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, strings.Fields(member.ExplicitRoles)) 905 newMember := *member 906 newMember.SchemeGuest = rolesResult.schemeGuest 907 newMember.SchemeUser = rolesResult.schemeUser 908 newMember.SchemeAdmin = rolesResult.schemeAdmin 909 newMember.Roles = strings.Join(rolesResult.roles, " ") 910 newMember.ExplicitRoles = strings.Join(rolesResult.explicitRoles, " ") 911 newMembers = append(newMembers, &newMember) 912 } 913 914 return newMembers, nil 915 } 916 917 func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) (*model.TeamMember, *model.AppError) { 918 members, err := s.SaveMultipleMembers([]*model.TeamMember{member}, maxUsersPerTeam) 919 if err != nil { 920 return nil, err 921 } 922 return members[0], nil 923 } 924 925 func (s SqlTeamStore) UpdateMultipleMembers(members []*model.TeamMember) ([]*model.TeamMember, *model.AppError) { 926 teams := []string{} 927 for _, member := range members { 928 member.PreUpdate() 929 930 if err := member.IsValid(); err != nil { 931 return nil, err 932 } 933 934 if _, err := s.GetMaster().Update(NewTeamMemberFromModel(member)); err != nil { 935 return nil, model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError) 936 } 937 teams = append(teams, member.TeamId) 938 } 939 940 query := s.getQueryBuilder(). 941 Select( 942 "Teams.Id as Id", 943 "TeamScheme.DefaultTeamGuestRole as Guest", 944 "TeamScheme.DefaultTeamUserRole as User", 945 "TeamScheme.DefaultTeamAdminRole as Admin", 946 ). 947 From("Teams"). 948 LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id"). 949 Where(sq.Eq{"Teams.Id": teams}) 950 951 sqlQuery, args, err := query.ToSql() 952 if err != nil { 953 return nil, model.NewAppError("SqlUserStore.Save", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 954 } 955 var defaultTeamsRoles []struct { 956 Id string 957 Guest sql.NullString 958 User sql.NullString 959 Admin sql.NullString 960 } 961 _, err = s.GetMaster().Select(&defaultTeamsRoles, sqlQuery, args...) 962 if err != nil { 963 return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, err.Error(), http.StatusInternalServerError) 964 } 965 966 defaultTeamRolesByTeam := map[string]struct { 967 Id string 968 Guest sql.NullString 969 User sql.NullString 970 Admin sql.NullString 971 }{} 972 for _, defaultRoles := range defaultTeamsRoles { 973 defaultTeamRolesByTeam[defaultRoles.Id] = defaultRoles 974 } 975 976 updatedMembers := []*model.TeamMember{} 977 for _, member := range members { 978 s.InvalidateAllTeamIdsForUser(member.UserId) 979 defaultTeamGuestRole := defaultTeamRolesByTeam[member.TeamId].Guest.String 980 defaultTeamUserRole := defaultTeamRolesByTeam[member.TeamId].User.String 981 defaultTeamAdminRole := defaultTeamRolesByTeam[member.TeamId].Admin.String 982 rolesResult := getTeamRoles(member.SchemeGuest, member.SchemeUser, member.SchemeAdmin, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, strings.Fields(member.ExplicitRoles)) 983 updatedMember := *member 984 updatedMember.SchemeGuest = rolesResult.schemeGuest 985 updatedMember.SchemeUser = rolesResult.schemeUser 986 updatedMember.SchemeAdmin = rolesResult.schemeAdmin 987 updatedMember.Roles = strings.Join(rolesResult.roles, " ") 988 updatedMember.ExplicitRoles = strings.Join(rolesResult.explicitRoles, " ") 989 updatedMembers = append(updatedMembers, &updatedMember) 990 } 991 992 return updatedMembers, nil 993 } 994 995 func (s SqlTeamStore) UpdateMember(member *model.TeamMember) (*model.TeamMember, *model.AppError) { 996 members, err := s.UpdateMultipleMembers([]*model.TeamMember{member}) 997 if err != nil { 998 return nil, err 999 } 1000 return members[0], nil 1001 } 1002 1003 func (s SqlTeamStore) GetMember(teamId string, userId string) (*model.TeamMember, *model.AppError) { 1004 query := s.getTeamMembersWithSchemeSelectQuery(). 1005 Where(sq.Eq{"TeamMembers.TeamId": teamId}). 1006 Where(sq.Eq{"TeamMembers.UserId": userId}) 1007 1008 queryString, args, err := query.ToSql() 1009 if err != nil { 1010 return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1011 } 1012 1013 var dbMember teamMemberWithSchemeRoles 1014 err = s.GetReplica().SelectOne(&dbMember, queryString, args...) 1015 if err != nil { 1016 if err == sql.ErrNoRows { 1017 return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound) 1018 } 1019 return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1020 } 1021 1022 return dbMember.ToModel(), nil 1023 } 1024 1025 func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int, teamMembersGetOptions *model.TeamMembersGetOptions) ([]*model.TeamMember, *model.AppError) { 1026 query := s.getTeamMembersWithSchemeSelectQuery(). 1027 Where(sq.Eq{"TeamMembers.TeamId": teamId}). 1028 Where(sq.Eq{"TeamMembers.DeleteAt": 0}). 1029 Limit(uint64(limit)). 1030 Offset(uint64(offset)) 1031 1032 if teamMembersGetOptions == nil || teamMembersGetOptions.Sort == "" { 1033 query = query.OrderBy("UserId") 1034 } 1035 1036 if teamMembersGetOptions != nil { 1037 if teamMembersGetOptions.Sort == model.USERNAME || teamMembersGetOptions.ExcludeDeletedUsers { 1038 query = query.LeftJoin("Users ON TeamMembers.UserId = Users.Id") 1039 } 1040 1041 if teamMembersGetOptions.ExcludeDeletedUsers { 1042 query = query.Where(sq.Eq{"Users.DeleteAt": 0}) 1043 } 1044 1045 if teamMembersGetOptions.Sort == model.USERNAME { 1046 query = query.OrderBy(model.USERNAME) 1047 } 1048 1049 query = applyTeamMemberViewRestrictionsFilter(query, teamId, teamMembersGetOptions.ViewRestrictions) 1050 } 1051 1052 queryString, args, err := query.ToSql() 1053 if err != nil { 1054 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1055 } 1056 1057 var dbMembers teamMemberWithSchemeRolesList 1058 _, err = s.GetReplica().Select(&dbMembers, queryString, args...) 1059 if err != nil { 1060 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 1061 } 1062 1063 return dbMembers.ToModel(), nil 1064 } 1065 1066 func (s SqlTeamStore) GetTotalMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) { 1067 query := s.getQueryBuilder(). 1068 Select("count(DISTINCT TeamMembers.UserId)"). 1069 From("TeamMembers, Users"). 1070 Where("TeamMembers.DeleteAt = 0"). 1071 Where("TeamMembers.UserId = Users.Id"). 1072 Where(sq.Eq{"TeamMembers.TeamId": teamId}) 1073 1074 query = applyTeamMemberViewRestrictionsFilterForStats(query, teamId, restrictions) 1075 queryString, args, err := query.ToSql() 1076 if err != nil { 1077 return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1078 } 1079 1080 count, err := s.GetReplica().SelectInt(queryString, args...) 1081 if err != nil { 1082 return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 1083 } 1084 return count, nil 1085 } 1086 1087 func (s SqlTeamStore) GetActiveMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) { 1088 query := s.getQueryBuilder(). 1089 Select("count(DISTINCT TeamMembers.UserId)"). 1090 From("TeamMembers, Users"). 1091 Where("TeamMembers.DeleteAt = 0"). 1092 Where("TeamMembers.UserId = Users.Id"). 1093 Where("Users.DeleteAt = 0"). 1094 Where(sq.Eq{"TeamMembers.TeamId": teamId}) 1095 1096 query = applyTeamMemberViewRestrictionsFilterForStats(query, teamId, restrictions) 1097 queryString, args, err := query.ToSql() 1098 if err != nil { 1099 return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1100 } 1101 1102 count, err := s.GetReplica().SelectInt(queryString, args...) 1103 if err != nil { 1104 return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_active_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 1105 } 1106 1107 return count, nil 1108 } 1109 1110 func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError) { 1111 if len(userIds) == 0 { 1112 return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "Invalid list of user ids", http.StatusInternalServerError) 1113 } 1114 1115 query := s.getTeamMembersWithSchemeSelectQuery(). 1116 Where(sq.Eq{"TeamMembers.TeamId": teamId}). 1117 Where(sq.Eq{"TeamMembers.UserId": userIds}). 1118 Where(sq.Eq{"TeamMembers.DeleteAt": 0}) 1119 1120 query = applyTeamMemberViewRestrictionsFilter(query, teamId, restrictions) 1121 1122 queryString, args, err := query.ToSql() 1123 if err != nil { 1124 return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1125 } 1126 1127 var dbMembers teamMemberWithSchemeRolesList 1128 if _, err = s.GetReplica().Select(&dbMembers, queryString, args...); err != nil { 1129 return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 1130 } 1131 return dbMembers.ToModel(), nil 1132 } 1133 1134 func (s SqlTeamStore) GetTeamsForUser(userId string) ([]*model.TeamMember, *model.AppError) { 1135 query := s.getTeamMembersWithSchemeSelectQuery(). 1136 Where(sq.Eq{"TeamMembers.UserId": userId}) 1137 1138 queryString, args, err := query.ToSql() 1139 if err != nil { 1140 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1141 } 1142 1143 var dbMembers teamMemberWithSchemeRolesList 1144 _, err = s.GetReplica().Select(&dbMembers, queryString, args...) 1145 if err != nil { 1146 return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1147 } 1148 1149 return dbMembers.ToModel(), nil 1150 } 1151 1152 func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage int) ([]*model.TeamMember, *model.AppError) { 1153 query := s.getTeamMembersWithSchemeSelectQuery(). 1154 Where(sq.Eq{"TeamMembers.UserId": userId}). 1155 Limit(uint64(perPage)). 1156 Offset(uint64(page * perPage)) 1157 1158 queryString, args, err := query.ToSql() 1159 if err != nil { 1160 return nil, model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1161 } 1162 1163 var dbMembers teamMemberWithSchemeRolesList 1164 _, err = s.GetReplica().Select(&dbMembers, queryString, args...) 1165 if err != nil { 1166 return nil, model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1167 } 1168 1169 return dbMembers.ToModel(), nil 1170 } 1171 1172 func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) ([]*model.ChannelUnread, *model.AppError) { 1173 query, args, err := s.getQueryBuilder(). 1174 Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps"). 1175 From("Channels"). 1176 Join("ChannelMembers ON Id = ChannelId"). 1177 Where(sq.Eq{"UserId": userId, "DeleteAt": 0}). 1178 Where(sq.NotEq{"TeamId": excludeTeamId}).ToSql() 1179 1180 if err != nil { 1181 return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1182 } 1183 var data []*model.ChannelUnread 1184 _, err = s.GetReplica().Select(&data, query, args...) 1185 1186 if err != nil { 1187 return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForAllTeams", "store.sql_team.get_unread.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1188 } 1189 1190 return data, nil 1191 } 1192 1193 func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) ([]*model.ChannelUnread, *model.AppError) { 1194 query, args, err := s.getQueryBuilder(). 1195 Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps"). 1196 From("Channels"). 1197 Join("ChannelMembers ON Id = ChannelId"). 1198 Where(sq.Eq{"UserId": userId, "TeamId": teamId, "DeleteAt": 0}).ToSql() 1199 1200 if err != nil { 1201 return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForTeam", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1202 } 1203 1204 var channels []*model.ChannelUnread 1205 _, err = s.GetReplica().Select(&channels, query, args...) 1206 1207 if err != nil { 1208 return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForTeam", "store.sql_team.get_unread.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 1209 } 1210 return channels, nil 1211 } 1212 1213 func (s SqlTeamStore) RemoveMembers(teamId string, userIds []string) *model.AppError { 1214 query := s.getQueryBuilder(). 1215 Delete("TeamMembers"). 1216 Where(sq.Eq{"TeamId": teamId}). 1217 Where(sq.Eq{"UserId": userIds}) 1218 1219 sql, args, err := query.ToSql() 1220 if err != nil { 1221 return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql.build_query.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError) 1222 } 1223 _, err = s.GetMaster().Exec(sql, args...) 1224 if err != nil { 1225 return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError) 1226 } 1227 return nil 1228 } 1229 1230 // RemoveMember remove from the database the team members that match the userId and teamId passed as parameter. 1231 func (s SqlTeamStore) RemoveMember(teamId string, userId string) *model.AppError { 1232 return s.RemoveMembers(teamId, []string{userId}) 1233 } 1234 1235 // RemoveAllMembersByTeam removes from the database the team members that belong to the teamId passed as parameter. 1236 func (s SqlTeamStore) RemoveAllMembersByTeam(teamId string) *model.AppError { 1237 sql, args, err := s.getQueryBuilder(). 1238 Delete("TeamMembers"). 1239 Where(sq.Eq{"TeamId": teamId}).ToSql() 1240 if err != nil { 1241 return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql.build_query.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError) 1242 } 1243 1244 _, err = s.GetMaster().Exec(sql, args...) 1245 if err != nil { 1246 return model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError) 1247 } 1248 return nil 1249 } 1250 1251 // RemoveAllMembersByUser removes from the database the team members that match the userId passed as parameter. 1252 func (s SqlTeamStore) RemoveAllMembersByUser(userId string) *model.AppError { 1253 sql, args, err := s.getQueryBuilder(). 1254 Delete("TeamMembers"). 1255 Where(sq.Eq{"UserId": userId}).ToSql() 1256 if err != nil { 1257 return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql.build_query.app_error", nil, "team_id="+userId+", "+err.Error(), http.StatusInternalServerError) 1258 } 1259 _, err = s.GetMaster().Exec(sql, args...) 1260 if err != nil { 1261 return model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError) 1262 } 1263 return nil 1264 } 1265 1266 func (s SqlTeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) *model.AppError { 1267 sql, args, err := s.getQueryBuilder(). 1268 Update("Teams"). 1269 SetMap(sq.Eq{"LastTeamIconUpdate": curTime, "UpdateAt": curTime}). 1270 Where(sq.Eq{"Id": teamId}).ToSql() 1271 if err != nil { 1272 return model.NewAppError("SqlTeamStore.UpdateLastTeamIconUpdate", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1273 } 1274 1275 if _, err = s.GetMaster().Exec(sql, args...); err != nil { 1276 return model.NewAppError("SqlTeamStore.UpdateLastTeamIconUpdate", "store.sql_team.update_last_team_icon_update.app_error", nil, "team_id="+teamId, http.StatusInternalServerError) 1277 } 1278 return nil 1279 } 1280 1281 // GetTeamsByScheme returns from the database all teams that match the schemeId provided as parameter, up to 1282 // a total limit passed as paramater and paginated by offset number passed as parameter. 1283 func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) ([]*model.Team, *model.AppError) { 1284 query, args, err := s.teamsQuery.Where(sq.Eq{"SchemeId": schemeId}). 1285 OrderBy("DisplayName"). 1286 Limit(uint64(limit)). 1287 Offset(uint64(offset)).ToSql() 1288 1289 if err != nil { 1290 return nil, model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1291 } 1292 1293 var teams []*model.Team 1294 _, err = s.GetReplica().Select(&teams, query, args...) 1295 if err != nil { 1296 return nil, model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql_team.get_by_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError) 1297 } 1298 return teams, nil 1299 } 1300 1301 // This function does the Advanced Permissions Phase 2 migration for TeamMember objects. It performs the migration 1302 // in batches as a single transaction per batch to ensure consistency but to also minimise execution time to avoid 1303 // causing unnecessary table locks. **THIS FUNCTION SHOULD NOT BE USED FOR ANY OTHER PURPOSE.** Executing this function 1304 // *after* the new Schemes functionality has been used on an installation will have unintended consequences. 1305 func (s SqlTeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) (map[string]string, *model.AppError) { 1306 var transaction *gorp.Transaction 1307 var err error 1308 1309 if transaction, err = s.GetMaster().Begin(); err != nil { 1310 return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 1311 } 1312 defer finalizeTransaction(transaction) 1313 1314 var teamMembers []teamMember 1315 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 { 1316 return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.select.app_error", nil, err.Error(), http.StatusInternalServerError) 1317 } 1318 1319 if len(teamMembers) == 0 { 1320 // No more team members in query result means that the migration has finished. 1321 return nil, nil 1322 } 1323 1324 for i := range teamMembers { 1325 member := teamMembers[i] 1326 roles := strings.Fields(member.Roles) 1327 var newRoles []string 1328 if !member.SchemeAdmin.Valid { 1329 member.SchemeAdmin = sql.NullBool{Bool: false, Valid: true} 1330 } 1331 if !member.SchemeUser.Valid { 1332 member.SchemeUser = sql.NullBool{Bool: false, Valid: true} 1333 } 1334 if !member.SchemeGuest.Valid { 1335 member.SchemeGuest = sql.NullBool{Bool: false, Valid: true} 1336 } 1337 for _, role := range roles { 1338 if role == model.TEAM_ADMIN_ROLE_ID { 1339 member.SchemeAdmin = sql.NullBool{Bool: true, Valid: true} 1340 } else if role == model.TEAM_USER_ROLE_ID { 1341 member.SchemeUser = sql.NullBool{Bool: true, Valid: true} 1342 } else if role == model.TEAM_GUEST_ROLE_ID { 1343 member.SchemeGuest = sql.NullBool{Bool: true, Valid: true} 1344 } else { 1345 newRoles = append(newRoles, role) 1346 } 1347 } 1348 member.Roles = strings.Join(newRoles, " ") 1349 1350 if _, err := transaction.Update(&member); err != nil { 1351 return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.update.app_error", nil, err.Error(), http.StatusInternalServerError) 1352 } 1353 1354 } 1355 1356 if err := transaction.Commit(); err != nil { 1357 return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 1358 } 1359 1360 data := make(map[string]string) 1361 data["TeamId"] = teamMembers[len(teamMembers)-1].TeamId 1362 data["UserId"] = teamMembers[len(teamMembers)-1].UserId 1363 1364 return data, nil 1365 } 1366 1367 func (s SqlTeamStore) ResetAllTeamSchemes() *model.AppError { 1368 if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId=''"); err != nil { 1369 return model.NewAppError("SqlTeamStore.ResetAllTeamSchemes", "store.sql_team.reset_all_team_schemes.app_error", nil, err.Error(), http.StatusInternalServerError) 1370 } 1371 return nil 1372 } 1373 1374 func (s SqlTeamStore) ClearCaches() {} 1375 1376 func (s SqlTeamStore) InvalidateAllTeamIdsForUser(userId string) {} 1377 1378 func (s SqlTeamStore) ClearAllCustomRoleAssignments() *model.AppError { 1379 1380 builtInRoles := model.MakeDefaultRoles() 1381 lastUserId := strings.Repeat("0", 26) 1382 lastTeamId := strings.Repeat("0", 26) 1383 1384 for { 1385 var transaction *gorp.Transaction 1386 var err error 1387 1388 if transaction, err = s.GetMaster().Begin(); err != nil { 1389 return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 1390 } 1391 defer finalizeTransaction(transaction) 1392 1393 var teamMembers []*teamMember 1394 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 { 1395 return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.select.app_error", nil, err.Error(), http.StatusInternalServerError) 1396 } 1397 1398 if len(teamMembers) == 0 { 1399 break 1400 } 1401 1402 for _, member := range teamMembers { 1403 lastUserId = member.UserId 1404 lastTeamId = member.TeamId 1405 1406 var newRoles []string 1407 1408 for _, role := range strings.Fields(member.Roles) { 1409 for name := range builtInRoles { 1410 if name == role { 1411 newRoles = append(newRoles, role) 1412 break 1413 } 1414 } 1415 } 1416 1417 newRolesString := strings.Join(newRoles, " ") 1418 if newRolesString != member.Roles { 1419 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 { 1420 return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.update.app_error", nil, err.Error(), http.StatusInternalServerError) 1421 } 1422 } 1423 } 1424 1425 if err := transaction.Commit(); err != nil { 1426 return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 1427 } 1428 } 1429 return nil 1430 } 1431 1432 // AnalyticsGetTeamCountForScheme returns the number of active teams that match the schemeId passed as parameter. 1433 func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) (int64, *model.AppError) { 1434 query, args, err := s.getQueryBuilder(). 1435 Select("count(*)"). 1436 From("Teams"). 1437 Where(sq.Eq{"SchemeId": schemeId, "DeleteAt": 0}).ToSql() 1438 1439 if err != nil { 1440 return 0, model.NewAppError("SqlTeamStore.AnalyticsGetTeamCountForScheme", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1441 } 1442 count, err := s.GetReplica().SelectInt(query, args...) 1443 if err != nil { 1444 return 0, model.NewAppError("SqlTeamStore.AnalyticsGetTeamCountForScheme", "store.sql_team.analytics_get_team_count_for_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError) 1445 } 1446 1447 return count, nil 1448 } 1449 1450 // GetAllForExportAfter returns teams for export, up to a total limit passed as paramater where Teams.Id is greater than the afterId passed as parameter. 1451 func (s SqlTeamStore) GetAllForExportAfter(limit int, afterId string) ([]*model.TeamForExport, *model.AppError) { 1452 var data []*model.TeamForExport 1453 query, args, err := s.getQueryBuilder(). 1454 Select("Teams.*", "Schemes.Name as SchemeName"). 1455 From("Teams"). 1456 LeftJoin("Schemes ON Teams.SchemeId = Schemes.Id"). 1457 Where(sq.Gt{"Teams.Id": afterId}). 1458 OrderBy("Id"). 1459 Limit(uint64(limit)).ToSql() 1460 1461 if err != nil { 1462 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1463 } 1464 if _, err = s.GetReplica().Select(&data, query, args...); err != nil { 1465 return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 1466 } 1467 1468 return data, nil 1469 } 1470 1471 // GetUserTeamIds get the team ids to which the user belongs to. allowFromCache parameter does not have any effect in this Store 1472 func (s SqlTeamStore) GetUserTeamIds(userID string, allowFromCache bool) ([]string, *model.AppError) { 1473 var teamIds []string 1474 query, args, err := s.getQueryBuilder(). 1475 Select("TeamId"). 1476 From("TeamMembers"). 1477 Join("Teams ON TeamMembers.TeamId = Teams.Id"). 1478 Where(sq.Eq{"TeamMembers.UserId": userID, "TeamMembers.DeleteAt": 0, "Teams.DeleteAt": 0}).ToSql() 1479 1480 if err != nil { 1481 return []string{}, model.NewAppError("SqlTeamStore.GetUserTeamIds", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1482 } 1483 _, err = s.GetReplica().Select(&teamIds, query, args...) 1484 if err != nil { 1485 return []string{}, model.NewAppError("SqlTeamStore.GetUserTeamIds", "store.sql_team.get_user_team_ids.app_error", nil, "userID="+userID+" "+err.Error(), http.StatusInternalServerError) 1486 } 1487 1488 return teamIds, nil 1489 } 1490 1491 func (s SqlTeamStore) GetTeamMembersForExport(userId string) ([]*model.TeamMemberForExport, *model.AppError) { 1492 var members []*model.TeamMemberForExport 1493 query, args, err := s.getQueryBuilder(). 1494 Select("TeamMembers.TeamId", "TeamMembers.UserId", "TeamMembers.Roles", "TeamMembers.DeleteAt", 1495 "(TeamMembers.SchemeGuest IS NOT NULL AND TeamMembers.SchemeGuest) as SchemeGuest", 1496 "TeamMembers.SchemeUser", "TeamMembers.SchemeAdmin", "Teams.Name as TeamName"). 1497 From("TeamMembers"). 1498 Join("Teams ON TeamMembers.TeamId = Teams.Id"). 1499 Where(sq.Eq{"TeamMembers.UserId": userId, "Teams.DeleteAt": 0}).ToSql() 1500 1501 if err != nil { 1502 return nil, model.NewAppError("SqlTeamStore.GetTeamMembersForExport", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1503 } 1504 _, err = s.GetReplica().Select(&members, query, args...) 1505 if err != nil { 1506 return nil, model.NewAppError("SqlTeamStore.GetTeamMembersForExport", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 1507 } 1508 return members, nil 1509 } 1510 1511 func (s SqlTeamStore) UserBelongsToTeams(userId string, teamIds []string) (bool, *model.AppError) { 1512 idQuery := sq.Eq{ 1513 "UserId": userId, 1514 "TeamId": teamIds, 1515 "DeleteAt": 0, 1516 } 1517 1518 query, params, err := s.getQueryBuilder().Select("Count(*)").From("TeamMembers").Where(idQuery).ToSql() 1519 if err != nil { 1520 return false, model.NewAppError("SqlTeamStore.UserBelongsToTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1521 } 1522 1523 c, err := s.GetReplica().SelectInt(query, params...) 1524 if err != nil { 1525 return false, model.NewAppError("SqlTeamStore.UserBelongsToTeams", "store.sql_team.user_belongs_to_teams.app_error", nil, err.Error(), http.StatusInternalServerError) 1526 } 1527 1528 return c > 0, nil 1529 } 1530 1531 func (s SqlTeamStore) UpdateMembersRole(teamID string, userIDs []string) *model.AppError { 1532 sql, args, err := s.getQueryBuilder(). 1533 Update("TeamMembers"). 1534 Set("SchemeAdmin", sq.Case().When(sq.Eq{"UserId": userIDs}, "true").Else("false")). 1535 Where(sq.Eq{"TeamId": teamID, "DeleteAt": 0}). 1536 Where(sq.Or{sq.Eq{"SchemeGuest": false}, sq.Expr("SchemeGuest IS NULL")}).ToSql() 1537 if err != nil { 1538 return model.NewAppError("SqlTeamStore.UpdateMembersRole", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1539 } 1540 if _, err = s.GetMaster().Exec(sql, args...); err != nil { 1541 return model.NewAppError("SqlTeamStore.UpdateMembersRole", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 1542 } 1543 1544 return nil 1545 } 1546 1547 func applyTeamMemberViewRestrictionsFilter(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder { 1548 if restrictions == nil { 1549 return query 1550 } 1551 1552 // If you have no access to teams or channels, return and empty result. 1553 if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 { 1554 return query.Where("1 = 0") 1555 } 1556 1557 teams := make([]interface{}, len(restrictions.Teams)) 1558 for i, v := range restrictions.Teams { 1559 teams[i] = v 1560 } 1561 channels := make([]interface{}, len(restrictions.Channels)) 1562 for i, v := range restrictions.Channels { 1563 channels[i] = v 1564 } 1565 1566 resultQuery := query.Join("Users ru ON (TeamMembers.UserId = ru.Id)") 1567 if restrictions.Teams != nil && len(restrictions.Teams) > 0 { 1568 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...) 1569 } 1570 if restrictions.Channels != nil && len(restrictions.Channels) > 0 { 1571 resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = ru.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...) 1572 } 1573 1574 return resultQuery.Distinct() 1575 } 1576 1577 func applyTeamMemberViewRestrictionsFilterForStats(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder { 1578 if restrictions == nil { 1579 return query 1580 } 1581 1582 // If you have no access to teams or channels, return and empty result. 1583 if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 { 1584 return query.Where("1 = 0") 1585 } 1586 1587 teams := make([]interface{}, len(restrictions.Teams)) 1588 for i, v := range restrictions.Teams { 1589 teams[i] = v 1590 } 1591 channels := make([]interface{}, len(restrictions.Channels)) 1592 for i, v := range restrictions.Channels { 1593 channels[i] = v 1594 } 1595 1596 resultQuery := query 1597 if restrictions.Teams != nil && len(restrictions.Teams) > 0 { 1598 resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = Users.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...) 1599 } 1600 if restrictions.Channels != nil && len(restrictions.Channels) > 0 { 1601 resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = Users.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...) 1602 } 1603 1604 return resultQuery 1605 } 1606 1607 func (s SqlTeamStore) GroupSyncedTeamCount() (int64, *model.AppError) { 1608 query := s.getQueryBuilder().Select("COUNT(*)").From("Teams").Where(sq.Eq{"GroupConstrained": true, "DeleteAt": 0}) 1609 1610 sql, args, err := query.ToSql() 1611 if err != nil { 1612 return 0, model.NewAppError("SqlTeamStore.GroupSyncedTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 1613 } 1614 1615 count, err := s.GetReplica().SelectInt(sql, args...) 1616 if err != nil { 1617 return 0, model.NewAppError("SqlTeamStore.GroupSyncedTeamCount", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 1618 } 1619 1620 return count, nil 1621 }