Make CI use a dummy password hasher for all tests (#22983)
During the recent hash algorithm change it became clear that the choice of password hash algorithm plays a role in the time taken for CI to run. Therefore as attempt to improve CI we should consider using a dummy hashing algorithm instead of a real hashing algorithm. This PR creates a dummy algorithm which is then set as the default hashing algorithm during tests that use the fixtures. This hopefully will cause a reduction in the time it takes for CI to run. --------- Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
models
modules
auth/password/hash
setting
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/go-testfixtures/testfixtures/v3"
|
||||
"xorm.io/xorm"
|
||||
@ -64,6 +66,11 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// register the dummy hash algorithm function used in the test fixtures
|
||||
_ = hash.Register("dummy", hash.NewDummyHasher)
|
||||
|
||||
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -115,5 +122,8 @@ func LoadFixtures(engine ...*xorm.Engine) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = hash.Register("dummy", hash.NewDummyHasher)
|
||||
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("argon2", NewArgon2Hasher)
|
||||
MustRegister("argon2", NewArgon2Hasher)
|
||||
}
|
||||
|
||||
// Argon2Hasher implements PasswordHasher
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("bcrypt", NewBcryptHasher)
|
||||
MustRegister("bcrypt", NewBcryptHasher)
|
||||
}
|
||||
|
||||
// BcryptHasher implements PasswordHasher
|
||||
|
33
modules/auth/password/hash/dummy.go
Normal file
33
modules/auth/password/hash/dummy.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hash
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// DummyHasher implements PasswordHasher and is a dummy hasher that simply
|
||||
// puts the password in place with its salt
|
||||
// This SHOULD NOT be used in production and is provided to make the integration
|
||||
// tests faster only
|
||||
type DummyHasher struct{}
|
||||
|
||||
// HashWithSaltBytes a provided password and salt
|
||||
func (hasher *DummyHasher) HashWithSaltBytes(password string, salt []byte) string {
|
||||
if hasher == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if len(salt) == 10 {
|
||||
return string(salt) + ":" + password
|
||||
}
|
||||
|
||||
return hex.EncodeToString(salt) + ":" + password
|
||||
}
|
||||
|
||||
// NewDummyHasher is a factory method to create a DummyHasher
|
||||
// Any provided configuration is ignored
|
||||
func NewDummyHasher(_ string) *DummyHasher {
|
||||
return &DummyHasher{}
|
||||
}
|
25
modules/auth/password/hash/dummy_test.go
Normal file
25
modules/auth/password/hash/dummy_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package hash
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDummyHasher(t *testing.T) {
|
||||
dummy := &PasswordHashAlgorithm{
|
||||
PasswordSaltHasher: NewDummyHasher(""),
|
||||
Specification: "dummy",
|
||||
}
|
||||
|
||||
password, salt := "password", "ZogKvWdyEx"
|
||||
|
||||
hash, err := dummy.Hash(password, salt)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, hash, salt+":"+password)
|
||||
|
||||
assert.True(t, dummy.VerifyPassword(password, hash, salt))
|
||||
}
|
@ -83,17 +83,26 @@ var (
|
||||
availableHasherFactories = map[string]func(string) PasswordSaltHasher{}
|
||||
)
|
||||
|
||||
// MustRegister registers a PasswordSaltHasher with the availableHasherFactories
|
||||
// Caution: This is not thread safe.
|
||||
func MustRegister[T PasswordSaltHasher](name string, newFn func(config string) T) {
|
||||
if err := Register(name, newFn); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Register registers a PasswordSaltHasher with the availableHasherFactories
|
||||
// Caution: This is not thread safe.
|
||||
func Register[T PasswordSaltHasher](name string, newFn func(config string) T) {
|
||||
func Register[T PasswordSaltHasher](name string, newFn func(config string) T) error {
|
||||
if _, has := availableHasherFactories[name]; has {
|
||||
panic(fmt.Errorf("duplicate registration of password salt hasher: %s", name))
|
||||
return fmt.Errorf("duplicate registration of password salt hasher: %s", name)
|
||||
}
|
||||
|
||||
availableHasherFactories[name] = func(config string) PasswordSaltHasher {
|
||||
n := newFn(config)
|
||||
return n
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// In early versions of gitea the password hash algorithm field of a user could be
|
||||
|
@ -19,16 +19,20 @@ func (t testSaltHasher) HashWithSaltBytes(password string, salt []byte) string {
|
||||
}
|
||||
|
||||
func Test_registerHasher(t *testing.T) {
|
||||
Register("Test_registerHasher", func(config string) testSaltHasher {
|
||||
MustRegister("Test_registerHasher", func(config string) testSaltHasher {
|
||||
return testSaltHasher(config)
|
||||
})
|
||||
|
||||
assert.Panics(t, func() {
|
||||
Register("Test_registerHasher", func(config string) testSaltHasher {
|
||||
MustRegister("Test_registerHasher", func(config string) testSaltHasher {
|
||||
return testSaltHasher(config)
|
||||
})
|
||||
})
|
||||
|
||||
assert.Error(t, Register("Test_registerHasher", func(config string) testSaltHasher {
|
||||
return testSaltHasher(config)
|
||||
}))
|
||||
|
||||
assert.Equal(t, "password$salt$",
|
||||
Parse("Test_registerHasher").PasswordSaltHasher.HashWithSaltBytes("password", []byte("salt")))
|
||||
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("pbkdf2", NewPBKDF2Hasher)
|
||||
MustRegister("pbkdf2", NewPBKDF2Hasher)
|
||||
}
|
||||
|
||||
// PBKDF2Hasher implements PasswordHasher
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("scrypt", NewScryptHasher)
|
||||
MustRegister("scrypt", NewScryptHasher)
|
||||
}
|
||||
|
||||
// ScryptHasher implements PasswordHasher
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/user"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
@ -232,6 +233,10 @@ func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
|
||||
if err := PrepareAppDataPath(); err != nil {
|
||||
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
|
||||
}
|
||||
// register the dummy hash algorithm function used in the test fixtures
|
||||
_ = hash.Register("dummy", hash.NewDummyHasher)
|
||||
|
||||
PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||
}
|
||||
|
||||
// newFileProviderFromConf initializes configuration context.
|
||||
|
Reference in New Issue
Block a user