MM-20644: Add users to teams as a SchemeAdmin based on a new configuration field on GroupTeams and GroupChannels records. (#13361)
* MM-20644: Add users to teams as a SchemeAdmin based on a new configuration field on GroupTeams and GroupChannels records. * MM-20644: Adds SchemeAdmin to mapping of the GroupSyncable struct fields. * MM-2064: Adds test to ensure SchemeAdmin field value is mapped. * MM-20644: Adds missing index creation for fresh DBs. * MM-20644: Duplicates UpdateMembersRole across Team and Channel stores. Adds tests. * MM-20644: Fixes some old method name references. * MM-20644: Moves variable declaration; removes Println statement. * MM-20644: Use a SQL query instead of two to update Team and Channel members. * MM-20644: Fixes tests; updates query. * MM-20644: Fix permission check for patching a group syncable. * MM-20644: Fixes test for change of permissions verification in group patch API request. * MM-20644: Fix for ORM select vs insert. * MM-20644: Linting fixes. * MM-20644: Fixes some tests. * MM-20644: Skips changing the role of guests. * MM-20644: Added syncableID filtering
Этот коммит содержится в:
коммит произвёл
catalintomai
родитель
04430041a8
Коммит
605040c597
@@ -2838,3 +2838,25 @@ func (s SqlChannelStore) UserBelongsToChannels(userId string, channelIds []strin
|
||||
}
|
||||
return c > 0, nil
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) UpdateMembersRole(channelID string, userIDs []string) *model.AppError {
|
||||
sql := fmt.Sprintf(`
|
||||
UPDATE
|
||||
ChannelMembers
|
||||
SET
|
||||
SchemeAdmin = CASE WHEN UserId IN ('%s') THEN
|
||||
TRUE
|
||||
ELSE
|
||||
FALSE
|
||||
END
|
||||
WHERE
|
||||
ChannelId = :ChannelId
|
||||
AND (SchemeGuest = false OR SchemeGuest IS NULL)
|
||||
`, strings.Join(userIDs, "', '"))
|
||||
|
||||
if _, err := s.GetMaster().Exec(sql, map[string]interface{}{"ChannelId": channelID}); err != nil {
|
||||
return model.NewAppError("SqlChannelStore.UpdateMembersRole", "store.update_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ func (s *SqlGroupStore) CreateIndexesIfNotExists() {
|
||||
s.CreateIndexIfNotExists("idx_groupchannels_channelid", "GroupChannels", "ChannelId")
|
||||
s.CreateColumnIfNotExistsNoDefault("Channels", "GroupConstrained", "tinyint(1)", "boolean")
|
||||
s.CreateColumnIfNotExistsNoDefault("Teams", "GroupConstrained", "tinyint(1)", "boolean")
|
||||
s.CreateIndexIfNotExists("idx_groupteams_schemeadmin", "GroupTeams", "SchemeAdmin")
|
||||
s.CreateIndexIfNotExists("idx_groupchannels_schemeadmin", "GroupChannels", "SchemeAdmin")
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) Create(group *model.Group) (*model.Group, *model.AppError) {
|
||||
@@ -512,6 +514,7 @@ func (s *SqlGroupStore) GetAllGroupSyncablesByGroupId(groupID string, syncableTy
|
||||
Type: syncableType,
|
||||
TeamDisplayName: result.TeamDisplayName,
|
||||
TeamType: result.TeamType,
|
||||
SchemeAdmin: result.SchemeAdmin,
|
||||
}
|
||||
groupSyncables = append(groupSyncables, groupSyncable)
|
||||
}
|
||||
@@ -550,6 +553,7 @@ func (s *SqlGroupStore) GetAllGroupSyncablesByGroupId(groupID string, syncableTy
|
||||
TeamDisplayName: result.TeamDisplayName,
|
||||
TeamType: result.TeamType,
|
||||
TeamID: result.TeamID,
|
||||
SchemeAdmin: result.SchemeAdmin,
|
||||
}
|
||||
groupSyncables = append(groupSyncables, groupSyncable)
|
||||
}
|
||||
@@ -784,7 +788,7 @@ func (s *SqlGroupStore) CountGroupsByChannel(channelId string, opts model.GroupS
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetGroupsByChannel(channelId string, opts model.GroupSearchOpts) ([]*model.Group, *model.AppError) {
|
||||
func (s *SqlGroupStore) GetGroupsByChannel(channelId string, opts model.GroupSearchOpts) ([]*model.GroupWithSchemeAdmin, *model.AppError) {
|
||||
query := s.groupsBySyncableBaseQuery(model.GroupSyncableTypeChannel, selectGroups, channelId, opts)
|
||||
|
||||
if opts.PageOpts != nil {
|
||||
@@ -797,7 +801,7 @@ func (s *SqlGroupStore) GetGroupsByChannel(channelId string, opts model.GroupSea
|
||||
return nil, model.NewAppError("SqlGroupStore.GetGroupsByChannel", "store.sql_group.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var groups []*model.Group
|
||||
var groups []*model.GroupWithSchemeAdmin
|
||||
|
||||
_, err = s.GetReplica().Select(&groups, queryString, args...)
|
||||
if err != nil {
|
||||
@@ -861,7 +865,7 @@ func (s *SqlGroupStore) ChannelMembersToRemove() ([]*model.ChannelMember, *model
|
||||
|
||||
func (s *SqlGroupStore) groupsBySyncableBaseQuery(st model.GroupSyncableType, t selectType, syncableID string, opts model.GroupSearchOpts) sq.SelectBuilder {
|
||||
selectStrs := map[selectType]string{
|
||||
selectGroups: "ug.*",
|
||||
selectGroups: "ug.*, gs.SchemeAdmin AS SyncableSchemeAdmin",
|
||||
selectCountGroups: "COUNT(*)",
|
||||
}
|
||||
|
||||
@@ -883,7 +887,7 @@ func (s *SqlGroupStore) groupsBySyncableBaseQuery(st model.GroupSyncableType, t
|
||||
|
||||
if opts.IncludeMemberCount && t == selectGroups {
|
||||
query = s.getQueryBuilder().
|
||||
Select("ug.*, coalesce(Members.MemberCount, 0) AS MemberCount").
|
||||
Select(fmt.Sprintf("ug.*, coalesce(Members.MemberCount, 0) AS MemberCount, Group%ss.SchemeAdmin AS SyncableSchemeAdmin", st)).
|
||||
From("UserGroups ug").
|
||||
LeftJoin("(SELECT GroupMembers.GroupId, COUNT(*) AS MemberCount FROM GroupMembers LEFT JOIN Users ON Users.Id = GroupMembers.UserId WHERE GroupMembers.DeleteAt = 0 AND Users.DeleteAt = 0 GROUP BY GroupId) AS Members ON Members.GroupId = ug.Id").
|
||||
LeftJoin(fmt.Sprintf("%[1]s ON %[1]s.GroupId = ug.Id", table)).
|
||||
@@ -919,7 +923,7 @@ func (s *SqlGroupStore) CountGroupsByTeam(teamId string, opts model.GroupSearchO
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetGroupsByTeam(teamId string, opts model.GroupSearchOpts) ([]*model.Group, *model.AppError) {
|
||||
func (s *SqlGroupStore) GetGroupsByTeam(teamId string, opts model.GroupSearchOpts) ([]*model.GroupWithSchemeAdmin, *model.AppError) {
|
||||
query := s.groupsBySyncableBaseQuery(model.GroupSyncableTypeTeam, selectGroups, teamId, opts)
|
||||
|
||||
if opts.PageOpts != nil {
|
||||
@@ -932,7 +936,7 @@ func (s *SqlGroupStore) GetGroupsByTeam(teamId string, opts model.GroupSearchOpt
|
||||
return nil, model.NewAppError("SqlGroupStore.GetGroupsByTeam", "store.sql_group.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var groups []*model.Group
|
||||
var groups []*model.GroupWithSchemeAdmin
|
||||
|
||||
_, err = s.GetReplica().Select(&groups, queryString, args...)
|
||||
if err != nil {
|
||||
@@ -1164,3 +1168,46 @@ func (s *SqlGroupStore) CountChannelMembersMinusGroupMembers(channelID string, g
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) AdminRoleGroupsForSyncableMember(userID, syncableID string, syncableType model.GroupSyncableType) ([]string, *model.AppError) {
|
||||
var groupIds []string
|
||||
|
||||
sql := fmt.Sprintf(`
|
||||
SELECT
|
||||
GroupMembers.GroupId
|
||||
FROM
|
||||
GroupMembers
|
||||
INNER JOIN
|
||||
Group%[1]ss ON Group%[1]ss.GroupId = GroupMembers.GroupId
|
||||
WHERE
|
||||
GroupMembers.UserId = :UserId
|
||||
AND GroupMembers.DeleteAt = 0
|
||||
AND %[1]sId = :%[1]sId
|
||||
AND Group%[1]ss.DeleteAt = 0
|
||||
AND Group%[1]ss.SchemeAdmin = TRUE`, syncableType)
|
||||
|
||||
_, err := s.GetReplica().Select(&groupIds, sql, map[string]interface{}{"UserId": userID, fmt.Sprintf("%sId", syncableType): syncableID})
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("SqlGroupStore AdminRoleGroupsForSyncableMember", "store.select_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return groupIds, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) PermittedSyncableAdmins(syncableID string, syncableType model.GroupSyncableType) ([]string, *model.AppError) {
|
||||
query := s.getQueryBuilder().Select("UserId").
|
||||
From(fmt.Sprintf("Group%ss", syncableType)).
|
||||
Join(fmt.Sprintf("GroupMembers ON GroupMembers.GroupId = Group%ss.GroupId AND Group%[1]ss.SchemeAdmin = TRUE AND GroupMembers.DeleteAt = 0", syncableType.String())).Where(fmt.Sprintf("Group%[1]ss.%[1]sId = ?", syncableType.String()), syncableID)
|
||||
|
||||
sql, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("SqlGroupStore.PermittedSyncableAdmins", "store.sql_group.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var userIDs []string
|
||||
if _, err = s.GetReplica().Select(&userIDs, sql, args...); err != nil {
|
||||
return nil, model.NewAppError("SqlGroupStore.PermittedSyncableAdmins", "store.select_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return userIDs, nil
|
||||
}
|
||||
|
||||
@@ -1080,6 +1080,28 @@ func (s SqlTeamStore) UserBelongsToTeams(userId string, teamIds []string) (bool,
|
||||
return c > 0, nil
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) UpdateMembersRole(teamID string, userIDs []string) *model.AppError {
|
||||
sql := fmt.Sprintf(`
|
||||
UPDATE
|
||||
TeamMembers
|
||||
SET
|
||||
SchemeAdmin = CASE WHEN UserId IN ('%s') THEN
|
||||
TRUE
|
||||
ELSE
|
||||
FALSE
|
||||
END
|
||||
WHERE
|
||||
TeamId = :TeamId
|
||||
AND (SchemeGuest = false OR SchemeGuest IS NULL)
|
||||
AND DeleteAt = 0`, strings.Join(userIDs, "', '"))
|
||||
|
||||
if _, err := s.GetMaster().Exec(sql, map[string]interface{}{"TeamId": teamID}); err != nil {
|
||||
return model.NewAppError("SqlTeamStore.UpdateMembersRole", "store.update_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyTeamMemberViewRestrictionsFilter(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder {
|
||||
if restrictions == nil {
|
||||
return query
|
||||
|
||||
@@ -754,6 +754,12 @@ func upgradeDatabaseToVersion520(sqlStore SqlStore) {
|
||||
|
||||
sqlStore.CreateColumnIfNotExistsNoDefault("Bots", "LastIconUpdate", "bigint", "bigint")
|
||||
|
||||
sqlStore.CreateColumnIfNotExists("GroupTeams", "SchemeAdmin", "boolean", "boolean", "0")
|
||||
sqlStore.CreateIndexIfNotExists("idx_groupteams_schemeadmin", "GroupTeams", "SchemeAdmin")
|
||||
|
||||
sqlStore.CreateColumnIfNotExists("GroupChannels", "SchemeAdmin", "boolean", "boolean", "0")
|
||||
sqlStore.CreateIndexIfNotExists("idx_groupchannels_schemeadmin", "GroupChannels", "SchemeAdmin")
|
||||
|
||||
// saveSchemaVersion(sqlStore, VERSION_5_20_0)
|
||||
// }
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user