Add early checks for user hashes.
parent
1ee442e86f
commit
716e017521
|
@ -35,8 +35,15 @@ func NewFileUserProvider(filepath string) *FileUserProvider {
|
|||
database, err := readDatabase(filepath)
|
||||
if err != nil {
|
||||
// Panic since the file does not exist when Authelia is starting.
|
||||
panic(err)
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// Early check whether hashed passwords are correct for all users
|
||||
err = checkPasswordHashes(database)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
return &FileUserProvider{
|
||||
path: &filepath,
|
||||
database: database,
|
||||
|
@ -44,24 +51,34 @@ func NewFileUserProvider(filepath string) *FileUserProvider {
|
|||
}
|
||||
}
|
||||
|
||||
func checkPasswordHashes(database *DatabaseModel) error {
|
||||
for u, v := range database.Users {
|
||||
_, err := ParseHash(v.HashedPassword)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to parse hash of user %s: %s", u, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readDatabase(path string) (*DatabaseModel, error) {
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("Unable to read database from file %s: %s", path, err)
|
||||
}
|
||||
db := DatabaseModel{}
|
||||
err = yaml.Unmarshal(content, &db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("Unable to parse database: %s", err)
|
||||
}
|
||||
|
||||
ok, err := govalidator.ValidateStruct(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("Invalid schema of database: %s", err)
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("The database format is invalid: %s", err.Error())
|
||||
return nil, fmt.Errorf("The database format is invalid: %s", err)
|
||||
}
|
||||
return &db, nil
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ func TestShouldUpdatePassword(t *testing.T) {
|
|||
|
||||
func TestShouldRaiseWhenLoadingMalformedDatabaseForFirstTime(t *testing.T) {
|
||||
WithDatabase(MalformedUserDatabaseContent, func(path string) {
|
||||
assert.Panics(t, func() {
|
||||
assert.PanicsWithValue(t, "Unable to parse database: yaml: line 4: mapping values are not allowed in this context", func() {
|
||||
NewFileUserProvider(path)
|
||||
})
|
||||
})
|
||||
|
@ -92,7 +92,15 @@ func TestShouldRaiseWhenLoadingMalformedDatabaseForFirstTime(t *testing.T) {
|
|||
|
||||
func TestShouldRaiseWhenLoadingDatabaseWithBadSchemaForFirstTime(t *testing.T) {
|
||||
WithDatabase(BadSchemaUserDatabaseContent, func(path string) {
|
||||
assert.Panics(t, func() {
|
||||
assert.PanicsWithValue(t, "Invalid schema of database: Users: non zero value required", func() {
|
||||
NewFileUserProvider(path)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestShouldRaiseWhenLoadingDatabaseWithBadHashesForTheFirstTime(t *testing.T) {
|
||||
WithDatabase(BadHashContent, func(path string) {
|
||||
assert.PanicsWithValue(t, "Unable to parse hash of user john: Cannot match pattern 'rounds=<int>' to find the number of rounds", func() {
|
||||
NewFileUserProvider(path)
|
||||
})
|
||||
})
|
||||
|
@ -165,3 +173,16 @@ users:
|
|||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
||||
`)
|
||||
|
||||
var BadHashContent = []byte(`
|
||||
users:
|
||||
john:
|
||||
password: "$6$rounds00000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
james:
|
||||
password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
||||
`)
|
||||
|
|
Loading…
Reference in New Issue