From afea42d5173702861435f491333fddfa9d15bdfa Mon Sep 17 00:00:00 2001 From: Gusted Date: Thu, 3 Apr 2025 23:42:37 +0000 Subject: [PATCH 1/6] chore: add empty `action_variable` fixture (#7419) - Ensures that this table gets emptied between integration tests and does not have any leftovers. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7419 Co-authored-by: Gusted Co-committed-by: Gusted --- models/fixtures/action_variable.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 models/fixtures/action_variable.yml diff --git a/models/fixtures/action_variable.yml b/models/fixtures/action_variable.yml new file mode 100644 index 0000000000..ca780a73aa --- /dev/null +++ b/models/fixtures/action_variable.yml @@ -0,0 +1 @@ +[] # empty From 99fc04b763d3d468e290f3b25a493dbd38b7cbc8 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 4 Apr 2025 03:30:19 +0000 Subject: [PATCH 2/6] fix: make installing Forgejo work again (#7452) - The default engine is no longer guaranteed to be of the type `*xorm.Engine`, so instead return the interface `db.Engine`. - Regression of forgejo/forgejo#7212 # Testing 1. Install a Forgejo instance via the setup screen. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7452 Reviewed-by: Earl Warren Co-authored-by: Gusted Co-committed-by: Gusted --- models/db/install/db.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/models/db/install/db.go b/models/db/install/db.go index 104a7a8e39..e64e85cf01 100644 --- a/models/db/install/db.go +++ b/models/db/install/db.go @@ -6,12 +6,10 @@ package install import ( "forgejo.org/models/db" "forgejo.org/modules/setting" - - "xorm.io/xorm" ) -func getXORMEngine() *xorm.Engine { - return db.DefaultContext.(*db.Context).Engine().(*xorm.Engine) +func getXORMEngine() db.Engine { + return db.DefaultContext.(*db.Context).Engine() } // CheckDatabaseConnection checks the database connection From 53df0bf9a4a17e32690b430cffca22776d58f246 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 4 Apr 2025 03:31:37 +0000 Subject: [PATCH 3/6] chore(sec): unify usage of `crypto/rand.Read` (#7453) - Unify the usage of [`crypto/rand.Read`](https://pkg.go.dev/crypto/rand#Read) to `util.CryptoRandomBytes`. - Refactor `util.CryptoRandomBytes` to never return an error. It is documented by Go, https://go.dev/issue/66821, to always succeed. So if we still receive a error or if the returned bytes read is not equal to the expected bytes to be read we panic (just to be on the safe side). - This simplifies a lot of code to no longer care about error handling. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7453 Reviewed-by: Earl Warren Co-authored-by: Gusted Co-committed-by: Gusted --- cmd/generate.go | 5 +---- models/actions/runner.go | 7 +------ models/actions/utils.go | 6 +----- models/auth/access_token.go | 6 +----- models/auth/auth_token.go | 5 +---- models/auth/oauth2.go | 12 ++---------- models/auth/twofactor.go | 10 +++------- models/organization/org.go | 8 ++------ models/user/email_address.go | 8 ++------ models/user/user.go | 16 ++++------------ modules/generate/generate.go | 24 +++++------------------- modules/generate/generate_test.go | 3 +-- modules/keying/keying.go | 8 +++----- modules/setting/lfs.go | 5 +---- modules/setting/oauth2.go | 10 ++-------- modules/util/util.go | 12 +++++++++--- modules/util/util_test.go | 18 ++++++++---------- options/locale_next/locale_en-US.json | 5 ++--- routers/install/install.go | 12 ++---------- routers/web/auth/2fa.go | 6 +----- routers/web/auth/auth.go | 6 +----- routers/web/auth/password.go | 8 ++------ routers/web/user/setting/security/2fa.go | 12 ++---------- tests/e2e/utils_e2e_test.go | 8 ++------ tests/integration/api_packages_test.go | 4 ++-- 25 files changed, 61 insertions(+), 163 deletions(-) diff --git a/cmd/generate.go b/cmd/generate.go index 8d3c221ec5..dcbdcd0353 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -70,10 +70,7 @@ func runGenerateInternalToken(c *cli.Context) error { } func runGenerateLfsJwtSecret(c *cli.Context) error { - _, jwtSecretBase64, err := generate.NewJwtSecret() - if err != nil { - return err - } + _, jwtSecretBase64 := generate.NewJwtSecret() fmt.Printf("%s", jwtSecretBase64) diff --git a/models/actions/runner.go b/models/actions/runner.go index ce977b49e2..4d5056b425 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -168,12 +168,7 @@ func (r *ActionRunner) GenerateToken() (err error) { // UpdateSecret updates the hash based on the specified token. It does not // ensure that the runner's UUID matches the first 16 bytes of the token. func (r *ActionRunner) UpdateSecret(token string) error { - saltBytes, err := util.CryptoRandomBytes(16) - if err != nil { - return fmt.Errorf("CryptoRandomBytes %v", err) - } - - salt := hex.EncodeToString(saltBytes) + salt := hex.EncodeToString(util.CryptoRandomBytes(16)) r.Token = token r.TokenSalt = salt diff --git a/models/actions/utils.go b/models/actions/utils.go index 7dd3f7ec12..d8e053b0ba 100644 --- a/models/actions/utils.go +++ b/models/actions/utils.go @@ -22,11 +22,7 @@ func generateSaltedToken() (string, string, string, string, error) { if err != nil { return "", "", "", "", err } - buf, err := util.CryptoRandomBytes(20) - if err != nil { - return "", "", "", "", err - } - token := hex.EncodeToString(buf) + token := hex.EncodeToString(util.CryptoRandomBytes(20)) hash := auth_model.HashToken(token, salt) return token, salt, hash, token[len(token)-8:], nil } diff --git a/models/auth/access_token.go b/models/auth/access_token.go index 31d88c6b20..695702b7a0 100644 --- a/models/auth/access_token.go +++ b/models/auth/access_token.go @@ -111,12 +111,8 @@ func generateAccessToken(t *AccessToken) error { if err != nil { return err } - token, err := util.CryptoRandomBytes(20) - if err != nil { - return err - } t.TokenSalt = salt - t.Token = hex.EncodeToString(token) + t.Token = hex.EncodeToString(util.CryptoRandomBytes(20)) t.TokenHash = HashToken(t.Token, t.TokenSalt) t.TokenLastEight = t.Token[len(t.Token)-8:] return nil diff --git a/models/auth/auth_token.go b/models/auth/auth_token.go index a3ac9c4c1a..d09aebcf85 100644 --- a/models/auth/auth_token.go +++ b/models/auth/auth_token.go @@ -63,10 +63,7 @@ func (authToken *AuthorizationToken) IsExpired() bool { func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeStamp, purpose AuthorizationPurpose) (lookupKey, validator string, err error) { // Request 64 random bytes. The first 32 bytes will be used for the lookupKey // and the other 32 bytes will be used for the validator. - rBytes, err := util.CryptoRandomBytes(64) - if err != nil { - return "", "", err - } + rBytes := util.CryptoRandomBytes(64) hexEncoded := hex.EncodeToString(rBytes) validator, lookupKey = hexEncoded[64:], hexEncoded[:64] diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index fb0a451566..fa68197cf0 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -184,13 +184,9 @@ var base32Lower = base32.NewEncoding(lowerBase32Chars).WithPadding(base32.NoPadd // GenerateClientSecret will generate the client secret and returns the plaintext and saves the hash at the database func (app *OAuth2Application) GenerateClientSecret(ctx context.Context) (string, error) { - rBytes, err := util.CryptoRandomBytes(32) - if err != nil { - return "", err - } // Add a prefix to the base32, this is in order to make it easier // for code scanners to grab sensitive tokens. - clientSecret := "gto_" + base32Lower.EncodeToString(rBytes) + clientSecret := "gto_" + base32Lower.EncodeToString(util.CryptoRandomBytes(32)) hashedSecret, err := bcrypt.GenerateFromPassword([]byte(clientSecret), bcrypt.DefaultCost) if err != nil { @@ -475,13 +471,9 @@ func (grant *OAuth2Grant) TableName() string { // GenerateNewAuthorizationCode generates a new authorization code for a grant and saves it to the database func (grant *OAuth2Grant) GenerateNewAuthorizationCode(ctx context.Context, redirectURI, codeChallenge, codeChallengeMethod string) (code *OAuth2AuthorizationCode, err error) { - rBytes, err := util.CryptoRandomBytes(32) - if err != nil { - return &OAuth2AuthorizationCode{}, err - } // Add a prefix to the base32, this is in order to make it easier // for code scanners to grab sensitive tokens. - codeSecret := "gta_" + base32Lower.EncodeToString(rBytes) + codeSecret := "gta_" + base32Lower.EncodeToString(util.CryptoRandomBytes(32)) code = &OAuth2AuthorizationCode{ Grant: grant, diff --git a/models/auth/twofactor.go b/models/auth/twofactor.go index f4c1e36b3f..fa3bc68781 100644 --- a/models/auth/twofactor.go +++ b/models/auth/twofactor.go @@ -61,17 +61,13 @@ func init() { } // GenerateScratchToken recreates the scratch token the user is using. -func (t *TwoFactor) GenerateScratchToken() (string, error) { - tokenBytes, err := util.CryptoRandomBytes(6) - if err != nil { - return "", err - } +func (t *TwoFactor) GenerateScratchToken() string { // these chars are specially chosen, avoid ambiguous chars like `0`, `O`, `1`, `I`. const base32Chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" - token := base32.NewEncoding(base32Chars).WithPadding(base32.NoPadding).EncodeToString(tokenBytes) + token := base32.NewEncoding(base32Chars).WithPadding(base32.NoPadding).EncodeToString(util.CryptoRandomBytes(6)) t.ScratchSalt, _ = util.CryptoRandomString(10) t.ScratchHash = HashToken(token, t.ScratchSalt) - return token, nil + return token } // HashToken return the hashable salt diff --git a/models/organization/org.go b/models/organization/org.go index 74eca3c2a5..ff95261051 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -289,12 +289,8 @@ func CreateOrganization(ctx context.Context, org *Organization, owner *user_mode } org.LowerName = strings.ToLower(org.Name) - if org.Rands, err = user_model.GetUserSalt(); err != nil { - return err - } - if org.Salt, err = user_model.GetUserSalt(); err != nil { - return err - } + org.Rands = user_model.GetUserSalt() + org.Salt = user_model.GetUserSalt() org.UseCustomAvatar = true org.MaxRepoCreation = -1 org.NumTeams = 1 diff --git a/models/user/email_address.go b/models/user/email_address.go index f9eaec56c9..a3c33ffc00 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -266,9 +266,7 @@ func updateActivation(ctx context.Context, email *EmailAddress, activate bool) e if err != nil { return err } - if user.Rands, err = GetUserSalt(); err != nil { - return err - } + user.Rands = GetUserSalt() email.IsActivated = activate if _, err := db.GetEngine(ctx).ID(email.ID).Cols("is_activated").Update(email); err != nil { return err @@ -403,9 +401,7 @@ func ActivateUserEmail(ctx context.Context, userID int64, email string, activate // The user's activation state should be synchronized with the primary email if user.IsActive != activate { user.IsActive = activate - if user.Rands, err = GetUserSalt(); err != nil { - return fmt.Errorf("unable to generate salt: %w", err) - } + user.Rands = GetUserSalt() if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) } diff --git a/models/user/user.go b/models/user/user.go index 900878768e..26074a0998 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -387,9 +387,7 @@ func (u *User) SetPassword(passwd string) (err error) { return err } - if u.Salt, err = GetUserSalt(); err != nil { - return err - } + u.Salt = GetUserSalt() if u.Passwd, err = hash.Parse(setting.PasswordHashAlgo).Hash(passwd, u.Salt); err != nil { return err } @@ -559,13 +557,9 @@ func IsUserExist(ctx context.Context, uid int64, name string) (bool, error) { const SaltByteLength = 16 // GetUserSalt returns a random user salt token. -func GetUserSalt() (string, error) { - rBytes, err := util.CryptoRandomBytes(SaltByteLength) - if err != nil { - return "", err - } +func GetUserSalt() string { // Returns a 32 bytes long string. - return hex.EncodeToString(rBytes), nil + return hex.EncodeToString(util.CryptoRandomBytes(SaltByteLength)) } // Note: The set of characters here can safely expand without a breaking change, @@ -772,9 +766,7 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa u.LowerName = strings.ToLower(u.Name) u.AvatarEmail = u.Email - if u.Rands, err = GetUserSalt(); err != nil { - return err - } + u.Rands = GetUserSalt() if u.Passwd != "" { if err = u.SetPassword(u.Passwd); err != nil { return err diff --git a/modules/generate/generate.go b/modules/generate/generate.go index 9738195da9..16a797ef5a 100644 --- a/modules/generate/generate.go +++ b/modules/generate/generate.go @@ -5,10 +5,8 @@ package generate import ( - "crypto/rand" "encoding/base64" "fmt" - "io" "time" "forgejo.org/modules/util" @@ -18,18 +16,11 @@ import ( // NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN. func NewInternalToken() (string, error) { - secretBytes := make([]byte, 32) - _, err := io.ReadFull(rand.Reader, secretBytes) - if err != nil { - return "", err - } - - secretKey := base64.RawURLEncoding.EncodeToString(secretBytes) + secretKey := base64.RawURLEncoding.EncodeToString(util.CryptoRandomBytes(32)) now := time.Now() - var internalToken string - internalToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + internalToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "nbf": now.Unix(), }).SignedString([]byte(secretKey)) if err != nil { @@ -54,14 +45,9 @@ func DecodeJwtSecret(src string) ([]byte, error) { } // NewJwtSecret generates a new base64 encoded value intended to be used for JWT secrets. -func NewJwtSecret() ([]byte, string, error) { - bytes := make([]byte, 32) - _, err := rand.Read(bytes) - if err != nil { - return nil, "", err - } - - return bytes, base64.RawURLEncoding.EncodeToString(bytes), nil +func NewJwtSecret() ([]byte, string) { + bytes := util.CryptoRandomBytes(32) + return bytes, base64.RawURLEncoding.EncodeToString(bytes) } // NewSecretKey generate a new value intended to be used by SECRET_KEY. diff --git a/modules/generate/generate_test.go b/modules/generate/generate_test.go index eb7178af33..b51d17deb2 100644 --- a/modules/generate/generate_test.go +++ b/modules/generate/generate_test.go @@ -26,8 +26,7 @@ func TestDecodeJwtSecret(t *testing.T) { } func TestNewJwtSecret(t *testing.T) { - secret, encoded, err := NewJwtSecret() - require.NoError(t, err) + secret, encoded := NewJwtSecret() assert.Len(t, secret, 32) decoded, err := DecodeJwtSecret(encoded) require.NoError(t, err) diff --git a/modules/keying/keying.go b/modules/keying/keying.go index 30c664180c..c859e30e9f 100644 --- a/modules/keying/keying.go +++ b/modules/keying/keying.go @@ -17,10 +17,11 @@ package keying import ( "crypto/hkdf" - "crypto/rand" "crypto/sha256" "encoding/binary" + "forgejo.org/modules/util" + "golang.org/x/crypto/chacha20poly1305" ) @@ -95,10 +96,7 @@ func (k *Key) Encrypt(plaintext, additionalData []byte) []byte { } // Generate a random nonce. - nonce := make([]byte, aeadNonceSize) - if n, err := rand.Read(nonce); err != nil || n != aeadNonceSize { - panic(err) - } + nonce := util.CryptoRandomBytes(aeadNonceSize) // Returns the ciphertext of this plaintext. return e.Seal(nonce, nonce, plaintext, additionalData) diff --git a/modules/setting/lfs.go b/modules/setting/lfs.go index 3cd48c538b..452bfae737 100644 --- a/modules/setting/lfs.go +++ b/modules/setting/lfs.go @@ -80,10 +80,7 @@ func loadLFSFrom(rootCfg ConfigProvider) error { jwtSecretBase64 := loadSecret(rootCfg.Section("server"), "LFS_JWT_SECRET_URI", "LFS_JWT_SECRET") LFS.JWTSecretBytes, err = generate.DecodeJwtSecret(jwtSecretBase64) if err != nil { - LFS.JWTSecretBytes, jwtSecretBase64, err = generate.NewJwtSecret() - if err != nil { - return fmt.Errorf("error generating JWT Secret for custom config: %v", err) - } + LFS.JWTSecretBytes, jwtSecretBase64 = generate.NewJwtSecret() // Save secret saveCfg, err := rootCfg.PrepareSaving() diff --git a/modules/setting/oauth2.go b/modules/setting/oauth2.go index 72500cfc89..9e95e1c6a9 100644 --- a/modules/setting/oauth2.go +++ b/modules/setting/oauth2.go @@ -138,10 +138,7 @@ func loadOAuth2From(rootCfg ConfigProvider) { if InstallLock { jwtSecretBytes, err := generate.DecodeJwtSecret(jwtSecretBase64) if err != nil { - jwtSecretBytes, jwtSecretBase64, err = generate.NewJwtSecret() - if err != nil { - log.Fatal("error generating JWT secret: %v", err) - } + jwtSecretBytes, jwtSecretBase64 = generate.NewJwtSecret() saveCfg, err := rootCfg.PrepareSaving() if err != nil { log.Fatal("save oauth2.JWT_SECRET failed: %v", err) @@ -161,10 +158,7 @@ var generalSigningSecret atomic.Pointer[[]byte] func GetGeneralTokenSigningSecret() []byte { old := generalSigningSecret.Load() if old == nil || len(*old) == 0 { - jwtSecret, _, err := generate.NewJwtSecret() - if err != nil { - log.Fatal("Unable to generate general JWT secret: %v", err) - } + jwtSecret, _ := generate.NewJwtSecret() if generalSigningSecret.CompareAndSwap(old, &jwtSecret) { return jwtSecret } diff --git a/modules/util/util.go b/modules/util/util.go index fc3fcc35f0..548fd1e90b 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -88,10 +88,16 @@ func CryptoRandomString(length int64) (string, error) { // CryptoRandomBytes generates `length` crypto bytes // This differs from CryptoRandomString, as each byte in CryptoRandomString is generated by [0,61] range // This function generates totally random bytes, each byte is generated by [0,255] range -func CryptoRandomBytes(length int64) ([]byte, error) { +func CryptoRandomBytes(length int64) []byte { + // crypto/rand.Read is documented to never return a error. + // https://go.dev/issue/66821 buf := make([]byte, length) - _, err := rand.Read(buf) - return buf, err + n, err := rand.Read(buf) + if err != nil || n != int(length) { + panic(err) + } + + return buf } // ToUpperASCII returns s with all ASCII letters mapped to their upper case. diff --git a/modules/util/util_test.go b/modules/util/util_test.go index 61f98de88a..21988fd0f8 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -163,20 +163,18 @@ func Test_RandomString(t *testing.T) { } func Test_RandomBytes(t *testing.T) { - bytes1, err := util.CryptoRandomBytes(32) - require.NoError(t, err) - - bytes2, err := util.CryptoRandomBytes(32) - require.NoError(t, err) + bytes1 := util.CryptoRandomBytes(32) + bytes2 := util.CryptoRandomBytes(32) + assert.Len(t, bytes1, 32) + assert.Len(t, bytes2, 32) assert.NotEqual(t, bytes1, bytes2) - bytes3, err := util.CryptoRandomBytes(256) - require.NoError(t, err) - - bytes4, err := util.CryptoRandomBytes(256) - require.NoError(t, err) + bytes3 := util.CryptoRandomBytes(256) + bytes4 := util.CryptoRandomBytes(256) + assert.Len(t, bytes3, 256) + assert.Len(t, bytes4, 256) assert.NotEqual(t, bytes3, bytes4) } diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json index e24c1a5bee..9b27c39379 100644 --- a/options/locale_next/locale_en-US.json +++ b/options/locale_next/locale_en-US.json @@ -20,6 +20,5 @@ "error.not_found.title": "Page not found", "alert.asset_load_failed": "Failed to load asset files from {path}. Please make sure the asset files can be accessed.", "alert.range_error": " must be a number between %[1]s and %[2]s.", - "install.invalid_lfs_path": "Unable to create the LFS root at the specified path: %[1]s", - "install.lfs_jwt_secret_failed": "Unable to generate a LFS JWT secret: %[1]s" -} \ No newline at end of file + "install.invalid_lfs_path": "Unable to create the LFS root at the specified path: %[1]s" +} diff --git a/routers/install/install.go b/routers/install/install.go index ace0b2c8ed..f64f395a7f 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -408,11 +408,7 @@ func SubmitInstall(ctx *context.Context) { if form.LFSRootPath != "" { cfg.Section("server").Key("LFS_START_SERVER").SetValue("true") cfg.Section("lfs").Key("PATH").SetValue(form.LFSRootPath) - var lfsJwtSecret string - if _, lfsJwtSecret, err = generate.NewJwtSecret(); err != nil { - ctx.RenderWithErr(ctx.Tr("install.lfs_jwt_secret_failed", err), tplInstall, &form) - return - } + _, lfsJwtSecret := generate.NewJwtSecret() cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(lfsJwtSecret) } else { cfg.Section("server").Key("LFS_START_SERVER").SetValue("false") @@ -483,11 +479,7 @@ func SubmitInstall(ctx *context.Context) { // FIXME: at the moment, no matter oauth2 is enabled or not, it must generate a "oauth2 JWT_SECRET" // see the "loadOAuth2From" in "setting/oauth2.go" if !cfg.Section("oauth2").HasKey("JWT_SECRET") && !cfg.Section("oauth2").HasKey("JWT_SECRET_URI") { - _, jwtSecretBase64, err := generate.NewJwtSecret() - if err != nil { - ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), tplInstall, &form) - return - } + _, jwtSecretBase64 := generate.NewJwtSecret() cfg.Section("oauth2").Key("JWT_SECRET").SetValue(jwtSecretBase64) } diff --git a/routers/web/auth/2fa.go b/routers/web/auth/2fa.go index 7acf9a87d3..ff769ffd5d 100644 --- a/routers/web/auth/2fa.go +++ b/routers/web/auth/2fa.go @@ -133,11 +133,7 @@ func TwoFactorScratchPost(ctx *context.Context) { // Validate the passcode with the stored TOTP secret. if twofa.VerifyScratchToken(form.Token) { // Invalidate the scratch token. - _, err = twofa.GenerateScratchToken() - if err != nil { - ctx.ServerError("UserSignIn", err) - return - } + twofa.GenerateScratchToken() if err = auth.UpdateTwoFactor(ctx, twofa); err != nil { ctx.ServerError("UserSignIn", err) return diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 39d86adb8c..722091a606 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -784,11 +784,7 @@ func ActivatePost(ctx *context.Context) { func handleAccountActivation(ctx *context.Context, user *user_model.User) { user.IsActive = true - var err error - if user.Rands, err = user_model.GetUserSalt(); err != nil { - ctx.ServerError("UpdateUser", err) - return - } + user.Rands = user_model.GetUserSalt() if err := user_model.UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { if user_model.IsErrUserNotExist(err) { ctx.NotFound("UpdateUserCols", err) diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index 82c2d4e9d3..cb6b22e5b7 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -242,12 +242,8 @@ func ResetPasswdPost(ctx *context.Context) { if regenerateScratchToken { // Invalidate the scratch token. - _, err := twofa.GenerateScratchToken() - if err != nil { - ctx.ServerError("UserSignIn", err) - return - } - if err = auth.UpdateTwoFactor(ctx, twofa); err != nil { + twofa.GenerateScratchToken() + if err := auth.UpdateTwoFactor(ctx, twofa); err != nil { ctx.ServerError("UserSignIn", err) return } diff --git a/routers/web/user/setting/security/2fa.go b/routers/web/user/setting/security/2fa.go index f1271c8370..8b362c4f08 100644 --- a/routers/web/user/setting/security/2fa.go +++ b/routers/web/user/setting/security/2fa.go @@ -40,11 +40,7 @@ func RegenerateScratchTwoFactor(ctx *context.Context) { return } - token, err := t.GenerateScratchToken() - if err != nil { - ctx.ServerError("SettingsTwoFactor: Failed to GenerateScratchToken", err) - return - } + token := t.GenerateScratchToken() if err = auth.UpdateTwoFactor(ctx, t); err != nil { ctx.ServerError("SettingsTwoFactor: Failed to UpdateTwoFactor", err) @@ -220,11 +216,7 @@ func EnrollTwoFactorPost(ctx *context.Context) { t = &auth.TwoFactor{ UID: ctx.Doer.ID, } - token, err := t.GenerateScratchToken() - if err != nil { - ctx.ServerError("SettingsTwoFactor: Failed to generate scratch token", err) - return - } + token := t.GenerateScratchToken() // Now we have to delete the secrets - because if we fail to insert then it's highly likely that they have already been used // If we can detect the unique constraint failure below we can move this to after the NewTwoFactor diff --git a/tests/e2e/utils_e2e_test.go b/tests/e2e/utils_e2e_test.go index d57c7bc2d3..f892d6c518 100644 --- a/tests/e2e/utils_e2e_test.go +++ b/tests/e2e/utils_e2e_test.go @@ -5,7 +5,6 @@ package e2e import ( "context" - "crypto/rand" "encoding/hex" "fmt" "net" @@ -23,6 +22,7 @@ import ( "forgejo.org/modules/json" modules_session "forgejo.org/modules/session" "forgejo.org/modules/setting" + "forgejo.org/modules/util" "forgejo.org/tests" "code.forgejo.org/go-chi/session" @@ -153,11 +153,7 @@ func stateHelper(t testing.TB) func(stateFile string, user *user_model.User) { require.NoError(t, err) return func(stateFile string, user *user_model.User) { - buf := make([]byte, opt.IDLength/2) - _, err = rand.Read(buf) - require.NoError(t, err) - - sessionID := hex.EncodeToString(buf) + sessionID := hex.EncodeToString(util.CryptoRandomBytes(int64(opt.IDLength) / 2)) s, err := vsp.Read(sessionID) require.NoError(t, err) diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index 814d026b91..9f8115f505 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -486,7 +486,7 @@ func TestPackageCleanup(t *testing.T) { defer tests.PrintCurrentTest(t)() // Upload and delete a generic package and upload a container blob - data, _ := util.CryptoRandomBytes(5) + data := util.CryptoRandomBytes(5) url := fmt.Sprintf("/api/packages/%s/generic/cleanup-test/1.1.1/file.bin", user.Name) req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(data)). AddBasicAuth(user.Name) @@ -496,7 +496,7 @@ func TestPackageCleanup(t *testing.T) { AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) - data, _ = util.CryptoRandomBytes(5) + data = util.CryptoRandomBytes(5) url = fmt.Sprintf("/v2/%s/cleanup-test/blobs/uploads?digest=sha256:%x", user.Name, sha256.Sum256(data)) req = NewRequestWithBody(t, "POST", url, bytes.NewReader(data)). AddBasicAuth(user.Name) From d688ca4515e2accaaa0f1c9789820e7a30954286 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 4 Apr 2025 03:49:54 +0000 Subject: [PATCH 4/6] Update module code.gitea.io/sdk/gitea to v0.21.0 (forgejo) (#7458) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | code.gitea.io/sdk/gitea | require | minor | `v0.20.0` -> `v0.21.0` | --- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7458 Reviewed-by: Earl Warren Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bb34c3cec5..3140b1c3e6 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( code.forgejo.org/go-chi/captcha v1.0.1 code.forgejo.org/go-chi/session v1.0.1 code.gitea.io/actions-proto-go v0.4.0 - code.gitea.io/sdk/gitea v0.20.0 + code.gitea.io/sdk/gitea v0.21.0 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 connectrpc.com/connect v1.17.0 github.com/42wim/httpsig v1.2.2 diff --git a/go.sum b/go.sum index 19f7c8ecd2..dd8e4ca8a8 100644 --- a/go.sum +++ b/go.sum @@ -636,8 +636,8 @@ code.forgejo.org/go-chi/session v1.0.1 h1:RNkcJQZJBqlvJoIFXSth87b3kMFZLDBA18Vcit code.forgejo.org/go-chi/session v1.0.1/go.mod h1:y69sjS984wc7k4xyu77yNE5HKeSlBoQW8VSGdsK7RAs= code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU= code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas= -code.gitea.io/sdk/gitea v0.20.0 h1:Zm/QDwwZK1awoM4AxdjeAQbxolzx2rIP8dDfmKu+KoU= -code.gitea.io/sdk/gitea v0.20.0/go.mod h1:faouBHC/zyx5wLgjmRKR62ydyvMzwWf3QnU0bH7Cw6U= +code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4= +code.gitea.io/sdk/gitea v0.21.0/go.mod h1:tnBjVhuKJCn8ibdyyhvUyxrR1Ca2KHEoTWoukNhXQPA= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM= connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= From a0df27c9295fba80868f219515bc82e7adba265e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 4 Apr 2025 03:52:13 +0000 Subject: [PATCH 5/6] Update module github.com/alecthomas/chroma/v2 to v2.16.0 (forgejo) (#7459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [github.com/alecthomas/chroma/v2](https://github.com/alecthomas/chroma) | require | minor | `v2.15.0` -> `v2.16.0` | --- ### Release Notes
alecthomas/chroma (github.com/alecthomas/chroma/v2) ### [`v2.16.0`](https://github.com/alecthomas/chroma/releases/tag/v2.16.0) [Compare Source](https://github.com/alecthomas/chroma/compare/v2.15.0...v2.16.0) #### Changelog - [`ad6f149`](https://github.com/alecthomas/chroma/commit/ad6f149) chore: clean up Makefile - [`9909f65`](https://github.com/alecthomas/chroma/commit/9909f65) fix: switch to jsdelivr as unpkg was throwing CORS errors - [`34bf362`](https://github.com/alecthomas/chroma/commit/34bf362) chore(deps): update all non-major dependencies ([#​1066](https://github.com/alecthomas/chroma/issues/1066)) - [`88084b6`](https://github.com/alecthomas/chroma/commit/88084b6) fix: Dot in a string breaks the highlighting in Terraform. Fixes [#​988](https://github.com/alecthomas/chroma/issues/988) ([#​1065](https://github.com/alecthomas/chroma/issues/1065)) - [`62197e9`](https://github.com/alecthomas/chroma/commit/62197e9) Add lexers.Aliases() method to display only lexers' aliases ([#​1057](https://github.com/alecthomas/chroma/issues/1057)) - [`7feb358`](https://github.com/alecthomas/chroma/commit/7feb358) chore(deps): update dependency svu to v3 ([#​1053](https://github.com/alecthomas/chroma/issues/1053)) - [`30e0bc6`](https://github.com/alecthomas/chroma/commit/30e0bc6) chore(deps): update all non-major dependencies ([#​1061](https://github.com/alecthomas/chroma/issues/1061)) - [`e0c7747`](https://github.com/alecthomas/chroma/commit/e0c7747) Fix IP address as name detection in nginx conf ([#​1060](https://github.com/alecthomas/chroma/issues/1060)) - [`0bf0e9f`](https://github.com/alecthomas/chroma/commit/0bf0e9f) Add luau file extension and alias to lua lexer ([#​1056](https://github.com/alecthomas/chroma/issues/1056)) - [`0e0e282`](https://github.com/alecthomas/chroma/commit/0e0e282) chore(deps): update all non-major dependencies ([#​1049](https://github.com/alecthomas/chroma/issues/1049)) - [`4b0882a`](https://github.com/alecthomas/chroma/commit/4b0882a) add Janet lexer ([#​1045](https://github.com/alecthomas/chroma/issues/1045)) - [`81fecd5`](https://github.com/alecthomas/chroma/commit/81fecd5) chore(deps): update all non-major dependencies ([#​1041](https://github.com/alecthomas/chroma/issues/1041)) - [`dc982d2`](https://github.com/alecthomas/chroma/commit/dc982d2) Add Mojo lexer ([#​1044](https://github.com/alecthomas/chroma/issues/1044)) - [`79621af`](https://github.com/alecthomas/chroma/commit/79621af) Fix solidity lexer's handling of inline assembly ([#​1040](https://github.com/alecthomas/chroma/issues/1040)) - [`9da461e`](https://github.com/alecthomas/chroma/commit/9da461e) chore(deps): update module github.com/mattn/go-colorable to v0.1.14 ([#​1039](https://github.com/alecthomas/chroma/issues/1039)) - [`f0d460e`](https://github.com/alecthomas/chroma/commit/f0d460e) Update Odin lexer for new build tag feature ([#​1038](https://github.com/alecthomas/chroma/issues/1038)) - [`0bd7c68`](https://github.com/alecthomas/chroma/commit/0bd7c68) chore: bump go.mod to Go 1.22 + add Iterator.Stdlib() - [`d829579`](https://github.com/alecthomas/chroma/commit/d829579) fix(ocaml): support multistring ([#​1035](https://github.com/alecthomas/chroma/issues/1035)) - [`e79c813`](https://github.com/alecthomas/chroma/commit/e79c813) chore(deps): update all non-major dependencies ([#​1029](https://github.com/alecthomas/chroma/issues/1029))
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7459 Reviewed-by: Earl Warren Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3140b1c3e6..12caf738bb 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/ProtonMail/go-crypto v1.1.6 github.com/PuerkitoBio/goquery v1.10.2 github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2 - github.com/alecthomas/chroma/v2 v2.15.0 + github.com/alecthomas/chroma/v2 v2.16.0 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.4.4 github.com/buildkite/terminal-to-html/v3 v3.16.8 @@ -170,7 +170,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/dlclark/regexp2 v1.11.4 // indirect + github.com/dlclark/regexp2 v1.11.5 // indirect github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect diff --git a/go.sum b/go.sum index dd8e4ca8a8..61de25c8ea 100644 --- a/go.sum +++ b/go.sum @@ -691,8 +691,8 @@ github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGW github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc= -github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio= +github.com/alecthomas/chroma/v2 v2.16.0 h1:QC5ZMizk67+HzxFDjQ4ASjni5kWBTGiigRG1u23IGvA= +github.com/alecthomas/chroma/v2 v2.16.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= @@ -835,8 +835,8 @@ github.com/djherbis/nio/v3 v3.0.1/go.mod h1:Ng4h80pbZFMla1yKzm61cF0tqqilXZYrogmW github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= -github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4= From c977585e4c83862d809a5d574d306e84d2b6860a Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 4 Apr 2025 04:04:58 +0000 Subject: [PATCH 6/6] Update dependency ansi_up to v6.0.3 (forgejo) (#7456) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7456 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e292568a83..58ae7c5880 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@github/text-expander-element": "2.8.0", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", - "ansi_up": "6.0.2", + "ansi_up": "6.0.3", "asciinema-player": "3.8.2", "chart.js": "4.4.5", "chartjs-adapter-dayjs-4": "1.0.4", @@ -4155,9 +4155,9 @@ } }, "node_modules/ansi_up": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.2.tgz", - "integrity": "sha512-3G3vKvl1ilEp7J1u6BmULpMA0xVoW/f4Ekqhl8RTrJrhEBkonKn5k3bUc5Xt+qDayA6iDX0jyUh3AbZjB/l0tw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.3.tgz", + "integrity": "sha512-V1t1pcsMkgdqwbtZGbqI732rb8u9X2GzcT3PAThzo/zMQSkoT4AGnRUnI/7fIOWMaL5c/8EE00VywATsjtIDbw==", "license": "MIT", "engines": { "node": "*" diff --git a/package.json b/package.json index a7e56a7d9e..34486e8d5a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@github/text-expander-element": "2.8.0", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", - "ansi_up": "6.0.2", + "ansi_up": "6.0.3", "asciinema-player": "3.8.2", "chart.js": "4.4.5", "chartjs-adapter-dayjs-4": "1.0.4",