Merge pull request '[gitea] week 2024-21 cherry pick (gitea/main -> forgejo)' (#3838) from algernon/wcp/2024-21 into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3838
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
This commit is contained in:
Earl Warren 2024-05-21 08:05:01 +00:00
commit 74e07656d2
38 changed files with 2184 additions and 462 deletions

View file

@ -124,16 +124,15 @@ func loadOAuth2From(rootCfg ConfigProvider) {
OAuth2.Enabled = sec.Key("ENABLE").MustBool(OAuth2.Enabled)
}
if !OAuth2.Enabled {
return
}
jwtSecretBase64 := loadSecret(sec, "JWT_SECRET_URI", "JWT_SECRET")
if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) {
OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile)
}
// FIXME: at the moment, no matter oauth2 is enabled or not, it must generate a "oauth2 JWT_SECRET"
// Because this secret is also used as GeneralTokenSigningSecret (as a quick not-that-breaking fix for some legacy problems).
// Including: CSRF token, account validation token, etc ...
// In main branch, the signing token should be refactored (eg: one unique for LFS/OAuth2/etc ...)
jwtSecretBase64 := loadSecret(sec, "JWT_SECRET_URI", "JWT_SECRET")
if InstallLock {
jwtSecretBytes, err := generate.DecodeJwtSecret(jwtSecretBase64)
if err != nil {
@ -155,8 +154,6 @@ func loadOAuth2From(rootCfg ConfigProvider) {
}
}
// generalSigningSecret is used as container for a []byte value
// instead of an additional mutex, we use CompareAndSwap func to change the value thread save
var generalSigningSecret atomic.Pointer[[]byte]
func GetGeneralTokenSigningSecret() []byte {
@ -164,11 +161,9 @@ func GetGeneralTokenSigningSecret() []byte {
if old == nil || len(*old) == 0 {
jwtSecret, _, err := generate.NewJwtSecret()
if err != nil {
log.Fatal("Unable to generate general JWT secret: %s", err.Error())
log.Fatal("Unable to generate general JWT secret: %v", err)
}
if generalSigningSecret.CompareAndSwap(old, &jwtSecret) {
// FIXME: in main branch, the signing token should be refactored (eg: one unique for LFS/OAuth2/etc ...)
log.Warn("OAuth2 is not enabled, unable to use a persistent signing secret, a new one is generated, which is not persistent between restarts and cluster nodes")
return jwtSecret
}
return *generalSigningSecret.Load()

View file

@ -4,6 +4,7 @@
package setting
import (
"os"
"testing"
"code.gitea.io/gitea/modules/generate"
@ -14,7 +15,7 @@ import (
func TestGetGeneralSigningSecret(t *testing.T) {
// when there is no general signing secret, it should be generated, and keep the same value
assert.Nil(t, generalSigningSecret.Load())
generalSigningSecret.Store(nil)
s1 := GetGeneralTokenSigningSecret()
assert.NotNil(t, s1)
s2 := GetGeneralTokenSigningSecret()
@ -32,3 +33,28 @@ JWT_SECRET = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
assert.Len(t, actual, 32)
assert.EqualValues(t, expected, actual)
}
func TestGetGeneralSigningSecretSave(t *testing.T) {
defer test.MockVariableValue(&InstallLock, true)()
old := GetGeneralTokenSigningSecret()
assert.Len(t, old, 32)
tmpFile := t.TempDir() + "/app.ini"
_ = os.WriteFile(tmpFile, nil, 0o644)
cfg, _ := NewConfigProviderFromFile(tmpFile)
loadOAuth2From(cfg)
generated := GetGeneralTokenSigningSecret()
assert.Len(t, generated, 32)
assert.NotEqual(t, old, generated)
generalSigningSecret.Store(nil)
cfg, _ = NewConfigProviderFromFile(tmpFile)
loadOAuth2From(cfg)
again := GetGeneralTokenSigningSecret()
assert.Equal(t, generated, again)
iniContent, err := os.ReadFile(tmpFile)
assert.NoError(t, err)
assert.Contains(t, string(iniContent), "JWT_SECRET = ")
}

View file

@ -57,8 +57,9 @@ type DeleteLabelsOption struct {
// IssueLabelsOption a collection of labels
type IssueLabelsOption struct {
// list of label IDs
Labels []int64 `json:"labels"`
// Labels can be a list of integers representing label IDs
// or a list of strings representing label names
Labels []any `json:"labels"`
// swagger:strfmt date-time
Updated *time.Time `json:"updated_at"`
}

View file

@ -230,7 +230,7 @@ type EditRepoOption struct {
Archived *bool `json:"archived,omitempty"`
// set to a string like `8h30m0s` to set the mirror interval time
MirrorInterval *string `json:"mirror_interval,omitempty"`
// enable prune - remove obsolete remote-tracking references
// enable prune - remove obsolete remote-tracking references when mirroring
EnablePrune *bool `json:"enable_prune,omitempty"`
}