Remove more global refs / state (#7723)

* remove more global refs / state

* fix job enterprise initialization

* fix api4 test compilation

* saml api endpoints fix
Этот коммит содержится в:
Chris
2017-10-26 14:21:22 -05:00
коммит произвёл Joram Wilander
родитель a0bfd2885d
Коммит 7ed011745a
23 изменённых файлов: 129 добавлений и 150 удалений

Просмотреть файл

@@ -114,7 +114,7 @@ func (a *App) InvalidateAllCaches() *model.AppError {
func (a *App) InvalidateAllCachesSkipSend() {
l4g.Info(utils.T("api.context.invalidate_all_caches"))
sessionCache.Purge()
a.sessionCache.Purge()
ClearStatusCache()
sqlstore.ClearChannelCaches()
sqlstore.ClearUserCaches()
@@ -133,7 +133,7 @@ func (a *App) GetConfig() *model.Config {
func (a *App) ReloadConfig() {
debug.FreeOSMemory()
utils.LoadConfig(utils.CfgFileName)
utils.LoadConfig(a.ConfigFileName())
// start/restart email batching job if necessary
a.InitEmailBatching()
@@ -157,8 +157,8 @@ func (a *App) SaveConfig(cfg *model.Config, sendConfigChangeClusterMessage bool)
}
utils.DisableConfigWatch()
utils.SaveConfig(utils.CfgFileName, cfg)
utils.LoadConfig(utils.CfgFileName)
utils.SaveConfig(a.ConfigFileName(), cfg)
utils.LoadConfig(a.ConfigFileName())
utils.EnableConfigWatch()
if a.Metrics != nil {

Просмотреть файл

@@ -48,6 +48,8 @@ type App struct {
Saml einterfaces.SamlInterface
newStore func() store.Store
sessionCache *utils.Cache
}
var appCount = 0
@@ -64,10 +66,10 @@ func New(options ...Option) *App {
app := &App{
goroutineExitSignal: make(chan struct{}, 1),
Jobs: &jobs.JobServer{},
Srv: &Server{
Router: mux.NewRouter(),
},
sessionCache: utils.NewLru(model.SESSION_CACHE_SIZE),
}
app.initEnterprise()
@@ -82,7 +84,7 @@ func New(options ...Option) *App {
}
app.Srv.Store = app.newStore()
app.Jobs.Store = app.Srv.Store
app.initJobs()
app.Srv.Router.NotFoundHandler = http.HandlerFunc(app.Handle404)
@@ -218,6 +220,10 @@ func (a *App) initEnterprise() {
if dataRetentionInterface != nil {
a.DataRetention = dataRetentionInterface(a)
}
}
func (a *App) initJobs() {
a.Jobs = jobs.NewJobServer(a.Config, a.Srv.Store)
if jobsDataRetentionJobInterface != nil {
a.Jobs.DataRetentionJob = jobsDataRetentionJobInterface(a)
}
@@ -240,6 +246,10 @@ func (a *App) UpdateConfig(f func(*model.Config)) {
f(utils.Cfg)
}
func (a *App) ConfigFileName() string {
return utils.CfgFileName
}
// Go creates a goroutine, but maintains a record of it to ensure that execution completes before
// the app is destroyed.
func (a *App) Go(f func()) {

Просмотреть файл

@@ -25,7 +25,7 @@ func (a *App) CheckPasswordAndAllCriteria(user *model.User, password string, mfa
// This to be used for places we check the users password when they are already logged in
func (a *App) doubleCheckPassword(user *model.User, password string) *model.AppError {
if err := checkUserLoginAttempts(user); err != nil {
if err := checkUserLoginAttempts(user, *a.Config().ServiceSettings.MaximumLoginAttempts); err != nil {
return err
}
@@ -83,15 +83,15 @@ func (a *App) CheckUserAdditionalAuthenticationCriteria(user *model.User, mfaTok
return err
}
if err := checkEmailVerified(user); err != nil {
return err
if !user.EmailVerified && a.Config().EmailSettings.RequireEmailVerification {
return model.NewAppError("Login", "api.user.login.not_verified.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)
}
if err := checkUserNotDisabled(user); err != nil {
return err
}
if err := checkUserLoginAttempts(user); err != nil {
if err := checkUserLoginAttempts(user, *a.Config().ServiceSettings.MaximumLoginAttempts); err != nil {
return err
}
@@ -116,21 +116,14 @@ func (a *App) CheckUserMfa(user *model.User, token string) *model.AppError {
return nil
}
func checkUserLoginAttempts(user *model.User) *model.AppError {
if user.FailedAttempts >= *utils.Cfg.ServiceSettings.MaximumLoginAttempts {
func checkUserLoginAttempts(user *model.User, max int) *model.AppError {
if user.FailedAttempts >= max {
return model.NewAppError("checkUserLoginAttempts", "api.user.check_user_login_attempts.too_many.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)
}
return nil
}
func checkEmailVerified(user *model.User) *model.AppError {
if !user.EmailVerified && utils.Cfg.EmailSettings.RequireEmailVerification {
return model.NewAppError("Login", "api.user.login.not_verified.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)
}
return nil
}
func checkUserNotDisabled(user *model.User) *model.AppError {
if user.DeleteAt > 0 {
return model.NewAppError("Login", "api.user.login.inactive.app_error", nil, "user_id="+user.Id, http.StatusUnauthorized)

Просмотреть файл

@@ -275,7 +275,7 @@ func (a *App) newSession(appName string, user *model.User) (*model.Session, *mod
return nil, model.NewAppError("newSession", "api.oauth.get_access_token.internal_session.app_error", nil, "", http.StatusInternalServerError)
} else {
session = result.Data.(*model.Session)
AddSessionToCache(session)
a.AddSessionToCache(session)
}
return session, nil

Просмотреть файл

@@ -7,7 +7,6 @@ import (
"testing"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
)
func TestOAuthRevokeAccessToken(t *testing.T) {
@@ -50,11 +49,11 @@ func TestOAuthDeleteApp(t *testing.T) {
th := Setup()
defer th.TearDown()
oldSetting := utils.Cfg.ServiceSettings.EnableOAuthServiceProvider
defer func() {
utils.Cfg.ServiceSettings.EnableOAuthServiceProvider = oldSetting
}()
utils.Cfg.ServiceSettings.EnableOAuthServiceProvider = true
oldSetting := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
defer th.App.UpdateConfig(func(cfg *model.Config) {
cfg.ServiceSettings.EnableOAuthServiceProvider = oldSetting
})
th.App.Config().ServiceSettings.EnableOAuthServiceProvider = true
a1 := &model.OAuthApp{}
a1.CreatorId = model.NewId()

Просмотреть файл

@@ -33,7 +33,7 @@ type PluginAPI struct {
}
func (api *PluginAPI) LoadPluginConfiguration(dest interface{}) error {
if b, err := json.Marshal(utils.Cfg.PluginSettings.Plugins[api.id]); err != nil {
if b, err := json.Marshal(api.app.Config().PluginSettings.Plugins[api.id]); err != nil {
return err
} else {
return json.Unmarshal(b, dest)
@@ -145,7 +145,7 @@ type BuiltInPluginAPI struct {
}
func (api *BuiltInPluginAPI) LoadPluginConfiguration(dest interface{}) error {
if b, err := json.Marshal(utils.Cfg.PluginSettings.Plugins[api.id]); err != nil {
if b, err := json.Marshal(api.app.Config().PluginSettings.Plugins[api.id]); err != nil {
return err
} else {
return json.Unmarshal(b, dest)

Просмотреть файл

@@ -52,59 +52,56 @@ func WriteSamlFile(fileData *multipart.FileHeader) *model.AppError {
return nil
}
func AddSamlPublicCertificate(fileData *multipart.FileHeader) *model.AppError {
func (a *App) AddSamlPublicCertificate(fileData *multipart.FileHeader) *model.AppError {
if err := WriteSamlFile(fileData); err != nil {
return err
}
cfg := &model.Config{}
*cfg = *utils.Cfg
cfg := a.Config().Clone()
*cfg.SamlSettings.PublicCertificateFile = fileData.Filename
if err := cfg.IsValid(); err != nil {
return err
}
utils.SaveConfig(utils.CfgFileName, cfg)
a.UpdateConfig(func(dest *model.Config) { *dest = *cfg })
utils.SaveConfig(a.ConfigFileName(), cfg)
return nil
}
func AddSamlPrivateCertificate(fileData *multipart.FileHeader) *model.AppError {
func (a *App) AddSamlPrivateCertificate(fileData *multipart.FileHeader) *model.AppError {
if err := WriteSamlFile(fileData); err != nil {
return err
}
cfg := &model.Config{}
*cfg = *utils.Cfg
cfg := a.Config().Clone()
*cfg.SamlSettings.PrivateKeyFile = fileData.Filename
if err := cfg.IsValid(); err != nil {
return err
}
utils.SaveConfig(utils.CfgFileName, cfg)
a.UpdateConfig(func(dest *model.Config) { *dest = *cfg })
utils.SaveConfig(a.ConfigFileName(), cfg)
return nil
}
func AddSamlIdpCertificate(fileData *multipart.FileHeader) *model.AppError {
func (a *App) AddSamlIdpCertificate(fileData *multipart.FileHeader) *model.AppError {
if err := WriteSamlFile(fileData); err != nil {
return err
}
cfg := &model.Config{}
*cfg = *utils.Cfg
cfg := a.Config().Clone()
*cfg.SamlSettings.IdpCertificateFile = fileData.Filename
if err := cfg.IsValid(); err != nil {
return err
}
utils.SaveConfig(utils.CfgFileName, cfg)
a.UpdateConfig(func(dest *model.Config) { *dest = *cfg })
utils.SaveConfig(a.ConfigFileName(), cfg)
return nil
}
@@ -123,14 +120,12 @@ func RemoveSamlFile(filename string) *model.AppError {
return nil
}
func RemoveSamlPublicCertificate() *model.AppError {
if err := RemoveSamlFile(*utils.Cfg.SamlSettings.PublicCertificateFile); err != nil {
func (a *App) RemoveSamlPublicCertificate() *model.AppError {
if err := RemoveSamlFile(*a.Config().SamlSettings.PublicCertificateFile); err != nil {
return err
}
cfg := &model.Config{}
*cfg = *utils.Cfg
cfg := a.Config().Clone()
*cfg.SamlSettings.PublicCertificateFile = ""
*cfg.SamlSettings.Encrypt = false
@@ -138,19 +133,18 @@ func RemoveSamlPublicCertificate() *model.AppError {
return err
}
utils.SaveConfig(utils.CfgFileName, cfg)
a.UpdateConfig(func(dest *model.Config) { *dest = *cfg })
utils.SaveConfig(a.ConfigFileName(), cfg)
return nil
}
func RemoveSamlPrivateCertificate() *model.AppError {
if err := RemoveSamlFile(*utils.Cfg.SamlSettings.PrivateKeyFile); err != nil {
func (a *App) RemoveSamlPrivateCertificate() *model.AppError {
if err := RemoveSamlFile(*a.Config().SamlSettings.PrivateKeyFile); err != nil {
return err
}
cfg := &model.Config{}
*cfg = *utils.Cfg
cfg := a.Config().Clone()
*cfg.SamlSettings.PrivateKeyFile = ""
*cfg.SamlSettings.Encrypt = false
@@ -158,19 +152,18 @@ func RemoveSamlPrivateCertificate() *model.AppError {
return err
}
utils.SaveConfig(utils.CfgFileName, cfg)
a.UpdateConfig(func(dest *model.Config) { *dest = *cfg })
utils.SaveConfig(a.ConfigFileName(), cfg)
return nil
}
func RemoveSamlIdpCertificate() *model.AppError {
if err := RemoveSamlFile(*utils.Cfg.SamlSettings.IdpCertificateFile); err != nil {
func (a *App) RemoveSamlIdpCertificate() *model.AppError {
if err := RemoveSamlFile(*a.Config().SamlSettings.IdpCertificateFile); err != nil {
return err
}
cfg := &model.Config{}
*cfg = *utils.Cfg
cfg := a.Config().Clone()
*cfg.SamlSettings.IdpCertificateFile = ""
*cfg.SamlSettings.Enable = false
@@ -178,17 +171,18 @@ func RemoveSamlIdpCertificate() *model.AppError {
return err
}
utils.SaveConfig(utils.CfgFileName, cfg)
a.UpdateConfig(func(dest *model.Config) { *dest = *cfg })
utils.SaveConfig(a.ConfigFileName(), cfg)
return nil
}
func GetSamlCertificateStatus() *model.SamlCertificateStatus {
func (a *App) GetSamlCertificateStatus() *model.SamlCertificateStatus {
status := &model.SamlCertificateStatus{}
status.IdpCertificateFile = utils.FileExistsInConfigFolder(*utils.Cfg.SamlSettings.IdpCertificateFile)
status.PrivateKeyFile = utils.FileExistsInConfigFolder(*utils.Cfg.SamlSettings.PrivateKeyFile)
status.PublicCertificateFile = utils.FileExistsInConfigFolder(*utils.Cfg.SamlSettings.PublicCertificateFile)
status.IdpCertificateFile = utils.FileExistsInConfigFolder(*a.Config().SamlSettings.IdpCertificateFile)
status.PrivateKeyFile = utils.FileExistsInConfigFolder(*a.Config().SamlSettings.PrivateKeyFile)
status.PublicCertificateFile = utils.FileExistsInConfigFolder(*a.Config().SamlSettings.PublicCertificateFile)
return status
}

Просмотреть файл

@@ -53,11 +53,12 @@ func (rl *RecoveryLogger) Println(i ...interface{}) {
}
type CorsWrapper struct {
config model.ConfigFunc
router *mux.Router
}
func (cw *CorsWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(*utils.Cfg.ServiceSettings.AllowCorsFrom) > 0 {
if len(*cw.config().ServiceSettings.AllowCorsFrom) > 0 {
if utils.OriginChecker(r) {
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
@@ -88,25 +89,6 @@ func (m *VaryBy) Key(r *http.Request) string {
return utils.GetIpAddress(r)
}
func initalizeThrottledVaryBy() *throttled.VaryBy {
vary := throttled.VaryBy{}
if utils.Cfg.RateLimitSettings.VaryByRemoteAddr {
vary.RemoteAddr = true
}
if len(utils.Cfg.RateLimitSettings.VaryByHeader) > 0 {
vary.Headers = strings.Fields(utils.Cfg.RateLimitSettings.VaryByHeader)
if utils.Cfg.RateLimitSettings.VaryByRemoteAddr {
l4g.Warn(utils.T("api.server.start_server.rate.warn"))
vary.RemoteAddr = false
}
}
return &vary
}
func redirectHTTPToHTTPS(w http.ResponseWriter, r *http.Request) {
if r.Host == "" {
http.Error(w, "Not Found", http.StatusNotFound)
@@ -121,7 +103,7 @@ func redirectHTTPToHTTPS(w http.ResponseWriter, r *http.Request) {
func (a *App) StartServer() {
l4g.Info(utils.T("api.server.start_server.starting.info"))
var handler http.Handler = &CorsWrapper{a.Srv.Router}
var handler http.Handler = &CorsWrapper{a.Config, a.Srv.Router}
if *a.Config().RateLimitSettings.Enable {
l4g.Info(utils.T("api.server.start_server.rate.info"))

Просмотреть файл

@@ -12,8 +12,6 @@ import (
l4g "github.com/alecthomas/log4go"
)
var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE)
func (a *App) CreateSession(session *model.Session) (*model.Session, *model.AppError) {
session.Token = ""
@@ -22,7 +20,7 @@ func (a *App) CreateSession(session *model.Session) (*model.Session, *model.AppE
} else {
session := result.Data.(*model.Session)
AddSessionToCache(session)
a.AddSessionToCache(session)
return session, nil
}
@@ -32,7 +30,7 @@ func (a *App) GetSession(token string) (*model.Session, *model.AppError) {
metrics := a.Metrics
var session *model.Session
if ts, ok := sessionCache.Get(token); ok {
if ts, ok := a.sessionCache.Get(token); ok {
session = ts.(*model.Session)
if metrics != nil {
metrics.IncrementMemCacheHitCounterSession()
@@ -53,7 +51,7 @@ func (a *App) GetSession(token string) (*model.Session, *model.AppError) {
}
if !session.IsExpired() {
AddSessionToCache(session)
a.AddSessionToCache(session)
}
}
}
@@ -132,13 +130,13 @@ func (a *App) ClearSessionCacheForUser(userId string) {
}
func (a *App) ClearSessionCacheForUserSkipClusterSend(userId string) {
keys := sessionCache.Keys()
keys := a.sessionCache.Keys()
for _, key := range keys {
if ts, ok := sessionCache.Get(key); ok {
if ts, ok := a.sessionCache.Get(key); ok {
session := ts.(*model.Session)
if session.UserId == userId {
sessionCache.Remove(key)
a.sessionCache.Remove(key)
}
}
}
@@ -146,12 +144,12 @@ func (a *App) ClearSessionCacheForUserSkipClusterSend(userId string) {
a.InvalidateWebConnSessionCacheForUser(userId)
}
func AddSessionToCache(session *model.Session) {
sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*utils.Cfg.ServiceSettings.SessionCacheInMinutes*60))
func (a *App) AddSessionToCache(session *model.Session) {
a.sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*a.Config().ServiceSettings.SessionCacheInMinutes*60))
}
func SessionCacheLength() int {
return sessionCache.Len()
func (a *App) SessionCacheLength() int {
return a.sessionCache.Len()
}
func (a *App) RevokeSessionsForDeviceId(userId string, deviceId string, currentSessionId string) *model.AppError {
@@ -227,7 +225,7 @@ func (a *App) UpdateLastActivityAtIfNeeded(session model.Session) {
}
session.LastActivityAt = now
AddSessionToCache(&session)
a.AddSessionToCache(&session)
}
func (a *App) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) {
@@ -301,7 +299,7 @@ func (a *App) createSessionForUserAccessToken(tokenString string) (*model.Sessio
} else {
session := result.Data.(*model.Session)
AddSessionToCache(session)
a.AddSessionToCache(session)
return session, nil
}

Просмотреть файл

@@ -23,16 +23,16 @@ func TestCache(t *testing.T) {
UserId: model.NewId(),
}
sessionCache.AddWithExpiresInSecs(session.Token, session, 5*60)
th.App.sessionCache.AddWithExpiresInSecs(session.Token, session, 5*60)
keys := sessionCache.Keys()
keys := th.App.sessionCache.Keys()
if len(keys) <= 0 {
t.Fatal("should have items")
}
th.App.ClearSessionCacheForUser(session.UserId)
rkeys := sessionCache.Keys()
rkeys := th.App.sessionCache.Keys()
if len(rkeys) != len(keys)-1 {
t.Fatal("should have one less")
}

Просмотреть файл

@@ -159,7 +159,7 @@ func IsUserSignUpAllowed() *model.AppError {
}
func (a *App) IsFirstUserAccount() bool {
if SessionCacheLength() == 0 {
if a.SessionCacheLength() == 0 {
if cr := <-a.Srv.Store.User().GetTotalUsersCount(); cr.Err != nil {
l4g.Error(cr.Err)
return false

Просмотреть файл

@@ -87,11 +87,11 @@ func TestCreateOAuthUser(t *testing.T) {
th.App.PermanentDeleteUser(user)
userCreation := utils.Cfg.TeamSettings.EnableUserCreation
defer func() {
utils.Cfg.TeamSettings.EnableUserCreation = userCreation
}()
utils.Cfg.TeamSettings.EnableUserCreation = false
userCreation := th.App.Config().TeamSettings.EnableUserCreation
defer th.App.UpdateConfig(func(cfg *model.Config) {
cfg.TeamSettings.EnableUserCreation = userCreation
})
th.App.Config().TeamSettings.EnableUserCreation = false
_, err = th.App.CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id)
if err == nil {