github.com/mad-app/mattermost-server@v5.11.1+incompatible/store/sqlstore/group_supplier.go (about) 1 // Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "context" 8 "database/sql" 9 "fmt" 10 "net/http" 11 12 "github.com/mattermost/mattermost-server/model" 13 "github.com/mattermost/mattermost-server/store" 14 ) 15 16 type groupTeam struct { 17 model.GroupSyncable 18 TeamId string `db:"TeamId"` 19 } 20 21 type groupChannel struct { 22 model.GroupSyncable 23 ChannelId string `db:"ChannelId"` 24 } 25 26 type groupTeamJoin struct { 27 groupTeam 28 TeamDisplayName string `db:"TeamDisplayName"` 29 TeamType string `db:"TeamType"` 30 } 31 32 type groupChannelJoin struct { 33 groupChannel 34 ChannelDisplayName string `db:"ChannelDisplayName"` 35 TeamDisplayName string `db:"TeamDisplayName"` 36 TeamType string `db:"TeamType"` 37 ChannelType string `db:"ChannelType"` 38 TeamID string `db:"TeamId"` 39 } 40 41 func initSqlSupplierGroups(sqlStore SqlStore) { 42 for _, db := range sqlStore.GetAllConns() { 43 groups := db.AddTableWithName(model.Group{}, "UserGroups").SetKeys(false, "Id") 44 groups.ColMap("Id").SetMaxSize(26) 45 groups.ColMap("Name").SetMaxSize(model.GroupNameMaxLength).SetUnique(true) 46 groups.ColMap("DisplayName").SetMaxSize(model.GroupDisplayNameMaxLength) 47 groups.ColMap("Description").SetMaxSize(model.GroupDescriptionMaxLength) 48 groups.ColMap("Source").SetMaxSize(model.GroupSourceMaxLength) 49 groups.ColMap("RemoteId").SetMaxSize(model.GroupRemoteIDMaxLength) 50 groups.SetUniqueTogether("Source", "RemoteId") 51 52 groupMembers := db.AddTableWithName(model.GroupMember{}, "GroupMembers").SetKeys(false, "GroupId", "UserId") 53 groupMembers.ColMap("GroupId").SetMaxSize(26) 54 groupMembers.ColMap("UserId").SetMaxSize(26) 55 56 groupTeams := db.AddTableWithName(groupTeam{}, "GroupTeams").SetKeys(false, "GroupId", "TeamId") 57 groupTeams.ColMap("GroupId").SetMaxSize(26) 58 groupTeams.ColMap("TeamId").SetMaxSize(26) 59 60 groupChannels := db.AddTableWithName(groupChannel{}, "GroupChannels").SetKeys(false, "GroupId", "ChannelId") 61 groupChannels.ColMap("GroupId").SetMaxSize(26) 62 groupChannels.ColMap("ChannelId").SetMaxSize(26) 63 } 64 } 65 66 func (s *SqlSupplier) CreateIndexesIfNotExistsGroups() { 67 s.CreateIndexIfNotExists("idx_groupmembers_create_at", "GroupMembers", "CreateAt") 68 s.CreateIndexIfNotExists("idx_usergroups_remote_id", "UserGroups", "RemoteId") 69 s.CreateIndexIfNotExists("idx_usergroups_delete_at", "UserGroups", "DeleteAt") 70 } 71 72 func (s *SqlSupplier) GroupCreate(ctx context.Context, group *model.Group, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 73 result := store.NewSupplierResult() 74 75 if len(group.Id) != 0 { 76 result.Err = model.NewAppError("SqlGroupStore.GroupCreate", "model.group.id.app_error", nil, "", http.StatusBadRequest) 77 return result 78 } 79 80 if err := group.IsValidForCreate(); err != nil { 81 result.Err = err 82 return result 83 } 84 85 group.Id = model.NewId() 86 group.CreateAt = model.GetMillis() 87 group.UpdateAt = group.CreateAt 88 89 if err := s.GetMaster().Insert(group); err != nil { 90 if IsUniqueConstraintError(err, []string{"Name", "groups_name_key"}) { 91 result.Err = model.NewAppError("SqlGroupStore.GroupCreate", "store.sql_group.unique_constraint", nil, err.Error(), http.StatusInternalServerError) 92 } else { 93 result.Err = model.NewAppError("SqlGroupStore.GroupCreate", "store.insert_error", nil, err.Error(), http.StatusInternalServerError) 94 } 95 return result 96 } 97 98 result.Data = group 99 return result 100 } 101 102 func (s *SqlSupplier) GroupGet(ctx context.Context, groupId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 103 result := store.NewSupplierResult() 104 105 var group *model.Group 106 if err := s.GetReplica().SelectOne(&group, "SELECT * from UserGroups WHERE Id = :Id", map[string]interface{}{"Id": groupId}); err != nil { 107 if err == sql.ErrNoRows { 108 result.Err = model.NewAppError("SqlGroupStore.GroupGet", "store.sql_group.no_rows", nil, err.Error(), http.StatusNotFound) 109 } else { 110 result.Err = model.NewAppError("SqlGroupStore.GroupGet", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 111 } 112 return result 113 } 114 115 result.Data = group 116 return result 117 } 118 119 func (s *SqlSupplier) GroupGetByRemoteID(ctx context.Context, remoteID string, groupSource model.GroupSource, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 120 result := store.NewSupplierResult() 121 122 var group *model.Group 123 if err := s.GetReplica().SelectOne(&group, "SELECT * from UserGroups WHERE RemoteId = :RemoteId AND Source = :Source", map[string]interface{}{"RemoteId": remoteID, "Source": groupSource}); err != nil { 124 if err == sql.ErrNoRows { 125 result.Err = model.NewAppError("SqlGroupStore.GroupGetByRemoteID", "store.sql_group.no_rows", nil, err.Error(), http.StatusNotFound) 126 } else { 127 result.Err = model.NewAppError("SqlGroupStore.GroupGetByRemoteID", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 128 } 129 return result 130 } 131 132 result.Data = group 133 return result 134 } 135 136 func (s *SqlSupplier) GroupGetAllBySource(ctx context.Context, groupSource model.GroupSource, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 137 result := store.NewSupplierResult() 138 139 var groups []*model.Group 140 141 if _, err := s.GetReplica().Select(&groups, "SELECT * from UserGroups WHERE DeleteAt = 0 AND Source = :Source", map[string]interface{}{"Source": groupSource}); err != nil { 142 result.Err = model.NewAppError("SqlGroupStore.GroupGetAllBySource", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 143 return result 144 } 145 146 result.Data = groups 147 148 return result 149 } 150 151 func (s *SqlSupplier) GroupUpdate(ctx context.Context, group *model.Group, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 152 result := store.NewSupplierResult() 153 154 var retrievedGroup *model.Group 155 if err := s.GetMaster().SelectOne(&retrievedGroup, "SELECT * FROM UserGroups WHERE Id = :Id", map[string]interface{}{"Id": group.Id}); err != nil { 156 if err == sql.ErrNoRows { 157 result.Err = model.NewAppError("SqlGroupStore.GroupUpdate", "store.sql_group.no_rows", nil, "id="+group.Id+","+err.Error(), http.StatusNotFound) 158 } else { 159 result.Err = model.NewAppError("SqlGroupStore.GroupUpdate", "store.select_error", nil, "id="+group.Id+","+err.Error(), http.StatusInternalServerError) 160 } 161 return result 162 } 163 164 // If updating DeleteAt it can only be to 0 165 if group.DeleteAt != retrievedGroup.DeleteAt && group.DeleteAt != 0 { 166 result.Err = model.NewAppError("SqlGroupStore.GroupUpdate", "model.group.delete_at.app_error", nil, "", http.StatusInternalServerError) 167 return result 168 } 169 170 // Reset these properties, don't update them based on input 171 group.CreateAt = retrievedGroup.CreateAt 172 group.UpdateAt = model.GetMillis() 173 174 if err := group.IsValidForUpdate(); err != nil { 175 result.Err = err 176 return result 177 } 178 179 rowsChanged, err := s.GetMaster().Update(group) 180 if err != nil { 181 result.Err = model.NewAppError("SqlGroupStore.GroupUpdate", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 182 return result 183 } 184 if rowsChanged != 1 { 185 result.Err = model.NewAppError("SqlGroupStore.GroupUpdate", "store.sql_group.no_rows_changed", nil, "", http.StatusInternalServerError) 186 return result 187 } 188 189 result.Data = group 190 return result 191 } 192 193 func (s *SqlSupplier) GroupDelete(ctx context.Context, groupID string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 194 result := store.NewSupplierResult() 195 196 var group *model.Group 197 if err := s.GetReplica().SelectOne(&group, "SELECT * from UserGroups WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": groupID}); err != nil { 198 if err == sql.ErrNoRows { 199 result.Err = model.NewAppError("SqlGroupStore.GroupDelete", "store.sql_group.no_rows", nil, "Id="+groupID+", "+err.Error(), http.StatusNotFound) 200 } else { 201 result.Err = model.NewAppError("SqlGroupStore.GroupDelete", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 202 } 203 204 return result 205 } 206 207 time := model.GetMillis() 208 group.DeleteAt = time 209 group.UpdateAt = time 210 211 if _, err := s.GetMaster().Update(group); err != nil { 212 result.Err = model.NewAppError("SqlGroupStore.GroupDelete", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 213 } 214 215 result.Data = group 216 return result 217 } 218 219 func (s *SqlSupplier) GroupGetMemberUsers(stc context.Context, groupID string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 220 result := store.NewSupplierResult() 221 222 var groupMembers []*model.User 223 224 query := ` 225 SELECT 226 Users.* 227 FROM 228 GroupMembers 229 JOIN Users ON Users.Id = GroupMembers.UserId 230 WHERE 231 GroupMembers.DeleteAt = 0 232 AND Users.DeleteAt = 0 233 AND GroupId = :GroupId` 234 235 if _, err := s.GetReplica().Select(&groupMembers, query, map[string]interface{}{"GroupId": groupID}); err != nil { 236 result.Err = model.NewAppError("SqlGroupStore.GroupGetAllBySource", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 237 return result 238 } 239 240 result.Data = groupMembers 241 242 return result 243 } 244 245 func (s *SqlSupplier) GroupGetMemberUsersPage(stc context.Context, groupID string, offset int, limit int, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 246 result := store.NewSupplierResult() 247 248 var groupMembers []*model.User 249 250 query := ` 251 SELECT 252 Users.* 253 FROM 254 GroupMembers 255 JOIN Users ON Users.Id = GroupMembers.UserId 256 WHERE 257 GroupMembers.DeleteAt = 0 258 AND Users.DeleteAt = 0 259 AND GroupId = :GroupId 260 ORDER BY 261 GroupMembers.CreateAt DESC 262 LIMIT 263 :Limit 264 OFFSET 265 :Offset` 266 267 if _, err := s.GetReplica().Select(&groupMembers, query, map[string]interface{}{"GroupId": groupID, "Limit": limit, "Offset": offset}); err != nil { 268 result.Err = model.NewAppError("SqlGroupStore.GroupGetMemberUsersPage", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 269 return result 270 } 271 272 result.Data = groupMembers 273 274 return result 275 } 276 277 func (s *SqlSupplier) GroupGetMemberCount(stc context.Context, groupID string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 278 result := store.NewSupplierResult() 279 280 var count int64 281 var err error 282 283 query := ` 284 SELECT 285 count(*) 286 FROM 287 GroupMembers 288 WHERE 289 GroupMembers.GroupId = :GroupId` 290 291 if count, err = s.GetReplica().SelectInt(query, map[string]interface{}{"GroupId": groupID}); err != nil { 292 result.Err = model.NewAppError("SqlGroupStore.GroupGetMemberUsersPage", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 293 return result 294 } 295 296 result.Data = count 297 298 return result 299 } 300 301 func (s *SqlSupplier) GroupCreateOrRestoreMember(ctx context.Context, groupID string, userID string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 302 result := store.NewSupplierResult() 303 304 member := &model.GroupMember{ 305 GroupId: groupID, 306 UserId: userID, 307 CreateAt: model.GetMillis(), 308 } 309 310 if result.Err = member.IsValid(); result.Err != nil { 311 return result 312 } 313 314 var retrievedGroup *model.Group 315 if err := s.GetMaster().SelectOne(&retrievedGroup, "SELECT * FROM UserGroups WHERE Id = :Id", map[string]interface{}{"Id": groupID}); err != nil { 316 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.insert_error", nil, "group_id="+member.GroupId+"user_id="+member.UserId+","+err.Error(), http.StatusInternalServerError) 317 return result 318 } 319 320 var retrievedMember *model.GroupMember 321 if err := s.GetMaster().SelectOne(&retrievedMember, "SELECT * FROM GroupMembers WHERE GroupId = :GroupId AND UserId = :UserId", map[string]interface{}{"GroupId": member.GroupId, "UserId": member.UserId}); err != nil { 322 if err != sql.ErrNoRows { 323 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.select_error", nil, "group_id="+member.GroupId+"user_id="+member.UserId+","+err.Error(), http.StatusInternalServerError) 324 return result 325 } 326 } 327 328 if retrievedMember != nil && retrievedMember.DeleteAt == 0 { 329 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.sql_group.uniqueness_error", nil, "group_id="+member.GroupId+", user_id="+member.UserId, http.StatusBadRequest) 330 return result 331 } 332 333 if retrievedMember == nil { 334 if err := s.GetMaster().Insert(member); err != nil { 335 if IsUniqueConstraintError(err, []string{"GroupId", "UserId", "groupmembers_pkey", "PRIMARY"}) { 336 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.sql_group.uniqueness_error", nil, "group_id="+member.GroupId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest) 337 return result 338 } 339 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.insert_error", nil, "group_id="+member.GroupId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError) 340 return result 341 } 342 } else { 343 member.DeleteAt = 0 344 var rowsChanged int64 345 var err error 346 if rowsChanged, err = s.GetMaster().Update(member); err != nil { 347 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.update_error", nil, "group_id="+member.GroupId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError) 348 return result 349 } 350 if rowsChanged != 1 { 351 result.Err = model.NewAppError("SqlGroupStore.GroupCreateOrRestoreMember", "store.sql_group.no_rows_changed", nil, "", http.StatusInternalServerError) 352 return result 353 } 354 } 355 356 result.Data = member 357 return result 358 } 359 360 func (s *SqlSupplier) GroupDeleteMember(ctx context.Context, groupID string, userID string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 361 result := store.NewSupplierResult() 362 363 var retrievedMember *model.GroupMember 364 if err := s.GetMaster().SelectOne(&retrievedMember, "SELECT * FROM GroupMembers WHERE GroupId = :GroupId AND UserId = :UserId AND DeleteAt = 0", map[string]interface{}{"GroupId": groupID, "UserId": userID}); err != nil { 365 if err == sql.ErrNoRows { 366 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteMember", "store.sql_group.no_rows", nil, "group_id="+groupID+"user_id="+userID+","+err.Error(), http.StatusNotFound) 367 return result 368 } 369 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteMember", "store.select_error", nil, "group_id="+groupID+"user_id="+userID+","+err.Error(), http.StatusInternalServerError) 370 return result 371 } 372 373 retrievedMember.DeleteAt = model.GetMillis() 374 375 if _, err := s.GetMaster().Update(retrievedMember); err != nil { 376 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteMember", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 377 return result 378 } 379 380 result.Data = retrievedMember 381 return result 382 } 383 384 func (s *SqlSupplier) GroupCreateGroupSyncable(ctx context.Context, groupSyncable *model.GroupSyncable, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 385 result := store.NewSupplierResult() 386 387 if err := groupSyncable.IsValid(); err != nil { 388 result.Err = err 389 return result 390 } 391 392 // Reset values that shouldn't be updatable by parameter 393 groupSyncable.DeleteAt = 0 394 groupSyncable.CreateAt = model.GetMillis() 395 groupSyncable.UpdateAt = groupSyncable.CreateAt 396 397 var err error 398 399 switch groupSyncable.Type { 400 case model.GroupSyncableTypeTeam: 401 teamResult := <-s.Team().Get(groupSyncable.SyncableId) 402 if teamResult.Err != nil { 403 result.Err = teamResult.Err 404 return result 405 } 406 407 err = s.GetMaster().Insert(groupSyncableToGroupTeam(groupSyncable)) 408 case model.GroupSyncableTypeChannel: 409 channelResult := <-s.Channel().Get(groupSyncable.SyncableId, false) 410 if channelResult.Err != nil { 411 result.Err = channelResult.Err 412 return result 413 } 414 415 err = s.GetMaster().Insert(groupSyncableToGroupChannel(groupSyncable)) 416 default: 417 result.Err = model.NewAppError("SqlGroupStore.GroupCreateGroupSyncable", "model.group_syncable.type.app_error", nil, "group_id="+groupSyncable.GroupId+", syncable_id="+groupSyncable.SyncableId+", "+err.Error(), http.StatusInternalServerError) 418 return result 419 } 420 421 if err != nil { 422 result.Err = model.NewAppError("SqlGroupStore.GroupCreateGroupSyncable", "store.insert_error", nil, "group_id="+groupSyncable.GroupId+", syncable_id="+groupSyncable.SyncableId+", "+err.Error(), http.StatusInternalServerError) 423 return result 424 } 425 426 result.Data = groupSyncable 427 return result 428 } 429 430 func (s *SqlSupplier) GroupGetGroupSyncable(ctx context.Context, groupID string, syncableID string, syncableType model.GroupSyncableType, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 431 result := store.NewSupplierResult() 432 433 groupSyncable, err := s.getGroupSyncable(groupID, syncableID, syncableType) 434 if err != nil { 435 if err == sql.ErrNoRows { 436 result.Err = model.NewAppError("SqlGroupStore.GroupGetGroupSyncable", "store.sql_group.no_rows", nil, err.Error(), http.StatusNotFound) 437 } else { 438 result.Err = model.NewAppError("SqlGroupStore.GroupGetGroupSyncable", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 439 } 440 return result 441 } 442 443 result.Data = groupSyncable 444 445 return result 446 } 447 448 func (s *SqlSupplier) getGroupSyncable(groupID string, syncableID string, syncableType model.GroupSyncableType) (*model.GroupSyncable, error) { 449 var err error 450 var result interface{} 451 452 switch syncableType { 453 case model.GroupSyncableTypeTeam: 454 result, err = s.GetMaster().Get(groupTeam{}, groupID, syncableID) 455 case model.GroupSyncableTypeChannel: 456 result, err = s.GetMaster().Get(groupChannel{}, groupID, syncableID) 457 } 458 459 if err != nil { 460 return nil, err 461 } 462 463 if result == nil { 464 return nil, sql.ErrNoRows 465 } 466 467 groupSyncable := model.GroupSyncable{} 468 switch syncableType { 469 case model.GroupSyncableTypeTeam: 470 groupTeam := result.(*groupTeam) 471 groupSyncable.SyncableId = groupTeam.TeamId 472 groupSyncable.GroupId = groupTeam.GroupId 473 groupSyncable.AutoAdd = groupTeam.AutoAdd 474 groupSyncable.CreateAt = groupTeam.CreateAt 475 groupSyncable.DeleteAt = groupTeam.DeleteAt 476 groupSyncable.UpdateAt = groupTeam.UpdateAt 477 groupSyncable.Type = syncableType 478 case model.GroupSyncableTypeChannel: 479 groupChannel := result.(*groupChannel) 480 groupSyncable.SyncableId = groupChannel.ChannelId 481 groupSyncable.GroupId = groupChannel.GroupId 482 groupSyncable.AutoAdd = groupChannel.AutoAdd 483 groupSyncable.CreateAt = groupChannel.CreateAt 484 groupSyncable.DeleteAt = groupChannel.DeleteAt 485 groupSyncable.UpdateAt = groupChannel.UpdateAt 486 groupSyncable.Type = syncableType 487 default: 488 return nil, fmt.Errorf("unable to convert syncableType: %s", syncableType.String()) 489 } 490 491 return &groupSyncable, nil 492 } 493 494 func (s *SqlSupplier) GroupGetAllGroupSyncablesByGroup(ctx context.Context, groupID string, syncableType model.GroupSyncableType, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 495 result := store.NewSupplierResult() 496 497 args := map[string]interface{}{"GroupId": groupID} 498 499 appErrF := func(msg string) *model.AppError { 500 return model.NewAppError("SqlGroupStore.GroupGetAllGroupSyncablesByGroup", "store.select_error", nil, msg, http.StatusInternalServerError) 501 } 502 503 groupSyncables := []*model.GroupSyncable{} 504 505 switch syncableType { 506 case model.GroupSyncableTypeTeam: 507 sqlQuery := ` 508 SELECT 509 GroupTeams.*, 510 Teams.DisplayName AS TeamDisplayName, 511 Teams.Type AS TeamType 512 FROM 513 GroupTeams 514 JOIN Teams ON Teams.Id = GroupTeams.TeamId 515 WHERE 516 GroupId = :GroupId AND GroupTeams.DeleteAt = 0` 517 518 results := []*groupTeamJoin{} 519 _, err := s.GetMaster().Select(&results, sqlQuery, args) 520 if err != nil { 521 result.Err = appErrF(err.Error()) 522 return result 523 } 524 for _, result := range results { 525 groupSyncable := &model.GroupSyncable{ 526 SyncableId: result.TeamId, 527 GroupId: result.GroupId, 528 AutoAdd: result.AutoAdd, 529 CreateAt: result.CreateAt, 530 DeleteAt: result.DeleteAt, 531 UpdateAt: result.UpdateAt, 532 Type: syncableType, 533 TeamDisplayName: result.TeamDisplayName, 534 TeamType: result.TeamType, 535 } 536 groupSyncables = append(groupSyncables, groupSyncable) 537 } 538 case model.GroupSyncableTypeChannel: 539 sqlQuery := ` 540 SELECT 541 GroupChannels.*, 542 Channels.DisplayName AS ChannelDisplayName, 543 Teams.DisplayName AS TeamDisplayName, 544 Channels.Type As ChannelType, 545 Teams.Type As TeamType, 546 Teams.Id AS TeamId 547 FROM 548 GroupChannels 549 JOIN Channels ON Channels.Id = GroupChannels.ChannelId 550 JOIN Teams ON Teams.Id = Channels.TeamId 551 WHERE 552 GroupId = :GroupId AND GroupChannels.DeleteAt = 0` 553 554 results := []*groupChannelJoin{} 555 _, err := s.GetMaster().Select(&results, sqlQuery, args) 556 if err != nil { 557 result.Err = appErrF(err.Error()) 558 return result 559 } 560 for _, result := range results { 561 groupSyncable := &model.GroupSyncable{ 562 SyncableId: result.ChannelId, 563 GroupId: result.GroupId, 564 AutoAdd: result.AutoAdd, 565 CreateAt: result.CreateAt, 566 DeleteAt: result.DeleteAt, 567 UpdateAt: result.UpdateAt, 568 Type: syncableType, 569 ChannelDisplayName: result.ChannelDisplayName, 570 ChannelType: result.ChannelType, 571 TeamDisplayName: result.TeamDisplayName, 572 TeamType: result.TeamType, 573 TeamID: result.TeamID, 574 } 575 groupSyncables = append(groupSyncables, groupSyncable) 576 } 577 } 578 579 result.Data = groupSyncables 580 return result 581 } 582 583 func (s *SqlSupplier) GroupUpdateGroupSyncable(ctx context.Context, groupSyncable *model.GroupSyncable, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 584 result := store.NewSupplierResult() 585 586 retrievedGroupSyncable, err := s.getGroupSyncable(groupSyncable.GroupId, groupSyncable.SyncableId, groupSyncable.Type) 587 if err != nil { 588 if err == sql.ErrNoRows { 589 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "store.sql_group.no_rows", nil, err.Error(), http.StatusInternalServerError) 590 return result 591 } 592 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "store.select_error", nil, "GroupId="+groupSyncable.GroupId+", SyncableId="+groupSyncable.SyncableId+", SyncableType="+groupSyncable.Type.String()+", "+err.Error(), http.StatusInternalServerError) 593 return result 594 } 595 596 if err := groupSyncable.IsValid(); err != nil { 597 result.Err = err 598 return result 599 } 600 601 // If updating DeleteAt it can only be to 0 602 if groupSyncable.DeleteAt != retrievedGroupSyncable.DeleteAt && groupSyncable.DeleteAt != 0 { 603 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "model.group.delete_at.app_error", nil, "", http.StatusInternalServerError) 604 return result 605 } 606 607 // Reset these properties, don't update them based on input 608 groupSyncable.CreateAt = retrievedGroupSyncable.CreateAt 609 groupSyncable.UpdateAt = model.GetMillis() 610 611 switch groupSyncable.Type { 612 case model.GroupSyncableTypeTeam: 613 _, err = s.GetMaster().Update(groupSyncableToGroupTeam(groupSyncable)) 614 case model.GroupSyncableTypeChannel: 615 _, err = s.GetMaster().Update(groupSyncableToGroupChannel(groupSyncable)) 616 default: 617 model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "model.group_syncable.type.app_error", nil, "group_id="+groupSyncable.GroupId+", syncable_id="+groupSyncable.SyncableId+", "+err.Error(), http.StatusInternalServerError) 618 return result 619 } 620 621 if err != nil { 622 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 623 return result 624 } 625 626 result.Data = groupSyncable 627 return result 628 } 629 630 func (s *SqlSupplier) GroupDeleteGroupSyncable(ctx context.Context, groupID string, syncableID string, syncableType model.GroupSyncableType, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 631 result := store.NewSupplierResult() 632 633 groupSyncable, err := s.getGroupSyncable(groupID, syncableID, syncableType) 634 if err != nil { 635 if err == sql.ErrNoRows { 636 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.sql_group.no_rows", nil, "Id="+groupID+", "+err.Error(), http.StatusNotFound) 637 } else { 638 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 639 } 640 return result 641 } 642 643 if groupSyncable.DeleteAt != 0 { 644 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.sql_group.group_syncable_already_deleted", nil, "group_id="+groupID+"syncable_id="+syncableID, http.StatusBadRequest) 645 return result 646 } 647 648 time := model.GetMillis() 649 groupSyncable.DeleteAt = time 650 groupSyncable.UpdateAt = time 651 652 switch groupSyncable.Type { 653 case model.GroupSyncableTypeTeam: 654 _, err = s.GetMaster().Update(groupSyncableToGroupTeam(groupSyncable)) 655 case model.GroupSyncableTypeChannel: 656 _, err = s.GetMaster().Update(groupSyncableToGroupChannel(groupSyncable)) 657 default: 658 model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "model.group_syncable.type.app_error", nil, "group_id="+groupSyncable.GroupId+", syncable_id="+groupSyncable.SyncableId+", "+err.Error(), http.StatusInternalServerError) 659 return result 660 } 661 662 if err != nil { 663 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 664 return result 665 } 666 667 result.Data = groupSyncable 668 return result 669 } 670 671 // PendingAutoAddTeamMembers returns a slice of UserTeamIDPair that need newly created memberships 672 // based on the groups configurations. 673 // 674 // Typically since will be the last successful group sync time. 675 func (s *SqlSupplier) PendingAutoAddTeamMembers(ctx context.Context, since int64, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 676 result := store.NewSupplierResult() 677 678 sql := ` 679 SELECT 680 GroupMembers.UserId, GroupTeams.TeamId 681 FROM 682 GroupMembers 683 JOIN GroupTeams 684 ON GroupTeams.GroupId = GroupMembers.GroupId 685 JOIN UserGroups ON UserGroups.Id = GroupMembers.GroupId 686 JOIN Teams ON Teams.Id = GroupTeams.TeamId 687 LEFT OUTER JOIN TeamMembers 688 ON 689 TeamMembers.TeamId = GroupTeams.TeamId 690 AND TeamMembers.UserId = GroupMembers.UserId 691 WHERE 692 TeamMembers.UserId IS NULL 693 AND UserGroups.DeleteAt = 0 694 AND GroupTeams.DeleteAt = 0 695 AND GroupTeams.AutoAdd = true 696 AND GroupMembers.DeleteAt = 0 697 AND Teams.DeleteAt = 0 698 AND (GroupMembers.CreateAt >= :Since 699 OR GroupTeams.UpdateAt >= :Since)` 700 701 var userTeamIDs []*model.UserTeamIDPair 702 703 _, err := s.GetMaster().Select(&userTeamIDs, sql, map[string]interface{}{"Since": since}) 704 if err != nil { 705 result.Err = model.NewAppError("SqlGroupStore.PendingAutoAddTeamMembers", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 706 } 707 708 result.Data = userTeamIDs 709 710 return result 711 } 712 713 // PendingAutoAddChannelMembers returns a slice of UserChannelIDPair that need newly created memberships 714 // based on the groups configurations. 715 // 716 // Typically since will be the last successful group sync time. 717 func (s *SqlSupplier) PendingAutoAddChannelMembers(ctx context.Context, since int64, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 718 result := store.NewSupplierResult() 719 720 sql := ` 721 SELECT 722 GroupMembers.UserId, GroupChannels.ChannelId 723 FROM 724 GroupMembers 725 JOIN GroupChannels ON GroupChannels.GroupId = GroupMembers.GroupId 726 JOIN UserGroups ON UserGroups.Id = GroupMembers.GroupId 727 JOIN Channels ON Channels.Id = GroupChannels.ChannelId 728 LEFT OUTER JOIN ChannelMemberHistory 729 ON 730 ChannelMemberHistory.ChannelId = GroupChannels.ChannelId 731 AND ChannelMemberHistory.UserId = GroupMembers.UserId 732 WHERE 733 ChannelMemberHistory.UserId IS NULL 734 AND ChannelMemberHistory.LeaveTime IS NULL 735 AND UserGroups.DeleteAt = 0 736 AND GroupChannels.DeleteAt = 0 737 AND GroupChannels.AutoAdd = true 738 AND GroupMembers.DeleteAt = 0 739 AND Channels.DeleteAt = 0 740 AND (GroupMembers.CreateAt >= :Since 741 OR GroupChannels.UpdateAt >= :Since)` 742 743 var userChannelIDs []*model.UserChannelIDPair 744 745 _, err := s.GetMaster().Select(&userChannelIDs, sql, map[string]interface{}{"Since": since}) 746 if err != nil { 747 result.Err = model.NewAppError("SqlGroupStore.PendingAutoAddChannelMembers", "store.select_error", nil, "", http.StatusInternalServerError) 748 } 749 750 result.Data = userChannelIDs 751 752 return result 753 } 754 755 func groupSyncableToGroupTeam(groupSyncable *model.GroupSyncable) *groupTeam { 756 return &groupTeam{ 757 GroupSyncable: *groupSyncable, 758 TeamId: groupSyncable.SyncableId, 759 } 760 } 761 762 func groupSyncableToGroupChannel(groupSyncable *model.GroupSyncable) *groupChannel { 763 return &groupChannel{ 764 GroupSyncable: *groupSyncable, 765 ChannelId: groupSyncable.SyncableId, 766 } 767 }