MM-48181: Invalidate cache to reflect permissions changes from a team scheme. (#21735)
* MM-48181: Bust the allChannelMembersForUserCache when assigning a team scheme. * MM-48181: Tests cache fix.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
98a14c8c55
Коммит
3e7a8d8426
@@ -308,6 +308,8 @@ func (a *App) UpdateTeamScheme(team *model.Team) (*model.Team, *model.AppError)
|
|||||||
return nil, model.NewAppError("UpdateTeamScheme", "app.team.clear_cache.app_error", nil, "", http.StatusInternalServerError).Wrap(nErr)
|
return nil, model.NewAppError("UpdateTeamScheme", "app.team.clear_cache.app_error", nil, "", http.StatusInternalServerError).Wrap(nErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.Srv().Store().Channel().ClearMembersForUserCache()
|
||||||
|
|
||||||
if appErr := a.sendTeamEvent(oldTeam, model.WebsocketEventUpdateTeamScheme); appErr != nil {
|
if appErr := a.sendTeamEvent(oldTeam, model.WebsocketEventUpdateTeamScheme); appErr != nil {
|
||||||
return nil, appErr
|
return nil, appErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1109,6 +1109,45 @@ func TestAppUpdateTeamScheme(t *testing.T) {
|
|||||||
updatedTeam, err := th.App.UpdateTeamScheme(th.BasicTeam)
|
updatedTeam, err := th.App.UpdateTeamScheme(th.BasicTeam)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, mockID, updatedTeam.SchemeId, "Wrong Team SchemeId")
|
require.Equal(t, mockID, updatedTeam.SchemeId, "Wrong Team SchemeId")
|
||||||
|
|
||||||
|
// Test that a newly applied team scheme applies the new permissions to a team member
|
||||||
|
th.App.SetPhase2PermissionsMigrationStatus(true)
|
||||||
|
|
||||||
|
team2Scheme := th.SetupTeamScheme()
|
||||||
|
channelUser, err := th.App.GetRoleByName(context.Background(), team2Scheme.DefaultChannelUserRole)
|
||||||
|
require.Nil(t, err)
|
||||||
|
channelUser.Permissions = []string{}
|
||||||
|
_, err = th.App.UpdateRole(channelUser) // Remove all permissions from the team user role of the scheme
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
channelAdmin, err := th.App.GetRoleByName(context.Background(), team2Scheme.DefaultChannelAdminRole)
|
||||||
|
require.Nil(t, err)
|
||||||
|
channelAdmin.Permissions = []string{}
|
||||||
|
_, err = th.App.UpdateRole(channelAdmin) // Remove all permissions from the team admin role of the scheme
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
team2 := th.CreateTeam()
|
||||||
|
th.App.AddUserToTeam(th.Context, team2.Id, th.BasicUser.Id, "")
|
||||||
|
channel := th.CreateChannel(th.Context, team2)
|
||||||
|
th.App.AddUserToChannel(th.Context, th.BasicUser, channel, true)
|
||||||
|
session := model.Session{
|
||||||
|
Roles: model.SystemUserRoleId,
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
TeamMembers: []*model.TeamMember{
|
||||||
|
{
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
TeamId: team2.Id,
|
||||||
|
SchemeUser: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// ensure user can update channel properties before applying the scheme
|
||||||
|
require.True(t, th.App.SessionHasPermissionToChannel(th.Context, session, channel.Id, model.PermissionManagePublicChannelProperties))
|
||||||
|
// apply the team scheme
|
||||||
|
team2.SchemeId = &team2Scheme.Id
|
||||||
|
_, err = th.App.UpdateTeamScheme(team2)
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.False(t, th.App.SessionHasPermissionToChannel(th.Context, session, channel.Id, model.PermissionManagePublicChannelProperties))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetTeamMembers(t *testing.T) {
|
func TestGetTeamMembers(t *testing.T) {
|
||||||
|
|||||||
@@ -696,6 +696,19 @@ func (s *OpenTracingLayerChannelStore) ClearCaches() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *OpenTracingLayerChannelStore) ClearMembersForUserCache() {
|
||||||
|
origCtx := s.Root.Store.Context()
|
||||||
|
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.ClearMembersForUserCache")
|
||||||
|
s.Root.Store.SetContext(newCtx)
|
||||||
|
defer func() {
|
||||||
|
s.Root.Store.SetContext(origCtx)
|
||||||
|
}()
|
||||||
|
|
||||||
|
defer span.Finish()
|
||||||
|
s.ChannelStore.ClearMembersForUserCache()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *OpenTracingLayerChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
func (s *OpenTracingLayerChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
||||||
origCtx := s.Root.Store.Context()
|
origCtx := s.Root.Store.Context()
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.ClearSidebarOnTeamLeave")
|
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.ClearSidebarOnTeamLeave")
|
||||||
|
|||||||
@@ -750,6 +750,12 @@ func (s *RetryLayerChannelStore) ClearCaches() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *RetryLayerChannelStore) ClearMembersForUserCache() {
|
||||||
|
|
||||||
|
s.ChannelStore.ClearMembersForUserCache()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *RetryLayerChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
func (s *RetryLayerChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
||||||
|
|
||||||
tries := 0
|
tries := 0
|
||||||
|
|||||||
@@ -451,6 +451,10 @@ var channelByNameCache = cache.NewLRU(cache.LRUOptions{
|
|||||||
Size: model.ChannelCacheSize,
|
Size: model.ChannelCacheSize,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
func (s SqlChannelStore) ClearMembersForUserCache() {
|
||||||
|
allChannelMembersForUserCache.Purge()
|
||||||
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) ClearCaches() {
|
func (s SqlChannelStore) ClearCaches() {
|
||||||
allChannelMembersForUserCache.Purge()
|
allChannelMembersForUserCache.Purge()
|
||||||
allChannelMembersNotifyPropsForChannelCache.Purge()
|
allChannelMembersNotifyPropsForChannelCache.Purge()
|
||||||
|
|||||||
@@ -267,6 +267,7 @@ type ChannelStore interface {
|
|||||||
AnalyticsDeletedTypeCount(teamID string, channelType model.ChannelType) (int64, error)
|
AnalyticsDeletedTypeCount(teamID string, channelType model.ChannelType) (int64, error)
|
||||||
GetChannelUnread(channelID, userID string) (*model.ChannelUnread, error)
|
GetChannelUnread(channelID, userID string) (*model.ChannelUnread, error)
|
||||||
ClearCaches()
|
ClearCaches()
|
||||||
|
ClearMembersForUserCache()
|
||||||
GetChannelsByScheme(schemeID string, offset int, limit int) (model.ChannelList, error)
|
GetChannelsByScheme(schemeID string, offset int, limit int) (model.ChannelList, error)
|
||||||
MigrateChannelMembers(fromChannelID string, fromUserID string) (map[string]string, error)
|
MigrateChannelMembers(fromChannelID string, fromUserID string) (map[string]string, error)
|
||||||
ResetAllChannelSchemes() error
|
ResetAllChannelSchemes() error
|
||||||
|
|||||||
@@ -150,6 +150,11 @@ func (_m *ChannelStore) ClearCaches() {
|
|||||||
_m.Called()
|
_m.Called()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearMembersForUserCache provides a mock function with given fields:
|
||||||
|
func (_m *ChannelStore) ClearMembersForUserCache() {
|
||||||
|
_m.Called()
|
||||||
|
}
|
||||||
|
|
||||||
// ClearSidebarOnTeamLeave provides a mock function with given fields: userID, teamID
|
// ClearSidebarOnTeamLeave provides a mock function with given fields: userID, teamID
|
||||||
func (_m *ChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
func (_m *ChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
||||||
ret := _m.Called(userID, teamID)
|
ret := _m.Called(userID, teamID)
|
||||||
|
|||||||
@@ -669,6 +669,21 @@ func (s *TimerLayerChannelStore) ClearCaches() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *TimerLayerChannelStore) ClearMembersForUserCache() {
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
s.ChannelStore.ClearMembersForUserCache()
|
||||||
|
|
||||||
|
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||||
|
if s.Root.Metrics != nil {
|
||||||
|
success := "false"
|
||||||
|
if true {
|
||||||
|
success = "true"
|
||||||
|
}
|
||||||
|
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.ClearMembersForUserCache", success, elapsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *TimerLayerChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
func (s *TimerLayerChannelStore) ClearSidebarOnTeamLeave(userID string, teamID string) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user