github.com/jfrerich/mattermost-server@v5.8.0-rc2+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.CanLeave = groupTeam.CanLeave 474 groupSyncable.AutoAdd = groupTeam.AutoAdd 475 groupSyncable.CreateAt = groupTeam.CreateAt 476 groupSyncable.DeleteAt = groupTeam.DeleteAt 477 groupSyncable.UpdateAt = groupTeam.UpdateAt 478 groupSyncable.Type = syncableType 479 case model.GroupSyncableTypeChannel: 480 groupChannel := result.(*groupChannel) 481 groupSyncable.SyncableId = groupChannel.ChannelId 482 groupSyncable.GroupId = groupChannel.GroupId 483 groupSyncable.CanLeave = groupChannel.CanLeave 484 groupSyncable.AutoAdd = groupChannel.AutoAdd 485 groupSyncable.CreateAt = groupChannel.CreateAt 486 groupSyncable.DeleteAt = groupChannel.DeleteAt 487 groupSyncable.UpdateAt = groupChannel.UpdateAt 488 groupSyncable.Type = syncableType 489 default: 490 return nil, fmt.Errorf("unable to convert syncableType: %s", syncableType.String()) 491 } 492 493 return &groupSyncable, nil 494 } 495 496 func (s *SqlSupplier) GroupGetAllGroupSyncablesByGroup(ctx context.Context, groupID string, syncableType model.GroupSyncableType, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 497 result := store.NewSupplierResult() 498 499 args := map[string]interface{}{"GroupId": groupID} 500 501 appErrF := func(msg string) *model.AppError { 502 return model.NewAppError("SqlGroupStore.GroupGetAllGroupSyncablesByGroup", "store.select_error", nil, msg, http.StatusInternalServerError) 503 } 504 505 groupSyncables := []*model.GroupSyncable{} 506 507 switch syncableType { 508 case model.GroupSyncableTypeTeam: 509 sqlQuery := ` 510 SELECT 511 GroupTeams.*, 512 Teams.DisplayName AS TeamDisplayName, 513 Teams.Type AS TeamType 514 FROM 515 GroupTeams 516 JOIN Teams ON Teams.Id = GroupTeams.TeamId 517 WHERE 518 GroupId = :GroupId AND GroupTeams.DeleteAt = 0` 519 520 results := []*groupTeamJoin{} 521 _, err := s.GetMaster().Select(&results, sqlQuery, args) 522 if err != nil { 523 result.Err = appErrF(err.Error()) 524 return result 525 } 526 for _, result := range results { 527 groupSyncable := &model.GroupSyncable{ 528 SyncableId: result.TeamId, 529 GroupId: result.GroupId, 530 CanLeave: result.CanLeave, 531 AutoAdd: result.AutoAdd, 532 CreateAt: result.CreateAt, 533 DeleteAt: result.DeleteAt, 534 UpdateAt: result.UpdateAt, 535 Type: syncableType, 536 TeamDisplayName: result.TeamDisplayName, 537 TeamType: result.TeamType, 538 } 539 groupSyncables = append(groupSyncables, groupSyncable) 540 } 541 case model.GroupSyncableTypeChannel: 542 sqlQuery := ` 543 SELECT 544 GroupChannels.*, 545 Channels.DisplayName AS ChannelDisplayName, 546 Teams.DisplayName AS TeamDisplayName, 547 Channels.Type As ChannelType, 548 Teams.Type As TeamType, 549 Teams.Id AS TeamId 550 FROM 551 GroupChannels 552 JOIN Channels ON Channels.Id = GroupChannels.ChannelId 553 JOIN Teams ON Teams.Id = Channels.TeamId 554 WHERE 555 GroupId = :GroupId AND GroupChannels.DeleteAt = 0` 556 557 results := []*groupChannelJoin{} 558 _, err := s.GetMaster().Select(&results, sqlQuery, args) 559 if err != nil { 560 result.Err = appErrF(err.Error()) 561 return result 562 } 563 for _, result := range results { 564 groupSyncable := &model.GroupSyncable{ 565 SyncableId: result.ChannelId, 566 GroupId: result.GroupId, 567 CanLeave: result.CanLeave, 568 AutoAdd: result.AutoAdd, 569 CreateAt: result.CreateAt, 570 DeleteAt: result.DeleteAt, 571 UpdateAt: result.UpdateAt, 572 Type: syncableType, 573 ChannelDisplayName: result.ChannelDisplayName, 574 ChannelType: result.ChannelType, 575 TeamDisplayName: result.TeamDisplayName, 576 TeamType: result.TeamType, 577 TeamID: result.TeamID, 578 } 579 groupSyncables = append(groupSyncables, groupSyncable) 580 } 581 } 582 583 result.Data = groupSyncables 584 return result 585 } 586 587 func (s *SqlSupplier) GroupUpdateGroupSyncable(ctx context.Context, groupSyncable *model.GroupSyncable, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 588 result := store.NewSupplierResult() 589 590 retrievedGroupSyncable, err := s.getGroupSyncable(groupSyncable.GroupId, groupSyncable.SyncableId, groupSyncable.Type) 591 if err != nil { 592 if err == sql.ErrNoRows { 593 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "store.sql_group.no_rows", nil, err.Error(), http.StatusInternalServerError) 594 return result 595 } 596 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "store.select_error", nil, "GroupId="+groupSyncable.GroupId+", SyncableId="+groupSyncable.SyncableId+", SyncableType="+groupSyncable.Type.String()+", "+err.Error(), http.StatusInternalServerError) 597 return result 598 } 599 600 if err := groupSyncable.IsValid(); err != nil { 601 result.Err = err 602 return result 603 } 604 605 // If updating DeleteAt it can only be to 0 606 if groupSyncable.DeleteAt != retrievedGroupSyncable.DeleteAt && groupSyncable.DeleteAt != 0 { 607 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "model.group.delete_at.app_error", nil, "", http.StatusInternalServerError) 608 return result 609 } 610 611 // Reset these properties, don't update them based on input 612 groupSyncable.CreateAt = retrievedGroupSyncable.CreateAt 613 groupSyncable.UpdateAt = model.GetMillis() 614 615 switch groupSyncable.Type { 616 case model.GroupSyncableTypeTeam: 617 _, err = s.GetMaster().Update(groupSyncableToGroupTeam(groupSyncable)) 618 case model.GroupSyncableTypeChannel: 619 _, err = s.GetMaster().Update(groupSyncableToGroupChannel(groupSyncable)) 620 default: 621 model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "model.group_syncable.type.app_error", nil, "group_id="+groupSyncable.GroupId+", syncable_id="+groupSyncable.SyncableId+", "+err.Error(), http.StatusInternalServerError) 622 return result 623 } 624 625 if err != nil { 626 result.Err = model.NewAppError("SqlGroupStore.GroupUpdateGroupSyncable", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 627 return result 628 } 629 630 result.Data = groupSyncable 631 return result 632 } 633 634 func (s *SqlSupplier) GroupDeleteGroupSyncable(ctx context.Context, groupID string, syncableID string, syncableType model.GroupSyncableType, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 635 result := store.NewSupplierResult() 636 637 groupSyncable, err := s.getGroupSyncable(groupID, syncableID, syncableType) 638 if err != nil { 639 if err == sql.ErrNoRows { 640 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.sql_group.no_rows", nil, "Id="+groupID+", "+err.Error(), http.StatusNotFound) 641 } else { 642 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 643 } 644 return result 645 } 646 647 if groupSyncable.DeleteAt != 0 { 648 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.sql_group.group_syncable_already_deleted", nil, "group_id="+groupID+"syncable_id="+syncableID, http.StatusBadRequest) 649 return result 650 } 651 652 time := model.GetMillis() 653 groupSyncable.DeleteAt = time 654 groupSyncable.UpdateAt = time 655 656 switch groupSyncable.Type { 657 case model.GroupSyncableTypeTeam: 658 _, err = s.GetMaster().Update(groupSyncableToGroupTeam(groupSyncable)) 659 case model.GroupSyncableTypeChannel: 660 _, err = s.GetMaster().Update(groupSyncableToGroupChannel(groupSyncable)) 661 default: 662 model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "model.group_syncable.type.app_error", nil, "group_id="+groupSyncable.GroupId+", syncable_id="+groupSyncable.SyncableId+", "+err.Error(), http.StatusInternalServerError) 663 return result 664 } 665 666 if err != nil { 667 result.Err = model.NewAppError("SqlGroupStore.GroupDeleteGroupSyncable", "store.update_error", nil, err.Error(), http.StatusInternalServerError) 668 return result 669 } 670 671 result.Data = groupSyncable 672 return result 673 } 674 675 // PendingAutoAddTeamMembers returns a slice of UserTeamIDPair that need newly created memberships 676 // based on the groups configurations. 677 // 678 // Typically since will be the last successful group sync time. 679 func (s *SqlSupplier) PendingAutoAddTeamMembers(ctx context.Context, since int64, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 680 result := store.NewSupplierResult() 681 682 sql := ` 683 SELECT 684 GroupMembers.UserId, GroupTeams.TeamId 685 FROM 686 GroupMembers 687 JOIN GroupTeams 688 ON GroupTeams.GroupId = GroupMembers.GroupId 689 JOIN UserGroups ON UserGroups.Id = GroupMembers.GroupId 690 JOIN Teams ON Teams.Id = GroupTeams.TeamId 691 LEFT OUTER JOIN TeamMembers 692 ON 693 TeamMembers.TeamId = GroupTeams.TeamId 694 AND TeamMembers.UserId = GroupMembers.UserId 695 WHERE 696 TeamMembers.UserId IS NULL 697 AND UserGroups.DeleteAt = 0 698 AND GroupTeams.DeleteAt = 0 699 AND GroupTeams.AutoAdd = true 700 AND GroupMembers.DeleteAt = 0 701 AND Teams.DeleteAt = 0 702 AND (GroupMembers.CreateAt >= :Since 703 OR GroupTeams.UpdateAt >= :Since)` 704 705 var userTeamIDs []*model.UserTeamIDPair 706 707 _, err := s.GetMaster().Select(&userTeamIDs, sql, map[string]interface{}{"Since": since}) 708 if err != nil { 709 result.Err = model.NewAppError("SqlGroupStore.PendingAutoAddTeamMembers", "store.select_error", nil, err.Error(), http.StatusInternalServerError) 710 } 711 712 result.Data = userTeamIDs 713 714 return result 715 } 716 717 // PendingAutoAddChannelMembers returns a slice of UserChannelIDPair that need newly created memberships 718 // based on the groups configurations. 719 // 720 // Typically since will be the last successful group sync time. 721 func (s *SqlSupplier) PendingAutoAddChannelMembers(ctx context.Context, since int64, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 722 result := store.NewSupplierResult() 723 724 sql := ` 725 SELECT 726 GroupMembers.UserId, GroupChannels.ChannelId 727 FROM 728 GroupMembers 729 JOIN GroupChannels ON GroupChannels.GroupId = GroupMembers.GroupId 730 JOIN UserGroups ON UserGroups.Id = GroupMembers.GroupId 731 JOIN Channels ON Channels.Id = GroupChannels.ChannelId 732 LEFT OUTER JOIN ChannelMemberHistory 733 ON 734 ChannelMemberHistory.ChannelId = GroupChannels.ChannelId 735 AND ChannelMemberHistory.UserId = GroupMembers.UserId 736 WHERE 737 ChannelMemberHistory.UserId IS NULL 738 AND ChannelMemberHistory.LeaveTime IS NULL 739 AND UserGroups.DeleteAt = 0 740 AND GroupChannels.DeleteAt = 0 741 AND GroupChannels.AutoAdd = true 742 AND GroupMembers.DeleteAt = 0 743 AND Channels.DeleteAt = 0 744 AND (GroupMembers.CreateAt >= :Since 745 OR GroupChannels.UpdateAt >= :Since)` 746 747 var userChannelIDs []*model.UserChannelIDPair 748 749 _, err := s.GetMaster().Select(&userChannelIDs, sql, map[string]interface{}{"Since": since}) 750 if err != nil { 751 result.Err = model.NewAppError("SqlGroupStore.PendingAutoAddChannelMembers", "store.select_error", nil, "", http.StatusInternalServerError) 752 } 753 754 result.Data = userChannelIDs 755 756 return result 757 } 758 759 func groupSyncableToGroupTeam(groupSyncable *model.GroupSyncable) *groupTeam { 760 return &groupTeam{ 761 GroupSyncable: *groupSyncable, 762 TeamId: groupSyncable.SyncableId, 763 } 764 } 765 766 func groupSyncableToGroupChannel(groupSyncable *model.GroupSyncable) *groupChannel { 767 return &groupChannel{ 768 GroupSyncable: *groupSyncable, 769 ChannelId: groupSyncable.SyncableId, 770 } 771 }