Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d39e0f2bb5 |
No files matched your search
+1
-5
@@ -14,10 +14,6 @@ var errNoPassword = errors.New(
|
||||
"account has no password set",
|
||||
)
|
||||
|
||||
// PasswordCost is the bcrypt cost at which SetPassword hashes a
|
||||
// password. Tests lower it to bcrypt.MinCost before they start.
|
||||
var PasswordCost = bcrypt.DefaultCost //nolint:gochecknoglobals // tests lower it
|
||||
|
||||
// SetPassword sets a bcrypt-hashed password on a session,
|
||||
// enabling multi-client login via POST /api/v1/login.
|
||||
func (database *Database) SetPassword(
|
||||
@@ -26,7 +22,7 @@ func (database *Database) SetPassword(
|
||||
password string,
|
||||
) error {
|
||||
hash, err := bcrypt.GenerateFromPassword(
|
||||
[]byte(password), PasswordCost,
|
||||
[]byte(password), database.passwordCost,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("hash password: %w", err)
|
||||
|
||||
+18
-5
@@ -15,6 +15,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"sneak.berlin/go/neoirc/internal/config"
|
||||
"sneak.berlin/go/neoirc/internal/logger"
|
||||
|
||||
@@ -39,13 +40,19 @@ type Params struct {
|
||||
|
||||
Logger *logger.Logger
|
||||
Config *config.Config
|
||||
|
||||
// PasswordCost is the bcrypt cost at which SetPassword hashes
|
||||
// a password. The server leaves it unset, which means
|
||||
// bcrypt.DefaultCost. Tests set a lower cost to save time.
|
||||
PasswordCost int `optional:"true"`
|
||||
}
|
||||
|
||||
// Database manages the SQLite connection and migrations.
|
||||
type Database struct {
|
||||
conn *sql.DB
|
||||
log *slog.Logger
|
||||
params *Params
|
||||
conn *sql.DB
|
||||
log *slog.Logger
|
||||
params *Params
|
||||
passwordCost int
|
||||
}
|
||||
|
||||
// New creates a new Database and registers lifecycle hooks.
|
||||
@@ -53,9 +60,15 @@ func New(
|
||||
lifecycle fx.Lifecycle,
|
||||
params Params,
|
||||
) (*Database, error) {
|
||||
passwordCost := params.PasswordCost
|
||||
if passwordCost == 0 {
|
||||
passwordCost = bcrypt.DefaultCost
|
||||
}
|
||||
|
||||
database := &Database{ //nolint:exhaustruct // conn set in OnStart
|
||||
params: ¶ms,
|
||||
log: params.Logger.Get(),
|
||||
params: ¶ms,
|
||||
log: params.Logger.Get(),
|
||||
passwordCost: passwordCost,
|
||||
}
|
||||
|
||||
database.log.Info("Database instantiated")
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"go.uber.org/fx/fxtest"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"sneak.berlin/go/neoirc/internal/config"
|
||||
"sneak.berlin/go/neoirc/internal/db"
|
||||
"sneak.berlin/go/neoirc/internal/dbtest"
|
||||
@@ -30,13 +29,6 @@ const (
|
||||
endlessQueryTimeout = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// A password hashed at full cost takes seconds under -race.
|
||||
db.PasswordCost = bcrypt.MinCost
|
||||
|
||||
m.Run()
|
||||
}
|
||||
|
||||
// TestDefaultDBURLSetsWALAndBusyTimeout opens a file database
|
||||
// with the default URL's parameters the way the server does,
|
||||
// and checks the journal mode and busy timeout it ends up with.
|
||||
|
||||
@@ -8,10 +8,12 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"sneak.berlin/go/neoirc/internal/dbtest"
|
||||
)
|
||||
|
||||
// NewTestDatabase creates an in-memory database for testing.
|
||||
// NewTestDatabase creates an in-memory database for testing. It
|
||||
// hashes passwords at bcrypt.MinCost.
|
||||
func NewTestDatabase(tb testing.TB) (*Database, error) {
|
||||
tb.Helper()
|
||||
|
||||
@@ -23,8 +25,9 @@ func NewTestDatabase(tb testing.TB) (*Database, error) {
|
||||
}
|
||||
|
||||
database := &Database{ //nolint:exhaustruct // test helper, params not needed
|
||||
conn: conn,
|
||||
log: slog.Default(),
|
||||
conn: conn,
|
||||
log: slog.Default(),
|
||||
passwordCost: bcrypt.MinCost,
|
||||
}
|
||||
|
||||
err = database.runMigrations(context.Background())
|
||||
|
||||
@@ -47,9 +47,6 @@ import (
|
||||
const templateDBURL = "file:template?mode=memory&cache=shared"
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// A password hashed at full cost takes seconds under -race.
|
||||
db.PasswordCost = bcrypt.MinCost
|
||||
|
||||
template := fx.New(
|
||||
fx.NopLogger,
|
||||
fx.Supply(
|
||||
@@ -237,7 +234,7 @@ func newTestDB(
|
||||
cfg *config.Config,
|
||||
) (*db.Database, error) {
|
||||
database, err := db.New(lifecycle, db.Params{ //nolint:exhaustruct
|
||||
Logger: log, Config: cfg,
|
||||
Logger: log, Config: cfg, PasswordCost: bcrypt.MinCost,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("test db: %w", err)
|
||||
|
||||
@@ -39,13 +39,6 @@ const testTimeout = 5 * time.Second
|
||||
// notification, and a test fails when one is missing.
|
||||
const testPollInterval = time.Hour
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// A password hashed at full cost takes seconds under -race.
|
||||
db.PasswordCost = bcrypt.MinCost
|
||||
|
||||
m.Run()
|
||||
}
|
||||
|
||||
// testEnv holds the shared test infrastructure.
|
||||
type testEnv struct {
|
||||
dbURL string
|
||||
@@ -133,8 +126,9 @@ func newTestEnvWithResolver(
|
||||
}
|
||||
|
||||
database, err := db.New(lifecycle, db.Params{
|
||||
Logger: dbLog,
|
||||
Config: &config.Config{DBURL: dbURL},
|
||||
Logger: dbLog,
|
||||
Config: &config.Config{DBURL: dbURL},
|
||||
PasswordCost: bcrypt.MinCost,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("new database: %v", err)
|
||||
|
||||
Reference in new issue
Block a user