aboutsummaryrefslogtreecommitdiffstats
path: root/modules/setting
diff options
context:
space:
mode:
Diffstat (limited to 'modules/setting')
-rw-r--r--modules/setting/actions_test.go26
-rw-r--r--modules/setting/api.go2
-rw-r--r--modules/setting/attachment_test.go22
-rw-r--r--modules/setting/config_env.go2
-rw-r--r--modules/setting/config_env_test.go21
-rw-r--r--modules/setting/config_provider.go5
-rw-r--r--modules/setting/config_provider_test.go8
-rw-r--r--modules/setting/cron_test.go2
-rw-r--r--modules/setting/git_test.go24
-rw-r--r--modules/setting/global_lock_test.go6
-rw-r--r--modules/setting/incoming_email.go3
-rw-r--r--modules/setting/indexer.go2
-rw-r--r--modules/setting/lfs_test.go22
-rw-r--r--modules/setting/log.go7
-rw-r--r--modules/setting/mailer_test.go4
-rw-r--r--modules/setting/markup.go90
-rw-r--r--modules/setting/markup_test.go51
-rw-r--r--modules/setting/mirror.go6
-rw-r--r--modules/setting/oauth2_test.go2
-rw-r--r--modules/setting/packages.go18
-rw-r--r--modules/setting/packages_test.go24
-rw-r--r--modules/setting/path.go16
-rw-r--r--modules/setting/repository.go33
-rw-r--r--modules/setting/repository_archive_test.go12
-rw-r--r--modules/setting/security.go12
-rw-r--r--modules/setting/server.go60
-rw-r--r--modules/setting/service.go33
-rw-r--r--modules/setting/service_test.go41
-rw-r--r--modules/setting/setting.go4
-rw-r--r--modules/setting/ssh.go35
-rw-r--r--modules/setting/storage.go18
-rw-r--r--modules/setting/storage_test.go126
32 files changed, 467 insertions, 270 deletions
diff --git a/modules/setting/actions_test.go b/modules/setting/actions_test.go
index 3645a3f5da..353cc657fa 100644
--- a/modules/setting/actions_test.go
+++ b/modules/setting/actions_test.go
@@ -21,9 +21,9 @@ func Test_getStorageInheritNameSectionTypeForActions(t *testing.T) {
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "minio", Actions.LogStorage.Type)
- assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
+ assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
+ assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
iniStr = `
[storage.actions_log]
@@ -34,9 +34,9 @@ STORAGE_TYPE = minio
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "minio", Actions.LogStorage.Type)
- assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
+ assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
assert.EqualValues(t, "local", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
+ assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
iniStr = `
[storage.actions_log]
@@ -50,9 +50,9 @@ STORAGE_TYPE = minio
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "minio", Actions.LogStorage.Type)
- assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
+ assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
assert.EqualValues(t, "local", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
+ assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
iniStr = `
[storage.actions_artifacts]
@@ -66,9 +66,9 @@ STORAGE_TYPE = minio
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "local", Actions.LogStorage.Type)
- assert.EqualValues(t, "actions_log", filepath.Base(Actions.LogStorage.Path))
+ assert.Equal(t, "actions_log", filepath.Base(Actions.LogStorage.Path))
assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
+ assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
iniStr = `
[storage.actions_artifacts]
@@ -82,9 +82,9 @@ STORAGE_TYPE = minio
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "local", Actions.LogStorage.Type)
- assert.EqualValues(t, "actions_log", filepath.Base(Actions.LogStorage.Path))
+ assert.Equal(t, "actions_log", filepath.Base(Actions.LogStorage.Path))
assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
+ assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
iniStr = ``
cfg, err = NewConfigProviderFromData(iniStr)
@@ -92,9 +92,9 @@ STORAGE_TYPE = minio
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "local", Actions.LogStorage.Type)
- assert.EqualValues(t, "actions_log", filepath.Base(Actions.LogStorage.Path))
+ assert.Equal(t, "actions_log", filepath.Base(Actions.LogStorage.Path))
assert.EqualValues(t, "local", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
+ assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
}
func Test_getDefaultActionsURLForActions(t *testing.T) {
@@ -175,7 +175,7 @@ DEFAULT_ACTIONS_URL = gitea
if !tt.wantErr(t, loadActionsFrom(cfg)) {
return
}
- assert.EqualValues(t, tt.wantURL, Actions.DefaultActionsURL.URL())
+ assert.Equal(t, tt.wantURL, Actions.DefaultActionsURL.URL())
})
}
}
diff --git a/modules/setting/api.go b/modules/setting/api.go
index c36f05cfd1..cdad474cb9 100644
--- a/modules/setting/api.go
+++ b/modules/setting/api.go
@@ -18,6 +18,7 @@ var API = struct {
DefaultPagingNum int
DefaultGitTreesPerPage int
DefaultMaxBlobSize int64
+ DefaultMaxResponseSize int64
}{
EnableSwagger: true,
SwaggerURL: "",
@@ -25,6 +26,7 @@ var API = struct {
DefaultPagingNum: 30,
DefaultGitTreesPerPage: 1000,
DefaultMaxBlobSize: 10485760,
+ DefaultMaxResponseSize: 104857600,
}
func loadAPIFrom(rootCfg ConfigProvider) {
diff --git a/modules/setting/attachment_test.go b/modules/setting/attachment_test.go
index 3e8d2da4d9..c566dfa60c 100644
--- a/modules/setting/attachment_test.go
+++ b/modules/setting/attachment_test.go
@@ -25,9 +25,9 @@ MINIO_ENDPOINT = my_minio:9000
assert.NoError(t, loadAttachmentFrom(cfg))
assert.EqualValues(t, "minio", Attachment.Storage.Type)
- assert.EqualValues(t, "my_minio:9000", Attachment.Storage.MinioConfig.Endpoint)
- assert.EqualValues(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "my_minio:9000", Attachment.Storage.MinioConfig.Endpoint)
+ assert.Equal(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
}
func Test_getStorageTypeSectionOverridesStorageSection(t *testing.T) {
@@ -47,8 +47,8 @@ MINIO_BUCKET = gitea
assert.NoError(t, loadAttachmentFrom(cfg))
assert.EqualValues(t, "minio", Attachment.Storage.Type)
- assert.EqualValues(t, "gitea-minio", Attachment.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-minio", Attachment.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
}
func Test_getStorageSpecificOverridesStorage(t *testing.T) {
@@ -69,8 +69,8 @@ STORAGE_TYPE = local
assert.NoError(t, loadAttachmentFrom(cfg))
assert.EqualValues(t, "minio", Attachment.Storage.Type)
- assert.EqualValues(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
}
func Test_getStorageGetDefaults(t *testing.T) {
@@ -80,7 +80,7 @@ func Test_getStorageGetDefaults(t *testing.T) {
assert.NoError(t, loadAttachmentFrom(cfg))
// default storage is local, so bucket is empty
- assert.EqualValues(t, "", Attachment.Storage.MinioConfig.Bucket)
+ assert.Empty(t, Attachment.Storage.MinioConfig.Bucket)
}
func Test_getStorageInheritNameSectionType(t *testing.T) {
@@ -115,7 +115,7 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage := Attachment.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
}
func Test_AttachmentStorage1(t *testing.T) {
@@ -128,6 +128,6 @@ STORAGE_TYPE = minio
assert.NoError(t, loadAttachmentFrom(cfg))
assert.EqualValues(t, "minio", Attachment.Storage.Type)
- assert.EqualValues(t, "gitea", Attachment.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", Attachment.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
}
diff --git a/modules/setting/config_env.go b/modules/setting/config_env.go
index 5d94a9641f..409588dc44 100644
--- a/modules/setting/config_env.go
+++ b/modules/setting/config_env.go
@@ -97,7 +97,7 @@ func decodeEnvSectionKey(encoded string) (ok bool, section, key string) {
// decodeEnvironmentKey decode the environment key to section and key
// The environment key is in the form of GITEA__SECTION__KEY or GITEA__SECTION__KEY__FILE
-func decodeEnvironmentKey(prefixGitea, suffixFile, envKey string) (ok bool, section, key string, useFileValue bool) { //nolint:unparam
+func decodeEnvironmentKey(prefixGitea, suffixFile, envKey string) (ok bool, section, key string, useFileValue bool) {
if !strings.HasPrefix(envKey, prefixGitea) {
return false, "", "", false
}
diff --git a/modules/setting/config_env_test.go b/modules/setting/config_env_test.go
index 7d07c479a1..7d270ac21a 100644
--- a/modules/setting/config_env_test.go
+++ b/modules/setting/config_env_test.go
@@ -28,8 +28,8 @@ func TestDecodeEnvSectionKey(t *testing.T) {
ok, section, key = decodeEnvSectionKey("SEC")
assert.False(t, ok)
- assert.Equal(t, "", section)
- assert.Equal(t, "", key)
+ assert.Empty(t, section)
+ assert.Empty(t, key)
}
func TestDecodeEnvironmentKey(t *testing.T) {
@@ -38,19 +38,19 @@ func TestDecodeEnvironmentKey(t *testing.T) {
ok, section, key, file := decodeEnvironmentKey(prefix, suffix, "SEC__KEY")
assert.False(t, ok)
- assert.Equal(t, "", section)
- assert.Equal(t, "", key)
+ assert.Empty(t, section)
+ assert.Empty(t, key)
assert.False(t, file)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC")
assert.False(t, ok)
- assert.Equal(t, "", section)
- assert.Equal(t, "", key)
+ assert.Empty(t, section)
+ assert.Empty(t, key)
assert.False(t, file)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA____KEY")
assert.True(t, ok)
- assert.Equal(t, "", section)
+ assert.Empty(t, section)
assert.Equal(t, "KEY", key)
assert.False(t, file)
@@ -64,8 +64,8 @@ func TestDecodeEnvironmentKey(t *testing.T) {
// but it could be fixed in the future by adding a new suffix like "__VALUE" (no such key VALUE is used in Gitea either)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__FILE")
assert.False(t, ok)
- assert.Equal(t, "", section)
- assert.Equal(t, "", key)
+ assert.Empty(t, section)
+ assert.Empty(t, key)
assert.True(t, file)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__KEY__FILE")
@@ -73,6 +73,9 @@ func TestDecodeEnvironmentKey(t *testing.T) {
assert.Equal(t, "sec", section)
assert.Equal(t, "KEY", key)
assert.True(t, file)
+
+ ok, _, _, _ = decodeEnvironmentKey("PREFIX__", "", "PREFIX__SEC__KEY")
+ assert.True(t, ok)
}
func TestEnvironmentToConfig(t *testing.T) {
diff --git a/modules/setting/config_provider.go b/modules/setting/config_provider.go
index 3138f8a63e..09eaaefdaf 100644
--- a/modules/setting/config_provider.go
+++ b/modules/setting/config_provider.go
@@ -15,7 +15,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
- "gopkg.in/ini.v1" //nolint:depguard
+ "gopkg.in/ini.v1" //nolint:depguard // wrapper for this package
)
type ConfigKey interface {
@@ -26,6 +26,7 @@ type ConfigKey interface {
In(defaultVal string, candidates []string) string
String() string
Strings(delim string) []string
+ Bool() (bool, error)
MustString(defaultVal string) string
MustBool(defaultVal ...bool) bool
@@ -257,7 +258,7 @@ func (p *iniConfigProvider) Save() error {
}
filename := p.file
if filename == "" {
- return fmt.Errorf("config file path must not be empty")
+ return errors.New("config file path must not be empty")
}
if p.loadedFromEmpty {
if err := os.MkdirAll(filepath.Dir(filename), os.ModePerm); err != nil {
diff --git a/modules/setting/config_provider_test.go b/modules/setting/config_provider_test.go
index a666d124c7..63121f0074 100644
--- a/modules/setting/config_provider_test.go
+++ b/modules/setting/config_provider_test.go
@@ -62,17 +62,17 @@ key = 123
// test default behavior
assert.Equal(t, "123", ConfigSectionKeyString(sec, "key"))
- assert.Equal(t, "", ConfigSectionKeyString(secSub, "key"))
+ assert.Empty(t, ConfigSectionKeyString(secSub, "key"))
assert.Equal(t, "def", ConfigSectionKeyString(secSub, "key", "def"))
assert.Equal(t, "123", ConfigInheritedKeyString(secSub, "key"))
// Workaround for ini package's BuggyKeyOverwritten behavior
- assert.Equal(t, "", ConfigSectionKeyString(sec, "empty"))
- assert.Equal(t, "", ConfigSectionKeyString(secSub, "empty"))
+ assert.Empty(t, ConfigSectionKeyString(sec, "empty"))
+ assert.Empty(t, ConfigSectionKeyString(secSub, "empty"))
assert.Equal(t, "def", ConfigInheritedKey(secSub, "empty").MustString("def"))
assert.Equal(t, "def", ConfigInheritedKey(secSub, "empty").MustString("xyz"))
- assert.Equal(t, "", ConfigSectionKeyString(sec, "empty"))
+ assert.Empty(t, ConfigSectionKeyString(sec, "empty"))
assert.Equal(t, "def", ConfigSectionKeyString(secSub, "empty"))
}
diff --git a/modules/setting/cron_test.go b/modules/setting/cron_test.go
index 55244d7075..39a228068a 100644
--- a/modules/setting/cron_test.go
+++ b/modules/setting/cron_test.go
@@ -38,6 +38,6 @@ EXTEND = true
_, err = getCronSettings(cfg, "test", extended)
assert.NoError(t, err)
assert.True(t, extended.Base)
- assert.EqualValues(t, "white rabbit", extended.Second)
+ assert.Equal(t, "white rabbit", extended.Second)
assert.True(t, extended.Extend)
}
diff --git a/modules/setting/git_test.go b/modules/setting/git_test.go
index 441c514d8c..0d7f634abf 100644
--- a/modules/setting/git_test.go
+++ b/modules/setting/git_test.go
@@ -6,6 +6,8 @@ package setting
import (
"testing"
+ "code.gitea.io/gitea/modules/test"
+
"github.com/stretchr/testify/assert"
)
@@ -23,8 +25,8 @@ a.b = 1
`)
assert.NoError(t, err)
loadGitFrom(cfg)
- assert.EqualValues(t, "1", GitConfig.Options["a.b"])
- assert.EqualValues(t, "histogram", GitConfig.Options["diff.algorithm"])
+ assert.Equal(t, "1", GitConfig.Options["a.b"])
+ assert.Equal(t, "histogram", GitConfig.Options["diff.algorithm"])
cfg, err = NewConfigProviderFromData(`
[git.config]
@@ -32,24 +34,20 @@ diff.algorithm = other
`)
assert.NoError(t, err)
loadGitFrom(cfg)
- assert.EqualValues(t, "other", GitConfig.Options["diff.algorithm"])
+ assert.Equal(t, "other", GitConfig.Options["diff.algorithm"])
}
func TestGitReflog(t *testing.T) {
- oldGit := Git
- oldGitConfig := GitConfig
- defer func() {
- Git = oldGit
- GitConfig = oldGitConfig
- }()
+ defer test.MockVariableValue(&Git)
+ defer test.MockVariableValue(&GitConfig)
// default reflog config without legacy options
cfg, err := NewConfigProviderFromData(``)
assert.NoError(t, err)
loadGitFrom(cfg)
- assert.EqualValues(t, "true", GitConfig.GetOption("core.logAllRefUpdates"))
- assert.EqualValues(t, "90", GitConfig.GetOption("gc.reflogExpire"))
+ assert.Equal(t, "true", GitConfig.GetOption("core.logAllRefUpdates"))
+ assert.Equal(t, "90", GitConfig.GetOption("gc.reflogExpire"))
// custom reflog config by legacy options
cfg, err = NewConfigProviderFromData(`
@@ -60,6 +58,6 @@ EXPIRATION = 123
assert.NoError(t, err)
loadGitFrom(cfg)
- assert.EqualValues(t, "false", GitConfig.GetOption("core.logAllRefUpdates"))
- assert.EqualValues(t, "123", GitConfig.GetOption("gc.reflogExpire"))
+ assert.Equal(t, "false", GitConfig.GetOption("core.logAllRefUpdates"))
+ assert.Equal(t, "123", GitConfig.GetOption("gc.reflogExpire"))
}
diff --git a/modules/setting/global_lock_test.go b/modules/setting/global_lock_test.go
index 5eeb275523..5e15eb3483 100644
--- a/modules/setting/global_lock_test.go
+++ b/modules/setting/global_lock_test.go
@@ -16,7 +16,7 @@ func TestLoadGlobalLockConfig(t *testing.T) {
assert.NoError(t, err)
loadGlobalLockFrom(cfg)
- assert.EqualValues(t, "memory", GlobalLock.ServiceType)
+ assert.Equal(t, "memory", GlobalLock.ServiceType)
})
t.Run("RedisGlobalLockConfig", func(t *testing.T) {
@@ -29,7 +29,7 @@ SERVICE_CONN_STR = addrs=127.0.0.1:6379 db=0
assert.NoError(t, err)
loadGlobalLockFrom(cfg)
- assert.EqualValues(t, "redis", GlobalLock.ServiceType)
- assert.EqualValues(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr)
+ assert.Equal(t, "redis", GlobalLock.ServiceType)
+ assert.Equal(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr)
})
}
diff --git a/modules/setting/incoming_email.go b/modules/setting/incoming_email.go
index bf81f292a2..4e433dde60 100644
--- a/modules/setting/incoming_email.go
+++ b/modules/setting/incoming_email.go
@@ -4,6 +4,7 @@
package setting
import (
+ "errors"
"fmt"
"net/mail"
"strings"
@@ -50,7 +51,7 @@ func checkReplyToAddress() error {
}
if parsed.Name != "" {
- return fmt.Errorf("name must not be set")
+ return errors.New("name must not be set")
}
c := strings.Count(IncomingEmail.ReplyToAddress, IncomingEmail.TokenPlaceholder)
diff --git a/modules/setting/indexer.go b/modules/setting/indexer.go
index e34baae012..ace7eec70e 100644
--- a/modules/setting/indexer.go
+++ b/modules/setting/indexer.go
@@ -96,7 +96,7 @@ func loadIndexerFrom(rootCfg ConfigProvider) {
// IndexerGlobFromString parses a comma separated list of patterns and returns a glob.Glob slice suited for repo indexing
func IndexerGlobFromString(globstr string) []*GlobMatcher {
extarr := make([]*GlobMatcher, 0, 10)
- for _, expr := range strings.Split(strings.ToLower(globstr), ",") {
+ for expr := range strings.SplitSeq(strings.ToLower(globstr), ",") {
expr = strings.TrimSpace(expr)
if expr != "" {
if g, err := GlobMatcherCompile(expr, '.', '/'); err != nil {
diff --git a/modules/setting/lfs_test.go b/modules/setting/lfs_test.go
index d27dd7c5bf..1b829d8839 100644
--- a/modules/setting/lfs_test.go
+++ b/modules/setting/lfs_test.go
@@ -19,7 +19,7 @@ func Test_getStorageInheritNameSectionTypeForLFS(t *testing.T) {
assert.NoError(t, loadLFSFrom(cfg))
assert.EqualValues(t, "minio", LFS.Storage.Type)
- assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
iniStr = `
[server]
@@ -54,7 +54,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadLFSFrom(cfg))
assert.EqualValues(t, "minio", LFS.Storage.Type)
- assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
iniStr = `
[lfs]
@@ -68,7 +68,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadLFSFrom(cfg))
assert.EqualValues(t, "minio", LFS.Storage.Type)
- assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
iniStr = `
[lfs]
@@ -83,7 +83,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadLFSFrom(cfg))
assert.EqualValues(t, "minio", LFS.Storage.Type)
- assert.EqualValues(t, "my_lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "my_lfs/", LFS.Storage.MinioConfig.BasePath)
}
func Test_LFSStorage1(t *testing.T) {
@@ -96,8 +96,8 @@ STORAGE_TYPE = minio
assert.NoError(t, loadLFSFrom(cfg))
assert.EqualValues(t, "minio", LFS.Storage.Type)
- assert.EqualValues(t, "gitea", LFS.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", LFS.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
}
func Test_LFSClientServerConfigs(t *testing.T) {
@@ -112,9 +112,9 @@ BATCH_SIZE = 0
assert.NoError(t, err)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, 100, LFS.MaxBatchSize)
- assert.EqualValues(t, 20, LFSClient.BatchSize)
- assert.EqualValues(t, 8, LFSClient.BatchOperationConcurrency)
+ assert.Equal(t, 100, LFS.MaxBatchSize)
+ assert.Equal(t, 20, LFSClient.BatchSize)
+ assert.Equal(t, 8, LFSClient.BatchOperationConcurrency)
iniStr = `
[lfs_client]
@@ -125,6 +125,6 @@ BATCH_OPERATION_CONCURRENCY = 10
assert.NoError(t, err)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, 50, LFSClient.BatchSize)
- assert.EqualValues(t, 10, LFSClient.BatchOperationConcurrency)
+ assert.Equal(t, 50, LFSClient.BatchSize)
+ assert.Equal(t, 10, LFSClient.BatchOperationConcurrency)
}
diff --git a/modules/setting/log.go b/modules/setting/log.go
index 50c5779994..59866c7605 100644
--- a/modules/setting/log.go
+++ b/modules/setting/log.go
@@ -7,7 +7,6 @@ import (
"fmt"
golog "log"
"os"
- "path"
"path/filepath"
"strings"
@@ -41,7 +40,7 @@ func loadLogGlobalFrom(rootCfg ConfigProvider) {
Log.BufferLen = sec.Key("BUFFER_LEN").MustInt(10000)
Log.Mode = sec.Key("MODE").MustString("console")
- Log.RootPath = sec.Key("ROOT_PATH").MustString(path.Join(AppWorkPath, "log"))
+ Log.RootPath = sec.Key("ROOT_PATH").MustString(filepath.Join(AppWorkPath, "log"))
if !filepath.IsAbs(Log.RootPath) {
Log.RootPath = filepath.Join(AppWorkPath, Log.RootPath)
}
@@ -228,8 +227,8 @@ func initLoggerByName(manager *log.LoggerManager, rootCfg ConfigProvider, logger
}
var eventWriters []log.EventWriter
- modes := strings.Split(modeVal, ",")
- for _, modeName := range modes {
+ modes := strings.SplitSeq(modeVal, ",")
+ for modeName := range modes {
modeName = strings.TrimSpace(modeName)
if modeName == "" {
continue
diff --git a/modules/setting/mailer_test.go b/modules/setting/mailer_test.go
index fbabf11378..ceef35b051 100644
--- a/modules/setting/mailer_test.go
+++ b/modules/setting/mailer_test.go
@@ -34,8 +34,8 @@ func Test_loadMailerFrom(t *testing.T) {
// Check mailer setting
loadMailerFrom(cfg)
- assert.EqualValues(t, kase.SMTPAddr, MailService.SMTPAddr)
- assert.EqualValues(t, kase.SMTPPort, MailService.SMTPPort)
+ assert.Equal(t, kase.SMTPAddr, MailService.SMTPAddr)
+ assert.Equal(t, kase.SMTPPort, MailService.SMTPPort)
})
}
}
diff --git a/modules/setting/markup.go b/modules/setting/markup.go
index dfce8afa77..057b0650c3 100644
--- a/modules/setting/markup.go
+++ b/modules/setting/markup.go
@@ -8,6 +8,7 @@ import (
"strings"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
)
// ExternalMarkupRenderers represents the external markup renderers
@@ -23,18 +24,33 @@ const (
RenderContentModeIframe = "iframe"
)
+type MarkdownRenderOptions struct {
+ NewLineHardBreak bool
+ ShortIssuePattern bool // Actually it is a "markup" option because it is used in "post processor"
+}
+
+type MarkdownMathCodeBlockOptions struct {
+ ParseInlineDollar bool
+ ParseInlineParentheses bool
+ ParseBlockDollar bool
+ ParseBlockSquareBrackets bool
+}
+
// Markdown settings
var Markdown = struct {
- EnableHardLineBreakInComments bool
- EnableHardLineBreakInDocuments bool
- CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
- FileExtensions []string
- EnableMath bool
+ RenderOptionsComment MarkdownRenderOptions `ini:"-"`
+ RenderOptionsWiki MarkdownRenderOptions `ini:"-"`
+ RenderOptionsRepoFile MarkdownRenderOptions `ini:"-"`
+
+ CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"` // Actually it is a "markup" option because it is used in "post processor"
+ FileExtensions []string
+
+ EnableMath bool
+ MathCodeBlockDetection []string
+ MathCodeBlockOptions MarkdownMathCodeBlockOptions `ini:"-"`
}{
- EnableHardLineBreakInComments: true,
- EnableHardLineBreakInDocuments: false,
- FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd,.livemd", ","),
- EnableMath: true,
+ FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd,.livemd", ","),
+ EnableMath: true,
}
// MarkupRenderer defines the external parser configured in ini
@@ -60,8 +76,58 @@ type MarkupSanitizerRule struct {
func loadMarkupFrom(rootCfg ConfigProvider) {
mustMapSetting(rootCfg, "markdown", &Markdown)
+ const none = "none"
+
+ const renderOptionShortIssuePattern = "short-issue-pattern"
+ const renderOptionNewLineHardBreak = "new-line-hard-break"
+ cfgMarkdown := rootCfg.Section("markdown")
+ parseMarkdownRenderOptions := func(key string, defaults []string) (ret MarkdownRenderOptions) {
+ options := cfgMarkdown.Key(key).Strings(",")
+ options = util.IfEmpty(options, defaults)
+ for _, opt := range options {
+ switch opt {
+ case renderOptionShortIssuePattern:
+ ret.ShortIssuePattern = true
+ case renderOptionNewLineHardBreak:
+ ret.NewLineHardBreak = true
+ case none:
+ ret = MarkdownRenderOptions{}
+ case "":
+ default:
+ log.Error("Unknown markdown render option in %s: %s", key, opt)
+ }
+ }
+ return ret
+ }
+ Markdown.RenderOptionsComment = parseMarkdownRenderOptions("RENDER_OPTIONS_COMMENT", []string{renderOptionShortIssuePattern, renderOptionNewLineHardBreak})
+ Markdown.RenderOptionsWiki = parseMarkdownRenderOptions("RENDER_OPTIONS_WIKI", []string{renderOptionShortIssuePattern})
+ Markdown.RenderOptionsRepoFile = parseMarkdownRenderOptions("RENDER_OPTIONS_REPO_FILE", nil)
+
+ const mathCodeInlineDollar = "inline-dollar"
+ const mathCodeInlineParentheses = "inline-parentheses"
+ const mathCodeBlockDollar = "block-dollar"
+ const mathCodeBlockSquareBrackets = "block-square-brackets"
+ Markdown.MathCodeBlockDetection = util.IfEmpty(Markdown.MathCodeBlockDetection, []string{mathCodeInlineDollar, mathCodeBlockDollar})
+ Markdown.MathCodeBlockOptions = MarkdownMathCodeBlockOptions{}
+ for _, s := range Markdown.MathCodeBlockDetection {
+ switch s {
+ case mathCodeInlineDollar:
+ Markdown.MathCodeBlockOptions.ParseInlineDollar = true
+ case mathCodeInlineParentheses:
+ Markdown.MathCodeBlockOptions.ParseInlineParentheses = true
+ case mathCodeBlockDollar:
+ Markdown.MathCodeBlockOptions.ParseBlockDollar = true
+ case mathCodeBlockSquareBrackets:
+ Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets = true
+ case none:
+ Markdown.MathCodeBlockOptions = MarkdownMathCodeBlockOptions{}
+ case "":
+ default:
+ log.Error("Unknown math code block detection option: %s", s)
+ }
+ }
- MermaidMaxSourceCharacters = rootCfg.Section("markup").Key("MERMAID_MAX_SOURCE_CHARACTERS").MustInt(5000)
+ MermaidMaxSourceCharacters = rootCfg.Section("markup").Key("MERMAID_MAX_SOURCE_CHARACTERS").MustInt(50000)
ExternalMarkupRenderers = make([]*MarkupRenderer, 0, 10)
ExternalSanitizerRules = make([]MarkupSanitizerRule, 0, 10)
@@ -83,8 +149,8 @@ func loadMarkupFrom(rootCfg ConfigProvider) {
func newMarkupSanitizer(name string, sec ConfigSection) {
rule, ok := createMarkupSanitizerRule(name, sec)
if ok {
- if strings.HasPrefix(name, "sanitizer.") {
- names := strings.SplitN(strings.TrimPrefix(name, "sanitizer."), ".", 2)
+ if after, found := strings.CutPrefix(name, "sanitizer."); found {
+ names := strings.SplitN(after, ".", 2)
name = names[0]
}
for _, renderer := range ExternalMarkupRenderers {
diff --git a/modules/setting/markup_test.go b/modules/setting/markup_test.go
new file mode 100644
index 0000000000..c47a38ce15
--- /dev/null
+++ b/modules/setting/markup_test.go
@@ -0,0 +1,51 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package setting
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestLoadMarkup(t *testing.T) {
+ cfg, _ := NewConfigProviderFromData(``)
+ loadMarkupFrom(cfg)
+ assert.Equal(t, MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseBlockDollar: true}, Markdown.MathCodeBlockOptions)
+ assert.Equal(t, MarkdownRenderOptions{NewLineHardBreak: true, ShortIssuePattern: true}, Markdown.RenderOptionsComment)
+ assert.Equal(t, MarkdownRenderOptions{ShortIssuePattern: true}, Markdown.RenderOptionsWiki)
+ assert.Equal(t, MarkdownRenderOptions{}, Markdown.RenderOptionsRepoFile)
+
+ t.Run("Math", func(t *testing.T) {
+ cfg, _ = NewConfigProviderFromData(`
+[markdown]
+MATH_CODE_BLOCK_DETECTION = none
+`)
+ loadMarkupFrom(cfg)
+ assert.Equal(t, MarkdownMathCodeBlockOptions{}, Markdown.MathCodeBlockOptions)
+
+ cfg, _ = NewConfigProviderFromData(`
+[markdown]
+MATH_CODE_BLOCK_DETECTION = inline-dollar, inline-parentheses, block-dollar, block-square-brackets
+`)
+ loadMarkupFrom(cfg)
+ assert.Equal(t, MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseInlineParentheses: true, ParseBlockDollar: true, ParseBlockSquareBrackets: true}, Markdown.MathCodeBlockOptions)
+ })
+
+ t.Run("Render", func(t *testing.T) {
+ cfg, _ = NewConfigProviderFromData(`
+[markdown]
+RENDER_OPTIONS_COMMENT = none
+`)
+ loadMarkupFrom(cfg)
+ assert.Equal(t, MarkdownRenderOptions{}, Markdown.RenderOptionsComment)
+
+ cfg, _ = NewConfigProviderFromData(`
+[markdown]
+RENDER_OPTIONS_REPO_FILE = short-issue-pattern, new-line-hard-break
+`)
+ loadMarkupFrom(cfg)
+ assert.Equal(t, MarkdownRenderOptions{NewLineHardBreak: true, ShortIssuePattern: true}, Markdown.RenderOptionsRepoFile)
+ })
+}
diff --git a/modules/setting/mirror.go b/modules/setting/mirror.go
index 3aa530a1f4..300711789d 100644
--- a/modules/setting/mirror.go
+++ b/modules/setting/mirror.go
@@ -48,11 +48,7 @@ func loadMirrorFrom(rootCfg ConfigProvider) {
Mirror.MinInterval = 1 * time.Minute
}
if Mirror.DefaultInterval < Mirror.MinInterval {
- if time.Hour*8 < Mirror.MinInterval {
- Mirror.DefaultInterval = Mirror.MinInterval
- } else {
- Mirror.DefaultInterval = time.Hour * 8
- }
+ Mirror.DefaultInterval = max(time.Hour*8, Mirror.MinInterval)
log.Warn("Mirror.DefaultInterval is less than Mirror.MinInterval, set to %s", Mirror.DefaultInterval.String())
}
}
diff --git a/modules/setting/oauth2_test.go b/modules/setting/oauth2_test.go
index d0e5ccf13d..c6e66cad02 100644
--- a/modules/setting/oauth2_test.go
+++ b/modules/setting/oauth2_test.go
@@ -31,7 +31,7 @@ JWT_SECRET = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
actual := GetGeneralTokenSigningSecret()
expected, _ := generate.DecodeJwtSecretBase64("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
assert.Len(t, actual, 32)
- assert.EqualValues(t, expected, actual)
+ assert.Equal(t, expected, actual)
}
func TestGetGeneralSigningSecretSave(t *testing.T) {
diff --git a/modules/setting/packages.go b/modules/setting/packages.go
index 3f618cfd64..b598424064 100644
--- a/modules/setting/packages.go
+++ b/modules/setting/packages.go
@@ -6,8 +6,6 @@ package setting
import (
"fmt"
"math"
- "os"
- "path/filepath"
"github.com/dustin/go-humanize"
)
@@ -15,9 +13,8 @@ import (
// Package registry settings
var (
Packages = struct {
- Storage *Storage
- Enabled bool
- ChunkedUploadPath string
+ Storage *Storage
+ Enabled bool
LimitTotalOwnerCount int64
LimitTotalOwnerSize int64
@@ -67,17 +64,6 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
return err
}
- Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("tmp/package-upload"))
- if !filepath.IsAbs(Packages.ChunkedUploadPath) {
- Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath))
- }
-
- if HasInstallLock(rootCfg) {
- if err := os.MkdirAll(Packages.ChunkedUploadPath, os.ModePerm); err != nil {
- return fmt.Errorf("unable to create chunked upload directory: %s (%v)", Packages.ChunkedUploadPath, err)
- }
- }
-
Packages.LimitTotalOwnerSize = mustBytes(sec, "LIMIT_TOTAL_OWNER_SIZE")
Packages.LimitSizeAlpine = mustBytes(sec, "LIMIT_SIZE_ALPINE")
Packages.LimitSizeArch = mustBytes(sec, "LIMIT_SIZE_ARCH")
diff --git a/modules/setting/packages_test.go b/modules/setting/packages_test.go
index 87de276041..47378f35ad 100644
--- a/modules/setting/packages_test.go
+++ b/modules/setting/packages_test.go
@@ -41,7 +41,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadPackagesFrom(cfg))
assert.EqualValues(t, "minio", Packages.Storage.Type)
- assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath)
// we can also configure packages storage directly
iniStr = `
@@ -53,7 +53,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadPackagesFrom(cfg))
assert.EqualValues(t, "minio", Packages.Storage.Type)
- assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath)
// or we can indicate the storage type in the packages section
iniStr = `
@@ -68,7 +68,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadPackagesFrom(cfg))
assert.EqualValues(t, "minio", Packages.Storage.Type)
- assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath)
// or we can indicate the storage type and minio base path in the packages section
iniStr = `
@@ -84,7 +84,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadPackagesFrom(cfg))
assert.EqualValues(t, "minio", Packages.Storage.Type)
- assert.EqualValues(t, "my_packages/", Packages.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "my_packages/", Packages.Storage.MinioConfig.BasePath)
}
func Test_PackageStorage1(t *testing.T) {
@@ -109,8 +109,8 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage := Packages.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
- assert.EqualValues(t, "packages/", storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "packages/", storage.MinioConfig.BasePath)
assert.True(t, storage.MinioConfig.ServeDirect)
}
@@ -136,8 +136,8 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage := Packages.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
- assert.EqualValues(t, "packages/", storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "packages/", storage.MinioConfig.BasePath)
assert.True(t, storage.MinioConfig.ServeDirect)
}
@@ -164,8 +164,8 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage := Packages.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
- assert.EqualValues(t, "my_packages/", storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "my_packages/", storage.MinioConfig.BasePath)
assert.True(t, storage.MinioConfig.ServeDirect)
}
@@ -192,7 +192,7 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage := Packages.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
- assert.EqualValues(t, "my_packages/", storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "my_packages/", storage.MinioConfig.BasePath)
assert.True(t, storage.MinioConfig.ServeDirect)
}
diff --git a/modules/setting/path.go b/modules/setting/path.go
index 0fdc305aa1..f51457a620 100644
--- a/modules/setting/path.go
+++ b/modules/setting/path.go
@@ -11,6 +11,7 @@ import (
"strings"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/tempdir"
)
var (
@@ -196,3 +197,18 @@ func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkP
CustomPath = tmpCustomPath.Value
CustomConf = tmpCustomConf.Value
}
+
+// AppDataTempDir returns a managed temporary directory for the application data.
+// Using empty sub will get the managed base temp directory, and it's safe to delete it.
+// Gitea only creates subdirectories under it, but not the APP_TEMP_PATH directory itself.
+// * When APP_TEMP_PATH="/tmp": the managed temp directory is "/tmp/gitea-tmp"
+// * When APP_TEMP_PATH is not set: the managed temp directory is "/{APP_DATA_PATH}/tmp"
+func AppDataTempDir(sub string) *tempdir.TempDir {
+ if appTempPathInternal != "" {
+ return tempdir.New(appTempPathInternal, "gitea-tmp/"+sub)
+ }
+ if AppDataPath == "" {
+ panic("setting.AppDataPath is not set")
+ }
+ return tempdir.New(AppDataPath, "tmp/"+sub)
+}
diff --git a/modules/setting/repository.go b/modules/setting/repository.go
index c5619d0f04..318cf41108 100644
--- a/modules/setting/repository.go
+++ b/modules/setting/repository.go
@@ -5,7 +5,6 @@ package setting
import (
"os/exec"
- "path"
"path/filepath"
"strings"
@@ -63,17 +62,11 @@ var (
// Repository upload settings
Upload struct {
Enabled bool
- TempPath string
AllowedTypes string
FileMaxSize int64
MaxFiles int
} `ini:"-"`
- // Repository local settings
- Local struct {
- LocalCopyPath string
- } `ini:"-"`
-
// Pull request settings
PullRequest struct {
WorkInProgressPrefixes []string
@@ -89,6 +82,7 @@ var (
AddCoCommitterTrailers bool
TestConflictingPatchesWithGitApply bool
RetargetChildrenOnMerge bool
+ DelayCheckForInactiveDays int
} `ini:"repository.pull-request"`
// Issue Setting
@@ -106,11 +100,13 @@ var (
SigningKey string
SigningName string
SigningEmail string
+ SigningFormat string
InitialCommit []string
CRUDActions []string `ini:"CRUD_ACTIONS"`
Merges []string
Wiki []string
DefaultTrustModel string
+ TrustedSSHKeys []string `ini:"TRUSTED_SSH_KEYS"`
} `ini:"repository.signing"`
}{
DetectedCharsetsOrder: []string{
@@ -182,25 +178,16 @@ var (
// Repository upload settings
Upload: struct {
Enabled bool
- TempPath string
AllowedTypes string
FileMaxSize int64
MaxFiles int
}{
Enabled: true,
- TempPath: "data/tmp/uploads",
AllowedTypes: "",
FileMaxSize: 50,
MaxFiles: 5,
},
- // Repository local settings
- Local: struct {
- LocalCopyPath string
- }{
- LocalCopyPath: "tmp/local-repo",
- },
-
// Pull request settings
PullRequest: struct {
WorkInProgressPrefixes []string
@@ -216,6 +203,7 @@ var (
AddCoCommitterTrailers bool
TestConflictingPatchesWithGitApply bool
RetargetChildrenOnMerge bool
+ DelayCheckForInactiveDays int
}{
WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
// Same as GitHub. See
@@ -231,6 +219,7 @@ var (
PopulateSquashCommentWithCommitMessages: false,
AddCoCommitterTrailers: true,
RetargetChildrenOnMerge: true,
+ DelayCheckForInactiveDays: 7,
},
// Issue settings
@@ -255,20 +244,24 @@ var (
SigningKey string
SigningName string
SigningEmail string
+ SigningFormat string
InitialCommit []string
CRUDActions []string `ini:"CRUD_ACTIONS"`
Merges []string
Wiki []string
DefaultTrustModel string
+ TrustedSSHKeys []string `ini:"TRUSTED_SSH_KEYS"`
}{
SigningKey: "default",
SigningName: "",
SigningEmail: "",
+ SigningFormat: "openpgp", // git.SigningKeyFormatOpenPGP
InitialCommit: []string{"always"},
CRUDActions: []string{"pubkey", "twofa", "parentsigned"},
Merges: []string{"pubkey", "twofa", "basesigned", "commitssigned"},
Wiki: []string{"never"},
DefaultTrustModel: "collaborator",
+ TrustedSSHKeys: []string{},
},
}
RepoRootPath string
@@ -284,7 +277,7 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
Repository.GoGetCloneURLProtocol = sec.Key("GO_GET_CLONE_URL_PROTOCOL").MustString("https")
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch)
- RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "gitea-repositories"))
+ RepoRootPath = sec.Key("ROOT").MustString(filepath.Join(AppDataPath, "gitea-repositories"))
if !filepath.IsAbs(RepoRootPath) {
RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath)
} else {
@@ -309,8 +302,6 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
log.Fatal("Failed to map Repository.Editor settings: %v", err)
} else if err = rootCfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
log.Fatal("Failed to map Repository.Upload settings: %v", err)
- } else if err = rootCfg.Section("repository.local").MapTo(&Repository.Local); err != nil {
- log.Fatal("Failed to map Repository.Local settings: %v", err)
} else if err = rootCfg.Section("repository.pull-request").MapTo(&Repository.PullRequest); err != nil {
log.Fatal("Failed to map Repository.PullRequest settings: %v", err)
}
@@ -362,10 +353,6 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
}
}
- if !filepath.IsAbs(Repository.Upload.TempPath) {
- Repository.Upload.TempPath = path.Join(AppWorkPath, Repository.Upload.TempPath)
- }
-
if err := loadRepoArchiveFrom(rootCfg); err != nil {
log.Fatal("loadRepoArchiveFrom: %v", err)
}
diff --git a/modules/setting/repository_archive_test.go b/modules/setting/repository_archive_test.go
index a0f91f0da1..d5b95272d6 100644
--- a/modules/setting/repository_archive_test.go
+++ b/modules/setting/repository_archive_test.go
@@ -20,7 +20,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "minio", RepoArchive.Storage.Type)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
// we can also configure packages storage directly
iniStr = `
@@ -32,7 +32,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "minio", RepoArchive.Storage.Type)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
// or we can indicate the storage type in the packages section
iniStr = `
@@ -47,7 +47,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "minio", RepoArchive.Storage.Type)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
// or we can indicate the storage type and minio base path in the packages section
iniStr = `
@@ -63,7 +63,7 @@ STORAGE_TYPE = minio
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "minio", RepoArchive.Storage.Type)
- assert.EqualValues(t, "my_archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "my_archive/", RepoArchive.Storage.MinioConfig.BasePath)
}
func Test_RepoArchiveStorage(t *testing.T) {
@@ -85,7 +85,7 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage := RepoArchive.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
iniStr = `
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -107,5 +107,5 @@ MINIO_SECRET_ACCESS_KEY = correct_key
storage = RepoArchive.Storage
assert.EqualValues(t, "minio", storage.Type)
- assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket)
+ assert.Equal(t, "gitea", storage.MinioConfig.Bucket)
}
diff --git a/modules/setting/security.go b/modules/setting/security.go
index 2f798b75c7..153b6bc944 100644
--- a/modules/setting/security.go
+++ b/modules/setting/security.go
@@ -39,6 +39,7 @@ var (
CSRFCookieName = "_csrf"
CSRFCookieHTTPOnly = true
RecordUserSignupMetadata = false
+ TwoFactorAuthEnforced = false
)
// loadSecret load the secret from ini by uriKey or verbatimKey, only one of them could be set
@@ -110,7 +111,7 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
if SecretKey == "" {
// FIXME: https://github.com/go-gitea/gitea/issues/16832
// Until it supports rotating an existing secret key, we shouldn't move users off of the widely used default value
- SecretKey = "!#@FDEWREWR&*(" //nolint:gosec
+ SecretKey = "!#@FDEWREWR&*("
}
CookieRememberName = sec.Key("COOKIE_REMEMBER_NAME").MustString("gitea_incredible")
@@ -142,6 +143,15 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)
+ twoFactorAuth := sec.Key("TWO_FACTOR_AUTH").String()
+ switch twoFactorAuth {
+ case "":
+ case "enforced":
+ TwoFactorAuthEnforced = true
+ default:
+ log.Fatal("Invalid two-factor auth option: %s", twoFactorAuth)
+ }
+
InternalToken = loadSecret(sec, "INTERNAL_TOKEN_URI", "INTERNAL_TOKEN")
if InstallLock && InternalToken == "" {
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
diff --git a/modules/setting/server.go b/modules/setting/server.go
index e15b790906..8a22f6a844 100644
--- a/modules/setting/server.go
+++ b/modules/setting/server.go
@@ -7,6 +7,7 @@ import (
"encoding/base64"
"net"
"net/url"
+ "os"
"path/filepath"
"strconv"
"strings"
@@ -40,28 +41,47 @@ const (
LandingPageLogin LandingPage = "/user/login"
)
+const (
+ PublicURLAuto = "auto"
+ PublicURLLegacy = "legacy"
+)
+
// Server settings
var (
// AppURL is the Application ROOT_URL. It always has a '/' suffix
// It maps to ini:"ROOT_URL"
AppURL string
- // AppSubURL represents the sub-url mounting point for gitea. It is either "" or starts with '/' and ends without '/', such as '/{subpath}'.
+
+ // PublicURLDetection controls how to use the HTTP request headers to detect public URL
+ PublicURLDetection string
+
+ // AppSubURL represents the sub-url mounting point for gitea, parsed from "ROOT_URL"
+ // It is either "" or starts with '/' and ends without '/', such as '/{sub-path}'.
// This value is empty if site does not have sub-url.
AppSubURL string
- // UseSubURLPath makes Gitea handle requests with sub-path like "/sub-path/owner/repo/...", to make it easier to debug sub-path related problems without a reverse proxy.
+
+ // UseSubURLPath makes Gitea handle requests with sub-path like "/sub-path/owner/repo/...",
+ // to make it easier to debug sub-path related problems without a reverse proxy.
UseSubURLPath bool
+
// AppDataPath is the default path for storing data.
// It maps to ini:"APP_DATA_PATH" in [server] and defaults to AppWorkPath + "/data"
AppDataPath string
+
// LocalURL is the url for locally running applications to contact Gitea. It always has a '/' suffix
// It maps to ini:"LOCAL_ROOT_URL" in [server]
LocalURL string
- // AssetVersion holds a opaque value that is used for cache-busting assets
+
+ // AssetVersion holds an opaque value that is used for cache-busting assets
AssetVersion string
+ // appTempPathInternal is the temporary path for the app, it is only an internal variable
+ // DO NOT use it directly, always use AppDataTempDir
+ appTempPathInternal string
+
Protocol Scheme
- UseProxyProtocol bool // `ini:"USE_PROXY_PROTOCOL"`
- ProxyProtocolTLSBridging bool //`ini:"PROXY_PROTOCOL_TLS_BRIDGING"`
+ UseProxyProtocol bool
+ ProxyProtocolTLSBridging bool
ProxyProtocolHeaderTimeout time.Duration
ProxyProtocolAcceptUnknown bool
Domain string
@@ -178,13 +198,14 @@ func loadServerFrom(rootCfg ConfigProvider) {
EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
}
- Protocol = HTTP
protocolCfg := sec.Key("PROTOCOL").String()
if protocolCfg != "https" && EnableAcme {
log.Fatal("ACME could only be used with HTTPS protocol")
}
switch protocolCfg {
+ case "", "http":
+ Protocol = HTTP
case "https":
Protocol = HTTPS
if EnableAcme {
@@ -240,7 +261,7 @@ func loadServerFrom(rootCfg ConfigProvider) {
case "unix":
log.Warn("unix PROTOCOL value is deprecated, please use http+unix")
fallthrough
- case "http+unix":
+ default: // "http+unix"
Protocol = HTTPUnix
}
UnixSocketPermissionRaw := sec.Key("UNIX_SOCKET_PERMISSION").MustString("666")
@@ -253,6 +274,8 @@ func loadServerFrom(rootCfg ConfigProvider) {
if !filepath.IsAbs(HTTPAddr) {
HTTPAddr = filepath.Join(AppWorkPath, HTTPAddr)
}
+ default:
+ log.Fatal("Invalid PROTOCOL %q", Protocol)
}
UseProxyProtocol = sec.Key("USE_PROXY_PROTOCOL").MustBool(false)
ProxyProtocolTLSBridging = sec.Key("PROXY_PROTOCOL_TLS_BRIDGING").MustBool(false)
@@ -266,11 +289,15 @@ func loadServerFrom(rootCfg ConfigProvider) {
defaultAppURL := string(Protocol) + "://" + Domain + ":" + HTTPPort
AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL)
+ PublicURLDetection = sec.Key("PUBLIC_URL_DETECTION").MustString(PublicURLLegacy)
+ if PublicURLDetection != PublicURLAuto && PublicURLDetection != PublicURLLegacy {
+ log.Fatal("Invalid PUBLIC_URL_DETECTION value: %s", PublicURLDetection)
+ }
// Check validity of AppURL
appURL, err := url.Parse(AppURL)
if err != nil {
- log.Fatal("Invalid ROOT_URL '%s': %s", AppURL, err)
+ log.Fatal("Invalid ROOT_URL %q: %s", AppURL, err)
}
// Remove default ports from AppURL.
// (scheme-based URL normalization, RFC 3986 section 6.2.3)
@@ -306,13 +333,15 @@ func loadServerFrom(rootCfg ConfigProvider) {
defaultLocalURL = AppURL
case FCGIUnix:
defaultLocalURL = AppURL
- default:
+ case HTTP, HTTPS:
defaultLocalURL = string(Protocol) + "://"
if HTTPAddr == "0.0.0.0" {
defaultLocalURL += net.JoinHostPort("localhost", HTTPPort) + "/"
} else {
defaultLocalURL += net.JoinHostPort(HTTPAddr, HTTPPort) + "/"
}
+ default:
+ log.Fatal("Invalid PROTOCOL %q", Protocol)
}
LocalURL = sec.Key("LOCAL_ROOT_URL").MustString(defaultLocalURL)
LocalURL = strings.TrimRight(LocalURL, "/") + "/"
@@ -330,6 +359,19 @@ func loadServerFrom(rootCfg ConfigProvider) {
if !filepath.IsAbs(AppDataPath) {
AppDataPath = filepath.ToSlash(filepath.Join(AppWorkPath, AppDataPath))
}
+ if IsInTesting && HasInstallLock(rootCfg) {
+ // FIXME: in testing, the "app data" directory is not correctly initialized before loading settings
+ if _, err := os.Stat(AppDataPath); err != nil {
+ _ = os.MkdirAll(AppDataPath, os.ModePerm)
+ }
+ }
+
+ appTempPathInternal = sec.Key("APP_TEMP_PATH").String()
+ if appTempPathInternal != "" {
+ if _, err := os.Stat(appTempPathInternal); err != nil {
+ log.Fatal("APP_TEMP_PATH %q is not accessible: %v", appTempPathInternal, err)
+ }
+ }
EnableGzip = sec.Key("ENABLE_GZIP").MustBool()
EnablePprof = sec.Key("ENABLE_PPROF").MustBool(false)
diff --git a/modules/setting/service.go b/modules/setting/service.go
index 8c1843eeb7..b1b9fedd62 100644
--- a/modules/setting/service.go
+++ b/modules/setting/service.go
@@ -5,6 +5,7 @@ package setting
import (
"regexp"
+ "runtime"
"strings"
"time"
@@ -43,7 +44,8 @@ var Service = struct {
ShowRegistrationButton bool
EnablePasswordSignInForm bool
ShowMilestonesDashboardPage bool
- RequireSignInView bool
+ RequireSignInViewStrict bool
+ BlockAnonymousAccessExpensive bool
EnableNotifyMail bool
EnableBasicAuth bool
EnablePasskeyAuth bool
@@ -97,6 +99,13 @@ var Service = struct {
DisableOrganizationsPage bool `ini:"DISABLE_ORGANIZATIONS_PAGE"`
DisableCodePage bool `ini:"DISABLE_CODE_PAGE"`
} `ini:"service.explore"`
+
+ QoS struct {
+ Enabled bool
+ MaxInFlightRequests int
+ MaxWaitingRequests int
+ TargetWaitTime time.Duration
+ }
}{
AllowedUserVisibilityModesSlice: []bool{true, true, true},
}
@@ -159,7 +168,18 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.EmailDomainBlockList = CompileEmailGlobList(sec, "EMAIL_DOMAIN_BLOCKLIST")
Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration))
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
- Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
+
+ // boolean values are considered as "strict"
+ var err error
+ Service.RequireSignInViewStrict, err = sec.Key("REQUIRE_SIGNIN_VIEW").Bool()
+ if s := sec.Key("REQUIRE_SIGNIN_VIEW").String(); err != nil && s != "" {
+ // non-boolean value only supports "expensive" at the moment
+ Service.BlockAnonymousAccessExpensive = s == "expensive"
+ if !Service.BlockAnonymousAccessExpensive {
+ log.Fatal("Invalid config option: REQUIRE_SIGNIN_VIEW = %s", s)
+ }
+ }
+
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
Service.EnablePasswordSignInForm = sec.Key("ENABLE_PASSWORD_SIGNIN_FORM").MustBool(true)
Service.EnablePasskeyAuth = sec.Key("ENABLE_PASSKEY_AUTHENTICATION").MustBool(true)
@@ -243,6 +263,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
mustMapSetting(rootCfg, "service.explore", &Service.Explore)
loadOpenIDSetting(rootCfg)
+ loadQosSetting(rootCfg)
}
func loadOpenIDSetting(rootCfg ConfigProvider) {
@@ -264,3 +285,11 @@ func loadOpenIDSetting(rootCfg ConfigProvider) {
}
}
}
+
+func loadQosSetting(rootCfg ConfigProvider) {
+ sec := rootCfg.Section("qos")
+ Service.QoS.Enabled = sec.Key("ENABLED").MustBool(false)
+ Service.QoS.MaxInFlightRequests = sec.Key("MAX_INFLIGHT").MustInt(4 * runtime.NumCPU())
+ Service.QoS.MaxWaitingRequests = sec.Key("MAX_WAITING").MustInt(100)
+ Service.QoS.TargetWaitTime = sec.Key("TARGET_WAIT_TIME").MustDuration(250 * time.Millisecond)
+}
diff --git a/modules/setting/service_test.go b/modules/setting/service_test.go
index 1647bcec16..73736b793a 100644
--- a/modules/setting/service_test.go
+++ b/modules/setting/service_test.go
@@ -7,16 +7,14 @@ import (
"testing"
"code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/test"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
)
func TestLoadServices(t *testing.T) {
- oldService := Service
- defer func() {
- Service = oldService
- }()
+ defer test.MockVariableValue(&Service)()
cfg, err := NewConfigProviderFromData(`
[service]
@@ -48,10 +46,7 @@ EMAIL_DOMAIN_BLOCKLIST = d3, *.b
}
func TestLoadServiceVisibilityModes(t *testing.T) {
- oldService := Service
- defer func() {
- Service = oldService
- }()
+ defer test.MockVariableValue(&Service)()
kases := map[string]func(){
`
@@ -130,3 +125,33 @@ ALLOWED_USER_VISIBILITY_MODES = public, limit, privated
})
}
}
+
+func TestLoadServiceRequireSignInView(t *testing.T) {
+ defer test.MockVariableValue(&Service)()
+
+ cfg, err := NewConfigProviderFromData(`
+[service]
+`)
+ assert.NoError(t, err)
+ loadServiceFrom(cfg)
+ assert.False(t, Service.RequireSignInViewStrict)
+ assert.False(t, Service.BlockAnonymousAccessExpensive)
+
+ cfg, err = NewConfigProviderFromData(`
+[service]
+REQUIRE_SIGNIN_VIEW = true
+`)
+ assert.NoError(t, err)
+ loadServiceFrom(cfg)
+ assert.True(t, Service.RequireSignInViewStrict)
+ assert.False(t, Service.BlockAnonymousAccessExpensive)
+
+ cfg, err = NewConfigProviderFromData(`
+[service]
+REQUIRE_SIGNIN_VIEW = expensive
+`)
+ assert.NoError(t, err)
+ loadServiceFrom(cfg)
+ assert.False(t, Service.RequireSignInViewStrict)
+ assert.True(t, Service.BlockAnonymousAccessExpensive)
+}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 20da796b58..e14997801f 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -12,8 +12,8 @@ import (
"time"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/user"
- "code.gitea.io/gitea/modules/util"
)
// settings
@@ -159,7 +159,7 @@ func loadRunModeFrom(rootCfg ConfigProvider) {
// The following is a purposefully undocumented option. Please do not run Gitea as root. It will only cause future headaches.
// Please don't use root as a bandaid to "fix" something that is broken, instead the broken thing should instead be fixed properly.
unsafeAllowRunAsRoot := ConfigSectionKeyBool(rootSec, "I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")
- unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || util.OptionalBoolParse(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value()
+ unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || optional.ParseBool(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value()
RunMode = os.Getenv("GITEA_RUN_MODE")
if RunMode == "" {
RunMode = rootSec.Key("RUN_MODE").MustString("prod")
diff --git a/modules/setting/ssh.go b/modules/setting/ssh.go
index ea387e521f..900fc6ade2 100644
--- a/modules/setting/ssh.go
+++ b/modules/setting/ssh.go
@@ -4,8 +4,6 @@
package setting
import (
- "os"
- "path"
"path/filepath"
"strings"
"text/template"
@@ -32,8 +30,6 @@ var SSH = struct {
ServerKeyExchanges []string `ini:"SSH_SERVER_KEY_EXCHANGES"`
ServerMACs []string `ini:"SSH_SERVER_MACS"`
ServerHostKeys []string `ini:"SSH_SERVER_HOST_KEYS"`
- KeyTestPath string `ini:"SSH_KEY_TEST_PATH"`
- KeygenPath string `ini:"SSH_KEYGEN_PATH"`
AuthorizedKeysBackup bool `ini:"SSH_AUTHORIZED_KEYS_BACKUP"`
AuthorizedPrincipalsBackup bool `ini:"SSH_AUTHORIZED_PRINCIPALS_BACKUP"`
AuthorizedKeysCommandTemplate string `ini:"SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE"`
@@ -55,10 +51,6 @@ var SSH = struct {
StartBuiltinServer: false,
Domain: "",
Port: 22,
- ServerCiphers: []string{"chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"},
- ServerKeyExchanges: []string{"curve25519-sha256", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha256", "diffie-hellman-group14-sha1"},
- ServerMACs: []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1"},
- KeygenPath: "",
MinimumKeySizeCheck: true,
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 3071},
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
@@ -111,30 +103,27 @@ func loadSSHFrom(rootCfg ConfigProvider) {
}
homeDir = strings.ReplaceAll(homeDir, "\\", "/")
- SSH.RootPath = path.Join(homeDir, ".ssh")
- serverCiphers := sec.Key("SSH_SERVER_CIPHERS").Strings(",")
- if len(serverCiphers) > 0 {
- SSH.ServerCiphers = serverCiphers
- }
- serverKeyExchanges := sec.Key("SSH_SERVER_KEY_EXCHANGES").Strings(",")
- if len(serverKeyExchanges) > 0 {
- SSH.ServerKeyExchanges = serverKeyExchanges
- }
- serverMACs := sec.Key("SSH_SERVER_MACS").Strings(",")
- if len(serverMACs) > 0 {
- SSH.ServerMACs = serverMACs
- }
- SSH.KeyTestPath = os.TempDir()
+ SSH.RootPath = filepath.Join(homeDir, ".ssh")
+
if err = sec.MapTo(&SSH); err != nil {
log.Fatal("Failed to map SSH settings: %v", err)
}
+
+ serverCiphers := sec.Key("SSH_SERVER_CIPHERS").Strings(",")
+ SSH.ServerCiphers = util.Iif(len(serverCiphers) > 0, serverCiphers, nil)
+
+ serverKeyExchanges := sec.Key("SSH_SERVER_KEY_EXCHANGES").Strings(",")
+ SSH.ServerKeyExchanges = util.Iif(len(serverKeyExchanges) > 0, serverKeyExchanges, nil)
+
+ serverMACs := sec.Key("SSH_SERVER_MACS").Strings(",")
+ SSH.ServerMACs = util.Iif(len(serverMACs) > 0, serverMACs, nil)
+
for i, key := range SSH.ServerHostKeys {
if !filepath.IsAbs(key) {
SSH.ServerHostKeys[i] = filepath.Join(AppDataPath, key)
}
}
- SSH.KeygenPath = sec.Key("SSH_KEYGEN_PATH").String()
SSH.Port = sec.Key("SSH_PORT").MustInt(22)
SSH.ListenPort = sec.Key("SSH_LISTEN_PORT").MustInt(SSH.Port)
SSH.UseProxyProtocol = sec.Key("SSH_SERVER_USE_PROXY_PROTOCOL").MustBool(false)
diff --git a/modules/setting/storage.go b/modules/setting/storage.go
index d3d1fb9f30..ee246158d9 100644
--- a/modules/setting/storage.go
+++ b/modules/setting/storage.go
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"path/filepath"
+ "slices"
"strings"
)
@@ -30,12 +31,7 @@ var storageTypes = []StorageType{
// IsValidStorageType returns true if the given storage type is valid
func IsValidStorageType(storageType StorageType) bool {
- for _, t := range storageTypes {
- if t == storageType {
- return true
- }
- }
- return false
+ return slices.Contains(storageTypes, storageType)
}
// MinioStorageConfig represents the configuration for a minio storage
@@ -162,7 +158,7 @@ const (
targetSecIsSec // target section is from the name seciont [name]
)
-func getStorageSectionByType(rootCfg ConfigProvider, typ string) (ConfigSection, targetSecType, error) { //nolint:unparam
+func getStorageSectionByType(rootCfg ConfigProvider, typ string) (ConfigSection, targetSecType, error) { //nolint:unparam // FIXME: targetSecType is always 0, wrong design?
targetSec, err := rootCfg.GetSection(storageSectionName + "." + typ)
if err != nil {
if !IsValidStorageType(StorageType(typ)) {
@@ -210,8 +206,8 @@ func getStorageTargetSection(rootCfg ConfigProvider, name, typ string, sec Confi
targetSec, _ := rootCfg.GetSection(storageSectionName + "." + name)
if targetSec != nil {
targetType := targetSec.Key("STORAGE_TYPE").String()
- switch {
- case targetType == "":
+ switch targetType {
+ case "":
if targetSec.Key("PATH").String() == "" { // both storage type and path are empty, use default
return getDefaultStorageSection(rootCfg), targetSecIsDefault, nil
}
@@ -287,7 +283,7 @@ func getStorageForLocal(targetSec, overrideSec ConfigSection, tp targetSecType,
return &storage, nil
}
-func getStorageForMinio(targetSec, overrideSec ConfigSection, tp targetSecType, name string) (*Storage, error) { //nolint:dupl
+func getStorageForMinio(targetSec, overrideSec ConfigSection, tp targetSecType, name string) (*Storage, error) { //nolint:dupl // duplicates azure setup
var storage Storage
storage.Type = StorageType(targetSec.Key("STORAGE_TYPE").String())
if err := targetSec.MapTo(&storage.MinioConfig); err != nil {
@@ -316,7 +312,7 @@ func getStorageForMinio(targetSec, overrideSec ConfigSection, tp targetSecType,
return &storage, nil
}
-func getStorageForAzureBlob(targetSec, overrideSec ConfigSection, tp targetSecType, name string) (*Storage, error) { //nolint:dupl
+func getStorageForAzureBlob(targetSec, overrideSec ConfigSection, tp targetSecType, name string) (*Storage, error) { //nolint:dupl // duplicates minio setup
var storage Storage
storage.Type = StorageType(targetSec.Key("STORAGE_TYPE").String())
if err := targetSec.MapTo(&storage.AzureBlobConfig); err != nil {
diff --git a/modules/setting/storage_test.go b/modules/setting/storage_test.go
index afff85537e..6f5a54c41c 100644
--- a/modules/setting/storage_test.go
+++ b/modules/setting/storage_test.go
@@ -26,16 +26,16 @@ MINIO_BUCKET = gitea-storage
assert.NoError(t, err)
assert.NoError(t, loadAttachmentFrom(cfg))
- assert.EqualValues(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, "gitea-lfs", LFS.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-lfs", LFS.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
assert.NoError(t, loadAvatarsFrom(cfg))
- assert.EqualValues(t, "gitea-storage", Avatar.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "avatars/", Avatar.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-storage", Avatar.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "avatars/", Avatar.Storage.MinioConfig.BasePath)
}
func Test_getStorageUseOtherNameAsType(t *testing.T) {
@@ -51,12 +51,12 @@ MINIO_BUCKET = gitea-storage
assert.NoError(t, err)
assert.NoError(t, loadAttachmentFrom(cfg))
- assert.EqualValues(t, "gitea-storage", Attachment.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-storage", Attachment.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, "gitea-storage", LFS.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea-storage", LFS.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath)
}
func Test_getStorageInheritStorageType(t *testing.T) {
@@ -69,32 +69,32 @@ STORAGE_TYPE = minio
assert.NoError(t, loadPackagesFrom(cfg))
assert.EqualValues(t, "minio", Packages.Storage.Type)
- assert.EqualValues(t, "gitea", Packages.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", Packages.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath)
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "minio", RepoArchive.Storage.Type)
- assert.EqualValues(t, "gitea", RepoArchive.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", RepoArchive.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "minio", Actions.LogStorage.Type)
- assert.EqualValues(t, "gitea", Actions.LogStorage.MinioConfig.Bucket)
- assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", Actions.LogStorage.MinioConfig.Bucket)
+ assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath)
assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "gitea", Actions.ArtifactStorage.MinioConfig.Bucket)
- assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", Actions.ArtifactStorage.MinioConfig.Bucket)
+ assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath)
assert.NoError(t, loadAvatarsFrom(cfg))
assert.EqualValues(t, "minio", Avatar.Storage.Type)
- assert.EqualValues(t, "gitea", Avatar.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "avatars/", Avatar.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", Avatar.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "avatars/", Avatar.Storage.MinioConfig.BasePath)
assert.NoError(t, loadRepoAvatarFrom(cfg))
assert.EqualValues(t, "minio", RepoAvatar.Storage.Type)
- assert.EqualValues(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket)
- assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket)
+ assert.Equal(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath)
}
func Test_getStorageInheritStorageTypeAzureBlob(t *testing.T) {
@@ -107,32 +107,32 @@ STORAGE_TYPE = azureblob
assert.NoError(t, loadPackagesFrom(cfg))
assert.EqualValues(t, "azureblob", Packages.Storage.Type)
- assert.EqualValues(t, "gitea", Packages.Storage.AzureBlobConfig.Container)
- assert.EqualValues(t, "packages/", Packages.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "gitea", Packages.Storage.AzureBlobConfig.Container)
+ assert.Equal(t, "packages/", Packages.Storage.AzureBlobConfig.BasePath)
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "azureblob", RepoArchive.Storage.Type)
- assert.EqualValues(t, "gitea", RepoArchive.Storage.AzureBlobConfig.Container)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "gitea", RepoArchive.Storage.AzureBlobConfig.Container)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath)
assert.NoError(t, loadActionsFrom(cfg))
assert.EqualValues(t, "azureblob", Actions.LogStorage.Type)
- assert.EqualValues(t, "gitea", Actions.LogStorage.AzureBlobConfig.Container)
- assert.EqualValues(t, "actions_log/", Actions.LogStorage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "gitea", Actions.LogStorage.AzureBlobConfig.Container)
+ assert.Equal(t, "actions_log/", Actions.LogStorage.AzureBlobConfig.BasePath)
assert.EqualValues(t, "azureblob", Actions.ArtifactStorage.Type)
- assert.EqualValues(t, "gitea", Actions.ArtifactStorage.AzureBlobConfig.Container)
- assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "gitea", Actions.ArtifactStorage.AzureBlobConfig.Container)
+ assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.AzureBlobConfig.BasePath)
assert.NoError(t, loadAvatarsFrom(cfg))
assert.EqualValues(t, "azureblob", Avatar.Storage.Type)
- assert.EqualValues(t, "gitea", Avatar.Storage.AzureBlobConfig.Container)
- assert.EqualValues(t, "avatars/", Avatar.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "gitea", Avatar.Storage.AzureBlobConfig.Container)
+ assert.Equal(t, "avatars/", Avatar.Storage.AzureBlobConfig.BasePath)
assert.NoError(t, loadRepoAvatarFrom(cfg))
assert.EqualValues(t, "azureblob", RepoAvatar.Storage.Type)
- assert.EqualValues(t, "gitea", RepoAvatar.Storage.AzureBlobConfig.Container)
- assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "gitea", RepoAvatar.Storage.AzureBlobConfig.Container)
+ assert.Equal(t, "repo-avatars/", RepoAvatar.Storage.AzureBlobConfig.BasePath)
}
type testLocalStoragePathCase struct {
@@ -151,7 +151,7 @@ func testLocalStoragePath(t *testing.T, appDataPath, iniStr string, cases []test
assert.EqualValues(t, "local", storage.Type)
assert.True(t, filepath.IsAbs(storage.Path))
- assert.EqualValues(t, filepath.Clean(c.expectedPath), filepath.Clean(storage.Path))
+ assert.Equal(t, filepath.Clean(c.expectedPath), filepath.Clean(storage.Path))
}
}
@@ -389,8 +389,8 @@ MINIO_SECRET_ACCESS_KEY = my_secret_key
assert.NoError(t, loadRepoArchiveFrom(cfg))
cp := RepoArchive.Storage.ToShadowCopy()
- assert.EqualValues(t, "******", cp.MinioConfig.AccessKeyID)
- assert.EqualValues(t, "******", cp.MinioConfig.SecretAccessKey)
+ assert.Equal(t, "******", cp.MinioConfig.AccessKeyID)
+ assert.Equal(t, "******", cp.MinioConfig.SecretAccessKey)
}
func Test_getStorageConfiguration24(t *testing.T) {
@@ -445,10 +445,10 @@ MINIO_USE_SSL = true
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
- assert.EqualValues(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID)
- assert.EqualValues(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey)
+ assert.Equal(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID)
+ assert.Equal(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey)
assert.True(t, RepoArchive.Storage.MinioConfig.UseSSL)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
}
func Test_getStorageConfiguration28(t *testing.T) {
@@ -462,10 +462,10 @@ MINIO_BASE_PATH = /prefix
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
- assert.EqualValues(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID)
- assert.EqualValues(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey)
+ assert.Equal(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID)
+ assert.Equal(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey)
assert.True(t, RepoArchive.Storage.MinioConfig.UseSSL)
- assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
cfg, err = NewConfigProviderFromData(`
[storage]
@@ -476,9 +476,9 @@ MINIO_BASE_PATH = /prefix
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
- assert.EqualValues(t, "127.0.0.1", RepoArchive.Storage.MinioConfig.IamEndpoint)
+ assert.Equal(t, "127.0.0.1", RepoArchive.Storage.MinioConfig.IamEndpoint)
assert.True(t, RepoArchive.Storage.MinioConfig.UseSSL)
- assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
cfg, err = NewConfigProviderFromData(`
[storage]
@@ -493,10 +493,10 @@ MINIO_BASE_PATH = /lfs
`)
assert.NoError(t, err)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
- assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
+ assert.Equal(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
+ assert.Equal(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
assert.True(t, LFS.Storage.MinioConfig.UseSSL)
- assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "/lfs", LFS.Storage.MinioConfig.BasePath)
cfg, err = NewConfigProviderFromData(`
[storage]
@@ -511,10 +511,10 @@ MINIO_BASE_PATH = /lfs
`)
assert.NoError(t, err)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
- assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
+ assert.Equal(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
+ assert.Equal(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
assert.True(t, LFS.Storage.MinioConfig.UseSSL)
- assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath)
+ assert.Equal(t, "/lfs", LFS.Storage.MinioConfig.BasePath)
}
func Test_getStorageConfiguration29(t *testing.T) {
@@ -539,9 +539,9 @@ AZURE_BLOB_ACCOUNT_KEY = my_account_key
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
- assert.EqualValues(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName)
- assert.EqualValues(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey)
- assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName)
+ assert.Equal(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey)
+ assert.Equal(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath)
}
func Test_getStorageConfiguration31(t *testing.T) {
@@ -554,9 +554,9 @@ AZURE_BLOB_BASE_PATH = /prefix
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
- assert.EqualValues(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName)
- assert.EqualValues(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey)
- assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName)
+ assert.Equal(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey)
+ assert.Equal(t, "/prefix/repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath)
cfg, err = NewConfigProviderFromData(`
[storage]
@@ -570,9 +570,9 @@ AZURE_BLOB_BASE_PATH = /lfs
`)
assert.NoError(t, err)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName)
- assert.EqualValues(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey)
- assert.EqualValues(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName)
+ assert.Equal(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey)
+ assert.Equal(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath)
cfg, err = NewConfigProviderFromData(`
[storage]
@@ -586,7 +586,7 @@ AZURE_BLOB_BASE_PATH = /lfs
`)
assert.NoError(t, err)
assert.NoError(t, loadLFSFrom(cfg))
- assert.EqualValues(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName)
- assert.EqualValues(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey)
- assert.EqualValues(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath)
+ assert.Equal(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName)
+ assert.Equal(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey)
+ assert.Equal(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath)
}