Add system setting table with cache and also add cache supports for user setting (#18058)

This commit is contained in:
Lunny Xiao
2022-10-17 07:29:26 +08:00
committed by GitHub
parent 5d3dbffa15
commit f860a6d2e4
59 changed files with 1117 additions and 436 deletions

View File

@ -11,8 +11,10 @@ import (
"time"
repo_model "code.gitea.io/gitea/models/repo"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
@ -100,6 +102,14 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) {
assert.EqualValues(t, []string{"readme.md"}, headCommit.Modified)
}
func enableGravatar(t *testing.T) {
err := system_model.SetSettingNoVersion(system_model.KeyPictureDisableGravatar, "false")
assert.NoError(t, err)
setting.GravatarSource = "https://secure.gravatar.com/avatar"
err = system_model.Init()
assert.NoError(t, err)
}
func TestPushCommits_AvatarLink(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
@ -123,6 +133,8 @@ func TestPushCommits_AvatarLink(t *testing.T) {
},
}
enableGravatar(t)
assert.Equal(t,
"https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=84",
pushCommits.AvatarLink("user2@example.com"))

View File

@ -4,14 +4,6 @@
package setting
import (
"net/url"
"code.gitea.io/gitea/modules/log"
"strk.kbt.io/projects/go/libravatar"
)
// settings
var (
// Picture settings
@ -30,10 +22,8 @@ var (
}
GravatarSource string
GravatarSourceURL *url.URL
DisableGravatar bool
EnableFederatedAvatar bool
LibravatarService *libravatar.Libravatar
DisableGravatar bool // Depreciated: migrated to database
EnableFederatedAvatar bool // Depreciated: migrated to database
RepoAvatar = struct {
Storage
@ -69,38 +59,30 @@ func newPictureService() {
default:
GravatarSource = source
}
DisableGravatar = sec.Key("DISABLE_GRAVATAR").MustBool()
EnableFederatedAvatar = sec.Key("ENABLE_FEDERATED_AVATAR").MustBool(!InstallLock)
if OfflineMode {
DisableGravatar = true
EnableFederatedAvatar = false
}
if DisableGravatar {
EnableFederatedAvatar = false
}
if EnableFederatedAvatar || !DisableGravatar {
var err error
GravatarSourceURL, err = url.Parse(GravatarSource)
if err != nil {
log.Fatal("Failed to parse Gravatar URL(%s): %v",
GravatarSource, err)
}
}
if EnableFederatedAvatar {
LibravatarService = libravatar.New()
if GravatarSourceURL.Scheme == "https" {
LibravatarService.SetUseHTTPS(true)
LibravatarService.SetSecureFallbackHost(GravatarSourceURL.Host)
} else {
LibravatarService.SetUseHTTPS(false)
LibravatarService.SetFallbackHost(GravatarSourceURL.Host)
}
}
DisableGravatar = sec.Key("DISABLE_GRAVATAR").MustBool(GetDefaultDisableGravatar())
deprecatedSettingDB("", "DISABLE_GRAVATAR")
EnableFederatedAvatar = sec.Key("ENABLE_FEDERATED_AVATAR").MustBool(GetDefaultEnableFederatedAvatar(DisableGravatar))
deprecatedSettingDB("", "ENABLE_FEDERATED_AVATAR")
newRepoAvatarService()
}
func GetDefaultDisableGravatar() bool {
return !OfflineMode
}
func GetDefaultEnableFederatedAvatar(disableGravatar bool) bool {
v := !InstallLock
if OfflineMode {
v = false
}
if disableGravatar {
v = false
}
return v
}
func newRepoAvatarService() {
sec := Cfg.Section("picture")

View File

@ -606,6 +606,13 @@ func deprecatedSetting(oldSection, oldKey, newSection, newKey string) {
}
}
// deprecatedSettingDB add a hint that the configuration has been moved to database but still kept in app.ini
func deprecatedSettingDB(oldSection, oldKey string) {
if Cfg.Section(oldSection).HasKey(oldKey) {
log.Error("Deprecated `[%s]` `%s` present which has been copied to database table sys_setting", oldSection, oldKey)
}
}
// loadFromConf initializes configuration context.
// NOTE: do not print any log except error.
func loadFromConf(allowEmpty bool, extraConfig string) {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package appstate
package system
// StateStore is the interface to get/set app state items
type StateStore interface {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package appstate
package system
import (
"path/filepath"

View File

@ -2,10 +2,10 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package appstate
package system
import (
"code.gitea.io/gitea/models/appstate"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/json"
"github.com/yuin/goldmark/util"
@ -16,7 +16,7 @@ type DBStore struct{}
// Get reads the state item
func (f *DBStore) Get(item StateItem) error {
content, err := appstate.GetAppStateContent(item.Name())
content, err := system.GetAppStateContent(item.Name())
if err != nil {
return err
}
@ -32,5 +32,5 @@ func (f *DBStore) Set(item StateItem) error {
if err != nil {
return err
}
return appstate.SaveAppStateContent(item.Name(), util.BytesToReadOnlyString(b))
return system.SaveAppStateContent(item.Name(), util.BytesToReadOnlyString(b))
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package appstate
package system
// RuntimeState contains app state for runtime, and we can save remote version for update checker here in future
type RuntimeState struct {

46
modules/system/setting.go Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package system
import (
"strconv"
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/cache"
)
func genKey(key string) string {
return "system.setting." + key
}
// GetSetting returns the setting value via the key
func GetSetting(key string) (string, error) {
return cache.GetString(genKey(key), func() (string, error) {
res, err := system.GetSetting(key)
if err != nil {
return "", err
}
return res.SettingValue, nil
})
}
// GetSettingBool return bool value of setting,
// none existing keys and errors are ignored and result in false
func GetSettingBool(key string) bool {
s, _ := GetSetting(key)
b, _ := strconv.ParseBool(s)
return b
}
// SetSetting sets the setting value
func SetSetting(key, value string, version int) error {
cache.Remove(genKey(key))
return system.SetSetting(&system.Setting{
SettingKey: key,
SettingValue: value,
Version: version,
})
}

View File

@ -0,0 +1,34 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package system
import (
"fmt"
"code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
)
func genUserKey(userID int64, key string) string {
return fmt.Sprintf("user_%d.setting.%s", userID, key)
}
// GetUserSetting returns the user setting value via the key
func GetUserSetting(userID int64, key string) (string, error) {
return cache.GetString(genUserKey(userID, key), func() (string, error) {
res, err := user.GetSetting(userID, key)
if err != nil {
return "", err
}
return res.SettingValue, nil
})
}
// SetUserSetting sets the user setting value
func SetUserSetting(userID int64, key, value string) error {
cache.Remove(genUserKey(userID, key))
return user.SetUserSetting(userID, key, value)
}

View File

@ -29,6 +29,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo"
system_model "code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/emoji"
@ -41,6 +42,7 @@ import (
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/svg"
system_module "code.gitea.io/gitea/modules/system"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/gitdiff"
@ -85,7 +87,7 @@ func NewFuncMap() []template.FuncMap {
return setting.AssetVersion
},
"DisableGravatar": func() bool {
return setting.DisableGravatar
return system_module.GetSettingBool(system_model.KeyPictureDisableGravatar)
},
"DefaultShowFullName": func() bool {
return setting.UI.DefaultShowFullName

View File

@ -8,10 +8,10 @@ import (
"io"
"net/http"
"code.gitea.io/gitea/modules/appstate"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/proxy"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/system"
"github.com/hashicorp/go-version"
)
@ -64,13 +64,13 @@ func GiteaUpdateChecker(httpEndpoint string) error {
// UpdateRemoteVersion updates the latest available version of Gitea
func UpdateRemoteVersion(version string) (err error) {
return appstate.AppState.Set(&CheckerState{LatestVersion: version})
return system.AppState.Set(&CheckerState{LatestVersion: version})
}
// GetRemoteVersion returns the current remote version (or currently installed version if fail to fetch from DB)
func GetRemoteVersion() string {
item := new(CheckerState)
if err := appstate.AppState.Get(item); err != nil {
if err := system.AppState.Get(item); err != nil {
return ""
}
return item.LatestVersion