mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-04-08 02:31:36 +02:00
Merge branch 'forgejo' of /forgejo/forgejo into report_abuse
This commit is contained in:
commit
3f28306828
31 changed files with 76 additions and 179 deletions
|
@ -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)
|
||||
|
||||
|
|
6
go.mod
6
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
|
||||
|
@ -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
|
||||
|
|
12
go.sum
12
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=
|
||||
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
1
models/fixtures/action_variable.yml
Normal file
1
models/fixtures/action_variable.yml
Normal file
|
@ -0,0 +1 @@
|
|||
[] # empty
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -390,9 +390,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
|
||||
}
|
||||
|
@ -562,13 +560,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,
|
||||
|
@ -776,9 +770,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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
"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",
|
||||
"admin.config.moderation_config": "Moderation configuration",
|
||||
"moderation.report_abuse": "Report abuse",
|
||||
"moderation.report_content": "Report content",
|
||||
|
|
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -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": "*"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue