|
|
|
|
@ -115,3 +115,116 @@ func TestRepository_Authenticate(t *testing.T) {
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRepository_AuthenticateRehash(t *testing.T) {
|
|
|
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
|
|
|
rw := db.New(conn)
|
|
|
|
|
wrapper := db.TestWrapper(t)
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
|
|
|
|
|
authMethods := testAuthMethods(t, conn, 1)
|
|
|
|
|
authMethod := authMethods[0]
|
|
|
|
|
authMethodId := authMethod.GetPublicId()
|
|
|
|
|
userName := "kazmierczak"
|
|
|
|
|
passwd := "12345678"
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
|
|
repo, err := NewRepository(rw, rw, wrapper)
|
|
|
|
|
assert.NoError(err)
|
|
|
|
|
require.NotNil(repo)
|
|
|
|
|
|
|
|
|
|
// Get the default (original) argon2 configuration
|
|
|
|
|
origConf, err := repo.GetConfiguration(ctx, authMethodId)
|
|
|
|
|
assert.NoError(err)
|
|
|
|
|
require.NotNil(origConf)
|
|
|
|
|
origArgonConf, ok := origConf.(*Argon2Configuration)
|
|
|
|
|
require.True(ok, "want *Argon2Configuration")
|
|
|
|
|
require.NotEmpty(origArgonConf.PrivateId, "original configuration PrivateId")
|
|
|
|
|
origConfId := origArgonConf.PrivateId
|
|
|
|
|
|
|
|
|
|
// Create an account with a password
|
|
|
|
|
inAcct := &Account{
|
|
|
|
|
Account: &store.Account{
|
|
|
|
|
AuthMethodId: authMethod.PublicId,
|
|
|
|
|
UserName: userName,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
origAcct, err := repo.CreateAccount(ctx, inAcct, WithPassword(passwd))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.NotNil(origAcct)
|
|
|
|
|
assert.NotEmpty(origAcct.PublicId)
|
|
|
|
|
|
|
|
|
|
// Get the credential for the new account and verify the KDF used the
|
|
|
|
|
// original argon2 configuration
|
|
|
|
|
origCred := &Argon2Credential{Argon2Credential: &store.Argon2Credential{}}
|
|
|
|
|
require.NoError(rw.LookupWhere(ctx, origCred, "password_account_id = ?", origAcct.PublicId))
|
|
|
|
|
assert.Equal(origAcct.PublicId, origCred.PasswordAccountId)
|
|
|
|
|
assert.Equal(origConfId, origCred.PasswordConfId)
|
|
|
|
|
assert.Equal(origCred.CreateTime, origCred.UpdateTime, "create and update times are equal")
|
|
|
|
|
origCredId := origCred.PrivateId
|
|
|
|
|
|
|
|
|
|
// Authenticate and verify the credential ID
|
|
|
|
|
authAcct, err := repo.Authenticate(ctx, authMethodId, userName, passwd)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.NotNil(authAcct, "auth account")
|
|
|
|
|
assert.Equal(origAcct.PublicId, authAcct.PublicId)
|
|
|
|
|
assert.Equal(origCredId, authAcct.CredentialId)
|
|
|
|
|
auth1CredId := authAcct.CredentialId
|
|
|
|
|
|
|
|
|
|
// Get the credential and verify the call to Authenticate did not
|
|
|
|
|
// change anything
|
|
|
|
|
auth1Cred := &Argon2Credential{
|
|
|
|
|
Argon2Credential: &store.Argon2Credential{
|
|
|
|
|
PrivateId: auth1CredId,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
require.NoError(rw.LookupById(ctx, auth1Cred))
|
|
|
|
|
assert.Equal(authAcct.PublicId, auth1Cred.PasswordAccountId)
|
|
|
|
|
assert.Equal(origConfId, auth1Cred.PasswordConfId)
|
|
|
|
|
assert.Equal(origCred.PasswordConfId, auth1Cred.PasswordConfId, "same configuration ID")
|
|
|
|
|
assert.Equal(origCred.Salt, auth1Cred.Salt, "same salt")
|
|
|
|
|
assert.Equal(origCred.DerivedKey, auth1Cred.DerivedKey, "same derived key")
|
|
|
|
|
assert.Equal(origCred.UpdateTime, auth1Cred.UpdateTime, "same update time")
|
|
|
|
|
|
|
|
|
|
// Change the argon2 configuration
|
|
|
|
|
inArgonConf := origArgonConf.clone()
|
|
|
|
|
inArgonConf.Threads = origArgonConf.Threads + 1
|
|
|
|
|
|
|
|
|
|
upConf, err := repo.SetConfiguration(ctx, inArgonConf)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.NotNil(upConf)
|
|
|
|
|
assert.NotSame(inArgonConf, upConf)
|
|
|
|
|
|
|
|
|
|
upArgonConf, ok := upConf.(*Argon2Configuration)
|
|
|
|
|
require.True(ok, "want *Argon2Configuration")
|
|
|
|
|
assert.NotEqual(origConfId, upArgonConf.PrivateId)
|
|
|
|
|
|
|
|
|
|
// Authenticate and verify the credential ID has not changed
|
|
|
|
|
auth2Acct, err := repo.Authenticate(ctx, authMethodId, userName, passwd)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.NotNil(auth2Acct, "auth2 account")
|
|
|
|
|
assert.Equal(origAcct.PublicId, auth2Acct.PublicId)
|
|
|
|
|
require.Equal(origCredId, auth2Acct.CredentialId)
|
|
|
|
|
auth2CredId := auth2Acct.CredentialId
|
|
|
|
|
|
|
|
|
|
// Get the credential and verify the call to Authenticate changed the
|
|
|
|
|
// appropriate fields
|
|
|
|
|
auth2Cred := &Argon2Credential{
|
|
|
|
|
Argon2Credential: &store.Argon2Credential{
|
|
|
|
|
PrivateId: auth2CredId,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
require.NoError(rw.LookupById(ctx, auth2Cred))
|
|
|
|
|
// Verify fields that should not change
|
|
|
|
|
assert.Equal(auth2Acct.PublicId, auth2Cred.PasswordAccountId)
|
|
|
|
|
assert.Equal(origCred.PrivateId, auth2Cred.PrivateId, "the credential Id should not change")
|
|
|
|
|
assert.Equal(origCred.CreateTime, auth2Cred.CreateTime, "the create time should not change")
|
|
|
|
|
|
|
|
|
|
// Verify fields that should change
|
|
|
|
|
require.NoError(auth2Cred.decrypt(ctx, wrapper))
|
|
|
|
|
assert.NotEqual(origCred.UpdateTime, auth2Cred.UpdateTime, "the update time should be different")
|
|
|
|
|
assert.NotEqual(origCred.PasswordConfId, auth2Cred.PasswordConfId, "the configuration Id should be different")
|
|
|
|
|
assert.NotEqual(origCred.Salt, auth2Cred.Salt, "a new salt value should be generated")
|
|
|
|
|
assert.NotEqual(origCred.DerivedKey, auth2Cred.DerivedKey, "the derived key should be different")
|
|
|
|
|
}
|
|
|
|
|
|