github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/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 "net/http" 9 "strconv" 10 "strings" 11 12 "github.com/mattermost/gorp" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/store" 15 ) 16 17 const ( 18 TEAM_MEMBER_EXISTS_ERROR = "store.sql_team.save_member.exists.app_error" 19 ) 20 21 type SqlTeamStore struct { 22 SqlStore 23 } 24 25 type teamMember struct { 26 TeamId string 27 UserId string 28 Roles string 29 DeleteAt int64 30 SchemeUser sql.NullBool 31 SchemeAdmin sql.NullBool 32 } 33 34 func NewTeamMemberFromModel(tm *model.TeamMember) *teamMember { 35 return &teamMember{ 36 TeamId: tm.TeamId, 37 UserId: tm.UserId, 38 Roles: tm.ExplicitRoles, 39 DeleteAt: tm.DeleteAt, 40 SchemeUser: sql.NullBool{Valid: true, Bool: tm.SchemeUser}, 41 SchemeAdmin: sql.NullBool{Valid: true, Bool: tm.SchemeAdmin}, 42 } 43 } 44 45 type teamMemberWithSchemeRoles struct { 46 TeamId string 47 UserId string 48 Roles string 49 DeleteAt int64 50 SchemeUser sql.NullBool 51 SchemeAdmin sql.NullBool 52 TeamSchemeDefaultUserRole sql.NullString 53 TeamSchemeDefaultAdminRole sql.NullString 54 } 55 56 type teamMemberWithSchemeRolesList []teamMemberWithSchemeRoles 57 58 func (db teamMemberWithSchemeRoles) ToModel() *model.TeamMember { 59 var roles []string 60 var explicitRoles []string 61 62 // Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude 63 // them from ExplicitRoles field. 64 schemeUser := db.SchemeUser.Valid && db.SchemeUser.Bool 65 schemeAdmin := db.SchemeAdmin.Valid && db.SchemeAdmin.Bool 66 for _, role := range strings.Fields(db.Roles) { 67 isImplicit := false 68 if role == model.TEAM_USER_ROLE_ID { 69 // We have an implicit role via the system scheme. Override the "schemeUser" field to true. 70 schemeUser = true 71 isImplicit = true 72 } else if role == model.TEAM_ADMIN_ROLE_ID { 73 // We have an implicit role via the system scheme. 74 schemeAdmin = true 75 isImplicit = true 76 } 77 78 if !isImplicit { 79 explicitRoles = append(explicitRoles, role) 80 } 81 roles = append(roles, role) 82 } 83 84 // Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add 85 // them to the Roles field for backwards compatibility reasons. 86 var schemeImpliedRoles []string 87 if db.SchemeUser.Valid && db.SchemeUser.Bool { 88 if db.TeamSchemeDefaultUserRole.Valid && db.TeamSchemeDefaultUserRole.String != "" { 89 schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultUserRole.String) 90 } else { 91 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_USER_ROLE_ID) 92 } 93 } 94 if db.SchemeAdmin.Valid && db.SchemeAdmin.Bool { 95 if db.TeamSchemeDefaultAdminRole.Valid && db.TeamSchemeDefaultAdminRole.String != "" { 96 schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultAdminRole.String) 97 } else { 98 schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_ADMIN_ROLE_ID) 99 } 100 } 101 for _, impliedRole := range schemeImpliedRoles { 102 alreadyThere := false 103 for _, role := range roles { 104 if role == impliedRole { 105 alreadyThere = true 106 } 107 } 108 if !alreadyThere { 109 roles = append(roles, impliedRole) 110 } 111 } 112 113 tm := &model.TeamMember{ 114 TeamId: db.TeamId, 115 UserId: db.UserId, 116 Roles: strings.Join(roles, " "), 117 DeleteAt: db.DeleteAt, 118 SchemeUser: schemeUser, 119 SchemeAdmin: schemeAdmin, 120 ExplicitRoles: strings.Join(explicitRoles, " "), 121 } 122 return tm 123 } 124 125 func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember { 126 tms := make([]*model.TeamMember, 0) 127 128 for _, tm := range db { 129 tms = append(tms, tm.ToModel()) 130 } 131 132 return tms 133 } 134 135 func NewSqlTeamStore(sqlStore SqlStore) store.TeamStore { 136 s := &SqlTeamStore{sqlStore} 137 138 for _, db := range sqlStore.GetAllConns() { 139 table := db.AddTableWithName(model.Team{}, "Teams").SetKeys(false, "Id") 140 table.ColMap("Id").SetMaxSize(26) 141 table.ColMap("DisplayName").SetMaxSize(64) 142 table.ColMap("Name").SetMaxSize(64).SetUnique(true) 143 table.ColMap("Description").SetMaxSize(255) 144 table.ColMap("Email").SetMaxSize(128) 145 table.ColMap("CompanyName").SetMaxSize(64) 146 table.ColMap("AllowedDomains").SetMaxSize(500) 147 table.ColMap("InviteId").SetMaxSize(32) 148 149 tablem := db.AddTableWithName(teamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId") 150 tablem.ColMap("TeamId").SetMaxSize(26) 151 tablem.ColMap("UserId").SetMaxSize(26) 152 tablem.ColMap("Roles").SetMaxSize(64) 153 } 154 155 return s 156 } 157 158 func (s SqlTeamStore) CreateIndexesIfNotExists() { 159 s.CreateIndexIfNotExists("idx_teams_name", "Teams", "Name") 160 s.RemoveIndexIfExists("idx_teams_description", "Teams") 161 s.CreateIndexIfNotExists("idx_teams_invite_id", "Teams", "InviteId") 162 s.CreateIndexIfNotExists("idx_teams_update_at", "Teams", "UpdateAt") 163 s.CreateIndexIfNotExists("idx_teams_create_at", "Teams", "CreateAt") 164 s.CreateIndexIfNotExists("idx_teams_delete_at", "Teams", "DeleteAt") 165 166 s.CreateIndexIfNotExists("idx_teammembers_team_id", "TeamMembers", "TeamId") 167 s.CreateIndexIfNotExists("idx_teammembers_user_id", "TeamMembers", "UserId") 168 s.CreateIndexIfNotExists("idx_teammembers_delete_at", "TeamMembers", "DeleteAt") 169 } 170 171 func (s SqlTeamStore) Save(team *model.Team) store.StoreChannel { 172 return store.Do(func(result *store.StoreResult) { 173 if len(team.Id) > 0 { 174 result.Err = model.NewAppError("SqlTeamStore.Save", 175 "store.sql_team.save.existing.app_error", nil, "id="+team.Id, http.StatusBadRequest) 176 return 177 } 178 179 team.PreSave() 180 181 if result.Err = team.IsValid(); result.Err != nil { 182 return 183 } 184 185 if err := s.GetMaster().Insert(team); err != nil { 186 if IsUniqueConstraintError(err, []string{"Name", "teams_name_key"}) { 187 result.Err = model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.domain_exists.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusBadRequest) 188 } else { 189 result.Err = model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 190 } 191 } else { 192 result.Data = team 193 } 194 }) 195 } 196 197 func (s SqlTeamStore) Update(team *model.Team) store.StoreChannel { 198 return store.Do(func(result *store.StoreResult) { 199 team.PreUpdate() 200 201 if result.Err = team.IsValid(); result.Err != nil { 202 return 203 } 204 205 if oldResult, err := s.GetMaster().Get(model.Team{}, team.Id); err != nil { 206 result.Err = model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.finding.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 207 } else if oldResult == nil { 208 result.Err = model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.find.app_error", nil, "id="+team.Id, http.StatusBadRequest) 209 } else { 210 oldTeam := oldResult.(*model.Team) 211 team.CreateAt = oldTeam.CreateAt 212 team.UpdateAt = model.GetMillis() 213 team.Name = oldTeam.Name 214 215 if count, err := s.GetMaster().Update(team); err != nil { 216 result.Err = model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.updating.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError) 217 } else if count != 1 { 218 result.Err = model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.app_error", nil, "id="+team.Id, http.StatusInternalServerError) 219 } else { 220 result.Data = team 221 } 222 } 223 }) 224 } 225 226 func (s SqlTeamStore) UpdateDisplayName(name string, teamId string) store.StoreChannel { 227 return store.Do(func(result *store.StoreResult) { 228 if _, err := s.GetMaster().Exec("UPDATE Teams SET DisplayName = :Name WHERE Id = :Id", map[string]interface{}{"Name": name, "Id": teamId}); err != nil { 229 result.Err = model.NewAppError("SqlTeamStore.UpdateName", "store.sql_team.update_display_name.app_error", nil, "team_id="+teamId, http.StatusInternalServerError) 230 } else { 231 result.Data = teamId 232 } 233 }) 234 } 235 236 func (s SqlTeamStore) Get(id string) store.StoreChannel { 237 return store.Do(func(result *store.StoreResult) { 238 if obj, err := s.GetReplica().Get(model.Team{}, id); err != nil { 239 result.Err = model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.finding.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 240 } else if obj == nil { 241 result.Err = model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.find.app_error", nil, "id="+id, http.StatusNotFound) 242 } else { 243 team := obj.(*model.Team) 244 if len(team.InviteId) == 0 { 245 team.InviteId = team.Id 246 } 247 248 result.Data = team 249 } 250 }) 251 } 252 253 func (s SqlTeamStore) GetByInviteId(inviteId string) store.StoreChannel { 254 return store.Do(func(result *store.StoreResult) { 255 team := model.Team{} 256 257 if err := s.GetReplica().SelectOne(&team, "SELECT * FROM Teams WHERE Id = :InviteId OR InviteId = :InviteId", map[string]interface{}{"InviteId": inviteId}); err != nil { 258 result.Err = model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.finding.app_error", nil, "inviteId="+inviteId+", "+err.Error(), http.StatusNotFound) 259 } 260 261 if len(team.InviteId) == 0 { 262 team.InviteId = team.Id 263 } 264 265 if len(inviteId) == 0 || team.InviteId != inviteId { 266 result.Err = model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.find.app_error", nil, "inviteId="+inviteId, http.StatusNotFound) 267 } 268 269 result.Data = &team 270 }) 271 } 272 273 func (s SqlTeamStore) GetByName(name string) store.StoreChannel { 274 return store.Do(func(result *store.StoreResult) { 275 team := model.Team{} 276 277 if err := s.GetReplica().SelectOne(&team, "SELECT * FROM Teams WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil { 278 result.Err = model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) 279 } 280 281 if len(team.InviteId) == 0 { 282 team.InviteId = team.Id 283 } 284 285 result.Data = &team 286 }) 287 } 288 289 func (s SqlTeamStore) SearchByName(name string) store.StoreChannel { 290 return store.Do(func(result *store.StoreResult) { 291 var teams []*model.Team 292 293 if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Name LIKE :Name", map[string]interface{}{"Name": name + "%"}); err != nil { 294 result.Err = model.NewAppError("SqlTeamStore.SearchByName", "store.sql_team.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) 295 } 296 297 result.Data = teams 298 }) 299 } 300 301 func (s SqlTeamStore) SearchAll(term string) store.StoreChannel { 302 return store.Do(func(result *store.StoreResult) { 303 var teams []*model.Team 304 305 if _, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE Name LIKE :Term OR DisplayName LIKE :Term", map[string]interface{}{"Term": term + "%"}); err != nil { 306 result.Err = model.NewAppError("SqlTeamStore.SearchAll", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 307 } 308 309 result.Data = teams 310 }) 311 } 312 313 func (s SqlTeamStore) SearchOpen(term string) store.StoreChannel { 314 return store.Do(func(result *store.StoreResult) { 315 var teams []*model.Team 316 317 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 { 318 result.Err = model.NewAppError("SqlTeamStore.SearchOpen", "store.sql_team.search_open_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError) 319 } 320 321 result.Data = teams 322 }) 323 } 324 325 func (s SqlTeamStore) GetAll() store.StoreChannel { 326 return store.Do(func(result *store.StoreResult) { 327 var data []*model.Team 328 if _, err := s.GetReplica().Select(&data, "SELECT * FROM Teams"); err != nil { 329 result.Err = model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 330 } 331 332 for _, team := range data { 333 if len(team.InviteId) == 0 { 334 team.InviteId = team.Id 335 } 336 } 337 338 result.Data = data 339 }) 340 } 341 342 func (s SqlTeamStore) GetAllPage(offset int, limit int) store.StoreChannel { 343 return store.Do(func(result *store.StoreResult) { 344 var data []*model.Team 345 if _, err := s.GetReplica().Select(&data, "SELECT * FROM Teams LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 346 result.Err = model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 347 } 348 349 for _, team := range data { 350 if len(team.InviteId) == 0 { 351 team.InviteId = team.Id 352 } 353 } 354 355 result.Data = data 356 }) 357 } 358 359 func (s SqlTeamStore) GetTeamsByUserId(userId string) store.StoreChannel { 360 return store.Do(func(result *store.StoreResult) { 361 var data []*model.Team 362 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 { 363 result.Err = model.NewAppError("SqlTeamStore.GetTeamsByUserId", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 364 } 365 366 for _, team := range data { 367 if len(team.InviteId) == 0 { 368 team.InviteId = team.Id 369 } 370 } 371 372 result.Data = data 373 }) 374 } 375 376 func (s SqlTeamStore) GetAllTeamListing() store.StoreChannel { 377 return store.Do(func(result *store.StoreResult) { 378 query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1" 379 380 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 381 query = "SELECT * FROM Teams WHERE AllowOpenInvite = true" 382 } 383 384 var data []*model.Team 385 if _, err := s.GetReplica().Select(&data, query); err != nil { 386 result.Err = model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 387 } 388 389 for _, team := range data { 390 if len(team.InviteId) == 0 { 391 team.InviteId = team.Id 392 } 393 } 394 395 result.Data = data 396 }) 397 } 398 399 func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) store.StoreChannel { 400 return store.Do(func(result *store.StoreResult) { 401 query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1 LIMIT :Limit OFFSET :Offset" 402 403 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 404 query = "SELECT * FROM Teams WHERE AllowOpenInvite = true LIMIT :Limit OFFSET :Offset" 405 } 406 407 var data []*model.Team 408 if _, err := s.GetReplica().Select(&data, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 409 result.Err = model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError) 410 } 411 412 for _, team := range data { 413 if len(team.InviteId) == 0 { 414 team.InviteId = team.Id 415 } 416 } 417 418 result.Data = data 419 }) 420 } 421 422 func (s SqlTeamStore) PermanentDelete(teamId string) store.StoreChannel { 423 return store.Do(func(result *store.StoreResult) { 424 if _, err := s.GetMaster().Exec("DELETE FROM Teams WHERE Id = :TeamId", map[string]interface{}{"TeamId": teamId}); err != nil { 425 result.Err = model.NewAppError("SqlTeamStore.Delete", "store.sql_team.permanent_delete.app_error", nil, "teamId="+teamId+", "+err.Error(), http.StatusInternalServerError) 426 } 427 }) 428 } 429 430 func (s SqlTeamStore) AnalyticsTeamCount() store.StoreChannel { 431 return store.Do(func(result *store.StoreResult) { 432 if c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE DeleteAt = 0", map[string]interface{}{}); err != nil { 433 result.Err = model.NewAppError("SqlTeamStore.AnalyticsTeamCount", "store.sql_team.analytics_team_count.app_error", nil, err.Error(), http.StatusInternalServerError) 434 } else { 435 result.Data = c 436 } 437 }) 438 } 439 440 var TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY = ` 441 SELECT 442 TeamMembers.*, 443 TeamScheme.DefaultTeamUserRole TeamSchemeDefaultUserRole, 444 TeamScheme.DefaultTeamAdminRole TeamSchemeDefaultAdminRole 445 FROM 446 TeamMembers 447 LEFT JOIN 448 Teams ON TeamMembers.TeamId = Teams.Id 449 LEFT JOIN 450 Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id 451 ` 452 453 func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) store.StoreChannel { 454 return store.Do(func(result *store.StoreResult) { 455 if result.Err = member.IsValid(); result.Err != nil { 456 return 457 } 458 459 dbMember := NewTeamMemberFromModel(member) 460 461 if maxUsersPerTeam >= 0 { 462 if count, err := s.GetMaster().SelectInt( 463 `SELECT 464 COUNT(0) 465 FROM 466 TeamMembers 467 INNER JOIN 468 Users 469 ON 470 TeamMembers.UserId = Users.Id 471 WHERE 472 TeamId = :TeamId 473 AND TeamMembers.DeleteAt = 0 474 AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": member.TeamId}); err != nil { 475 result.Err = model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, "teamId="+member.TeamId+", "+err.Error(), http.StatusInternalServerError) 476 return 477 } else if count >= int64(maxUsersPerTeam) { 478 result.Err = model.NewAppError("SqlUserStore.Save", "store.sql_user.save.max_accounts.app_error", nil, "teamId="+member.TeamId, http.StatusBadRequest) 479 return 480 } 481 } 482 483 if err := s.GetMaster().Insert(dbMember); err != nil { 484 if IsUniqueConstraintError(err, []string{"TeamId", "teammembers_pkey", "PRIMARY"}) { 485 result.Err = model.NewAppError("SqlTeamStore.SaveMember", TEAM_MEMBER_EXISTS_ERROR, nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest) 486 } else { 487 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) 488 } 489 } else { 490 var retrievedMember teamMemberWithSchemeRoles 491 if err := s.GetMaster().SelectOne(&retrievedMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": dbMember.TeamId, "UserId": dbMember.UserId}); err != nil { 492 if err == sql.ErrNoRows { 493 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) 494 } else { 495 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) 496 } 497 } else { 498 result.Data = retrievedMember.ToModel() 499 } 500 } 501 }) 502 } 503 504 func (s SqlTeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel { 505 return store.Do(func(result *store.StoreResult) { 506 member.PreUpdate() 507 508 if result.Err = member.IsValid(); result.Err != nil { 509 return 510 } 511 512 if _, err := s.GetMaster().Update(NewTeamMemberFromModel(member)); err != nil { 513 result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError) 514 } else { 515 var retrievedMember teamMemberWithSchemeRoles 516 if err := s.GetMaster().SelectOne(&retrievedMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": member.TeamId, "UserId": member.UserId}); err != nil { 517 if err == sql.ErrNoRows { 518 result.Err = 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) 519 } else { 520 result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.app_error", nil, "team_id="+member.TeamId+"user_id="+member.UserId+","+err.Error(), http.StatusInternalServerError) 521 } 522 } else { 523 result.Data = retrievedMember.ToModel() 524 } 525 } 526 }) 527 } 528 529 func (s SqlTeamStore) GetMember(teamId string, userId string) store.StoreChannel { 530 return store.Do(func(result *store.StoreResult) { 531 var dbMember teamMemberWithSchemeRoles 532 err := s.GetReplica().SelectOne(&dbMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId}) 533 if err != nil { 534 if err == sql.ErrNoRows { 535 result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound) 536 } else { 537 result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusInternalServerError) 538 } 539 } else { 540 result.Data = dbMember.ToModel() 541 } 542 }) 543 } 544 545 func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int) store.StoreChannel { 546 return store.Do(func(result *store.StoreResult) { 547 var dbMembers teamMemberWithSchemeRolesList 548 _, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"TeamId": teamId, "Limit": limit, "Offset": offset}) 549 if err != nil { 550 result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 551 } else { 552 result.Data = dbMembers.ToModel() 553 } 554 }) 555 } 556 557 func (s SqlTeamStore) GetTotalMemberCount(teamId string) store.StoreChannel { 558 return store.Do(func(result *store.StoreResult) { 559 count, err := s.GetReplica().SelectInt(` 560 SELECT 561 count(*) 562 FROM 563 TeamMembers, 564 Users 565 WHERE 566 TeamMembers.UserId = Users.Id 567 AND TeamMembers.TeamId = :TeamId 568 AND TeamMembers.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) 569 if err != nil { 570 result.Err = model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 571 } else { 572 result.Data = count 573 } 574 }) 575 } 576 577 func (s SqlTeamStore) GetActiveMemberCount(teamId string) store.StoreChannel { 578 return store.Do(func(result *store.StoreResult) { 579 count, err := s.GetReplica().SelectInt(` 580 SELECT 581 count(*) 582 FROM 583 TeamMembers, 584 Users 585 WHERE 586 TeamMembers.UserId = Users.Id 587 AND TeamMembers.TeamId = :TeamId 588 AND TeamMembers.DeleteAt = 0 589 AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) 590 if err != nil { 591 result.Err = model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 592 } else { 593 result.Data = count 594 } 595 }) 596 } 597 598 func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string) store.StoreChannel { 599 return store.Do(func(result *store.StoreResult) { 600 var dbMembers teamMemberWithSchemeRolesList 601 props := make(map[string]interface{}) 602 idQuery := "" 603 604 for index, userId := range userIds { 605 if len(idQuery) > 0 { 606 idQuery += ", " 607 } 608 609 props["userId"+strconv.Itoa(index)] = userId 610 idQuery += ":userId" + strconv.Itoa(index) 611 } 612 613 props["TeamId"] = teamId 614 615 if _, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId IN ("+idQuery+") AND TeamMembers.DeleteAt = 0", props); err != nil { 616 result.Err = model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 617 } else { 618 result.Data = dbMembers.ToModel() 619 } 620 }) 621 } 622 623 func (s SqlTeamStore) GetTeamsForUser(userId string) store.StoreChannel { 624 return store.Do(func(result *store.StoreResult) { 625 var dbMembers teamMemberWithSchemeRolesList 626 _, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.UserId = :UserId", map[string]interface{}{"UserId": userId}) 627 if err != nil { 628 result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 629 } else { 630 result.Data = dbMembers.ToModel() 631 } 632 }) 633 } 634 635 func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) store.StoreChannel { 636 return store.Do(func(result *store.StoreResult) { 637 var data []*model.ChannelUnread 638 _, err := s.GetReplica().Select(&data, 639 `SELECT 640 Channels.TeamId TeamId, Channels.Id ChannelId, (Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount, ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps 641 FROM 642 Channels, ChannelMembers 643 WHERE 644 Id = ChannelId 645 AND UserId = :UserId 646 AND DeleteAt = 0 647 AND TeamId != :TeamId`, 648 map[string]interface{}{"UserId": userId, "TeamId": excludeTeamId}) 649 650 if err != nil { 651 result.Err = model.NewAppError("SqlTeamStore.GetChannelUnreadsForAllTeams", "store.sql_team.get_unread.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError) 652 } else { 653 result.Data = data 654 } 655 }) 656 } 657 658 func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) store.StoreChannel { 659 return store.Do(func(result *store.StoreResult) { 660 var data []*model.ChannelUnread 661 _, err := s.GetReplica().Select(&data, 662 `SELECT 663 Channels.TeamId TeamId, Channels.Id ChannelId, (Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount, ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps 664 FROM 665 Channels, ChannelMembers 666 WHERE 667 Id = ChannelId 668 AND UserId = :UserId 669 AND TeamId = :TeamId 670 AND DeleteAt = 0`, 671 map[string]interface{}{"TeamId": teamId, "UserId": userId}) 672 673 if err != nil { 674 result.Err = model.NewAppError("SqlTeamStore.GetChannelUnreadsForTeam", "store.sql_team.get_unread.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError) 675 } else { 676 result.Data = data 677 } 678 }) 679 } 680 681 func (s SqlTeamStore) RemoveMember(teamId string, userId string) store.StoreChannel { 682 return store.Do(func(result *store.StoreResult) { 683 _, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId AND UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId}) 684 if err != nil { 685 result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", user_id="+userId+", "+err.Error(), http.StatusInternalServerError) 686 } 687 }) 688 } 689 690 func (s SqlTeamStore) RemoveAllMembersByTeam(teamId string) store.StoreChannel { 691 return store.Do(func(result *store.StoreResult) { 692 _, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId}) 693 if err != nil { 694 result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError) 695 } 696 }) 697 } 698 699 func (s SqlTeamStore) RemoveAllMembersByUser(userId string) store.StoreChannel { 700 return store.Do(func(result *store.StoreResult) { 701 _, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}) 702 if err != nil { 703 result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError) 704 } 705 }) 706 } 707 708 func (us SqlTeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) store.StoreChannel { 709 return store.Do(func(result *store.StoreResult) { 710 if _, err := us.GetMaster().Exec("UPDATE Teams SET LastTeamIconUpdate = :Time, UpdateAt = :Time WHERE Id = :teamId", map[string]interface{}{"Time": curTime, "teamId": teamId}); err != nil { 711 result.Err = model.NewAppError("SqlTeamStore.UpdateLastTeamIconUpdate", "store.sql_team.update_last_team_icon_update.app_error", nil, "team_id="+teamId, http.StatusInternalServerError) 712 } else { 713 result.Data = teamId 714 } 715 }) 716 } 717 718 func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) store.StoreChannel { 719 return store.Do(func(result *store.StoreResult) { 720 var teams []*model.Team 721 _, 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}) 722 if err != nil { 723 result.Err = model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql_team.get_by_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError) 724 } else { 725 result.Data = teams 726 } 727 }) 728 } 729 730 // This function does the Advanced Permissions Phase 2 migration for TeamMember objects. It performs the migration 731 // in batches as a single transaction per batch to ensure consistency but to also minimise execution time to avoid 732 // causing unnecessary table locks. **THIS FUNCTION SHOULD NOT BE USED FOR ANY OTHER PURPOSE.** Executing this function 733 // *after* the new Schemes functionality has been used on an installation will have unintended consequences. 734 func (s SqlTeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) store.StoreChannel { 735 return store.Do(func(result *store.StoreResult) { 736 var transaction *gorp.Transaction 737 var err error 738 739 if transaction, err = s.GetMaster().Begin(); err != nil { 740 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 741 return 742 } 743 744 var teamMembers []teamMember 745 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 { 746 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.select.app_error", nil, err.Error(), http.StatusInternalServerError) 747 return 748 } 749 750 if len(teamMembers) == 0 { 751 // No more team members in query result means that the migration has finished. 752 return 753 } 754 755 for _, member := range teamMembers { 756 roles := strings.Fields(member.Roles) 757 var newRoles []string 758 member.SchemeAdmin = sql.NullBool{Bool: false, Valid: true} 759 member.SchemeUser = sql.NullBool{Bool: false, Valid: true} 760 for _, role := range roles { 761 if role == model.TEAM_ADMIN_ROLE_ID { 762 member.SchemeAdmin = sql.NullBool{Bool: true, Valid: true} 763 } else if role == model.TEAM_USER_ROLE_ID { 764 member.SchemeUser = sql.NullBool{Bool: true, Valid: true} 765 } else { 766 newRoles = append(newRoles, role) 767 } 768 } 769 member.Roles = strings.Join(newRoles, " ") 770 771 if _, err := transaction.Update(&member); err != nil { 772 if err2 := transaction.Rollback(); err2 != nil { 773 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.rollback_transaction.app_error", nil, err2.Error(), http.StatusInternalServerError) 774 return 775 } 776 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.update.app_error", nil, err.Error(), http.StatusInternalServerError) 777 return 778 } 779 780 } 781 782 if err := transaction.Commit(); err != nil { 783 if err2 := transaction.Rollback(); err2 != nil { 784 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.rollback_transaction.app_error", nil, err2.Error(), http.StatusInternalServerError) 785 return 786 } 787 result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 788 return 789 } 790 791 data := make(map[string]string) 792 data["TeamId"] = teamMembers[len(teamMembers)-1].TeamId 793 data["UserId"] = teamMembers[len(teamMembers)-1].UserId 794 result.Data = data 795 }) 796 } 797 798 func (s SqlTeamStore) ResetAllTeamSchemes() store.StoreChannel { 799 return store.Do(func(result *store.StoreResult) { 800 if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId=''"); err != nil { 801 result.Err = model.NewAppError("SqlTeamStore.ResetAllTeamSchemes", "store.sql_team.reset_all_team_schemes.app_error", nil, err.Error(), http.StatusInternalServerError) 802 } 803 }) 804 }