diff options
-rw-r--r-- | api/admin.go | 19 | ||||
-rw-r--r-- | api/admin_test.go | 12 | ||||
-rw-r--r-- | api/context.go | 9 | ||||
-rw-r--r-- | api/oauth.go | 6 | ||||
-rw-r--r-- | api/status.go | 4 | ||||
-rw-r--r-- | api/team.go | 3 | ||||
-rw-r--r-- | api/user.go | 9 | ||||
-rw-r--r-- | einterfaces/cluster.go | 1 | ||||
-rw-r--r-- | i18n/en.json | 4 | ||||
-rw-r--r-- | model/client.go | 10 | ||||
-rw-r--r-- | store/sql_channel_store.go | 5 | ||||
-rw-r--r-- | store/sql_user_store.go | 4 |
12 files changed, 76 insertions, 10 deletions
diff --git a/api/admin.go b/api/admin.go index d371d2515..20e5075b2 100644 --- a/api/admin.go +++ b/api/admin.go @@ -31,6 +31,7 @@ func InitAdmin() { BaseRoutes.Admin.Handle("/config", ApiAdminSystemRequired(getConfig)).Methods("GET") BaseRoutes.Admin.Handle("/save_config", ApiAdminSystemRequired(saveConfig)).Methods("POST") BaseRoutes.Admin.Handle("/reload_config", ApiAdminSystemRequired(reloadConfig)).Methods("GET") + BaseRoutes.Admin.Handle("/invalidate_all_caches", ApiAdminSystemRequired(invalidateAllCaches)).Methods("GET") BaseRoutes.Admin.Handle("/test_email", ApiAdminSystemRequired(testEmail)).Methods("POST") BaseRoutes.Admin.Handle("/recycle_db_conn", ApiAdminSystemRequired(recycleDatabaseConnection)).Methods("GET") BaseRoutes.Admin.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiAdminSystemRequired(getAnalytics)).Methods("GET") @@ -145,6 +146,24 @@ func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) { ReturnStatusOK(w) } +func invalidateAllCaches(c *Context, w http.ResponseWriter, r *http.Request) { + debug.FreeOSMemory() + + InvalidateAllCaches() + + if einterfaces.GetClusterInterface() != nil { + err := einterfaces.GetClusterInterface().InvalidateAllCaches() + if err != nil { + c.Err = err + return + } + + } + + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + ReturnStatusOK(w) +} + func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) { cfg := model.ConfigFromJson(r.Body) if cfg == nil { diff --git a/api/admin_test.go b/api/admin_test.go index e1520877c..e11835380 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -116,6 +116,18 @@ func TestReloadConfig(t *testing.T) { *utils.Cfg.TeamSettings.EnableOpenServer = true } +func TestInvalidateAllCache(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + + if _, err := th.BasicClient.InvalidateAllCaches(); err == nil { + t.Fatal("Shouldn't have permissions") + } + + if _, err := th.SystemAdminClient.InvalidateAllCaches(); err != nil { + t.Fatal(err) + } +} + func TestSaveConfig(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() diff --git a/api/context.go b/api/context.go index 3a867624b..4c2e9d489 100644 --- a/api/context.go +++ b/api/context.go @@ -17,6 +17,7 @@ import ( "github.com/mattermost/platform/einterfaces" "github.com/mattermost/platform/model" + "github.com/mattermost/platform/store" "github.com/mattermost/platform/utils" ) @@ -514,3 +515,11 @@ func RemoveAllSessionsForUserIdSkipClusterSend(userId string) { func AddSessionToCache(session *model.Session) { sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*utils.Cfg.ServiceSettings.SessionCacheInMinutes*60)) } + +func InvalidateAllCaches() { + l4g.Info(utils.T("api.context.invalidate_all_caches")) + sessionCache.Purge() + ClearStatusCache() + store.ClearChannelCaches() + store.ClearUserCaches() +} diff --git a/api/oauth.go b/api/oauth.go index 233ae0879..08c763b61 100644 --- a/api/oauth.go +++ b/api/oauth.go @@ -251,8 +251,8 @@ func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) { func RevokeAccessToken(token string) *model.AppError { + session := GetSession(token) schan := Srv.Store.Session().Remove(token) - sessionCache.Remove(token) if result := <-Srv.Store.OAuth().GetAccessData(token); result.Err != nil { return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.get.app_error", nil, "") @@ -268,6 +268,10 @@ func RevokeAccessToken(token string) *model.AppError { return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_session.app_error", nil, "") } + if session != nil { + RemoveAllSessionsForUserId(session.UserId) + } + return nil } diff --git a/api/status.go b/api/status.go index 897102a4b..a3d419862 100644 --- a/api/status.go +++ b/api/status.go @@ -16,6 +16,10 @@ import ( var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE) +func ClearStatusCache() { + statusCache.Purge() +} + func AddStatusCacheSkipClusterSend(status *model.Status) { statusCache.Add(status.UserId, status) } diff --git a/api/team.go b/api/team.go index eb184285d..3fc367ac0 100644 --- a/api/team.go +++ b/api/team.go @@ -458,12 +458,11 @@ func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) { if session.IsOAuth { RevokeAccessToken(session.Token) } else { - sessionCache.Remove(session.Token) - if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil { c.Err = result.Err return } else { + RemoveAllSessionsForUserId(session.UserId) w.Write([]byte(model.MapToJson(props))) return } diff --git a/api/user.go b/api/user.go index 5c92cf47a..2085ccb60 100644 --- a/api/user.go +++ b/api/user.go @@ -715,7 +715,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) { } } - sessionCache.Remove(c.Session.Token) + RemoveAllSessionsForUserId(c.Session.UserId) c.Session.SetExpireInDays(*utils.Cfg.ServiceSettings.SessionLengthMobileInDays) maxAge := *utils.Cfg.ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24 @@ -756,18 +756,13 @@ func RevokeSessionById(c *Context, sessionId string) { if session.IsOAuth { RevokeAccessToken(session.Token) } else { - sessionCache.Remove(session.Token) - if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil { c.Err = result.Err } } RevokeWebrtcToken(session.Id) - - if einterfaces.GetClusterInterface() != nil { - einterfaces.GetClusterInterface().RemoveAllSessionsForUserId(session.UserId) - } + RemoveAllSessionsForUserId(session.UserId) } } diff --git a/einterfaces/cluster.go b/einterfaces/cluster.go index 30a1af103..43ce46280 100644 --- a/einterfaces/cluster.go +++ b/einterfaces/cluster.go @@ -19,6 +19,7 @@ type ClusterInterface interface { GetLogs() ([]string, *model.AppError) GetClusterId() string ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError + InvalidateAllCaches() *model.AppError } var theClusterInterface ClusterInterface diff --git a/i18n/en.json b/i18n/en.json index 928353c10..33e3887b3 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -684,6 +684,10 @@ "translation": "Invalid session token=%v, err=%v" }, { + "id": "api.context.invalidate_all_caches", + "translation": "Purging all caches" + }, + { "id": "api.context.last_activity_at.error", "translation": "Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v" }, diff --git a/model/client.go b/model/client.go index f782940d8..53b1887a0 100644 --- a/model/client.go +++ b/model/client.go @@ -974,6 +974,16 @@ func (c *Client) ReloadConfig() (bool, *AppError) { } } +func (c *Client) InvalidateAllCaches() (bool, *AppError) { + c.clearExtraProperties() + if r, err := c.DoApiGet("/admin/invalidate_all_caches", "", ""); err != nil { + return false, err + } else { + c.fillInExtraProperties(r) + return c.CheckStatusOK(r), nil + } +} + func (c *Client) SaveConfig(config *Config) (*Result, *AppError) { if r, err := c.DoApiPost("/admin/save_config", config.ToJson()); err != nil { return nil, err diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go index e6b7b80bf..3ce672a68 100644 --- a/store/sql_channel_store.go +++ b/store/sql_channel_store.go @@ -33,6 +33,11 @@ type SqlChannelStore struct { var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE) var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE) +func ClearChannelCaches() { + channelMemberCountsCache.Purge() + allChannelMembersForUserCache.Purge() +} + func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore { s := &SqlChannelStore{sqlStore} diff --git a/store/sql_user_store.go b/store/sql_user_store.go index c8c6714d8..3fddfb77d 100644 --- a/store/sql_user_store.go +++ b/store/sql_user_store.go @@ -35,6 +35,10 @@ type SqlUserStore struct { var profilesInChannelCache *utils.Cache = utils.NewLru(PROFILES_IN_CHANNEL_CACHE_SIZE) +func ClearUserCaches() { + profilesInChannelCache.Purge() +} + func NewSqlUserStore(sqlStore *SqlStore) UserStore { us := &SqlUserStore{sqlStore} |