added more tests for internal record hooks
This commit is contained in:
@@ -308,3 +308,104 @@ func TestExternalAuthValidateHook(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExternalAuthClearOnVerfiedUpgrade(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
t.Run("unverified->no changes", func(t *testing.T) {
|
||||
user, err := app.FindAuthRecordByEmail("users", "test@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if user.Verified() {
|
||||
t.Fatal("Expected user to be unverified")
|
||||
}
|
||||
|
||||
beforeAuths, err := app.FindAllExternalAuthsByRecord(user)
|
||||
if err != nil || len(beforeAuths) == 0 {
|
||||
t.Fatalf("Expected at least one external auth (%v)", err)
|
||||
}
|
||||
|
||||
oldTokenKey := user.TokenKey()
|
||||
|
||||
if err = app.Save(user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if oldTokenKey != user.TokenKey() {
|
||||
t.Fatal("Expected tokenKey to remain unchanged")
|
||||
}
|
||||
|
||||
afterAuths, err := app.FindAllExternalAuthsByRecord(user)
|
||||
if err != nil || len(afterAuths) != len(beforeAuths) {
|
||||
t.Fatalf("Expected %d external auths, found %d (%v)", len(afterAuths), len(beforeAuths), err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("unverified->verified", func(t *testing.T) {
|
||||
user, err := app.FindAuthRecordByEmail("users", "test@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if user.Verified() {
|
||||
t.Fatal("Expected user to be unverified")
|
||||
}
|
||||
|
||||
externalAuths, err := app.FindAllExternalAuthsByRecord(user)
|
||||
if err != nil || len(externalAuths) == 0 {
|
||||
t.Fatalf("Expected at least one external auth (%v)", err)
|
||||
}
|
||||
|
||||
oldTokenKey := user.TokenKey()
|
||||
|
||||
user.SetVerified(true)
|
||||
if err = app.Save(user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if oldTokenKey == user.TokenKey() {
|
||||
t.Fatal("Expected tokenKey to be renewed")
|
||||
}
|
||||
|
||||
externalAuths, err = app.FindAllExternalAuthsByRecord(user)
|
||||
if err != nil || len(externalAuths) != 0 {
|
||||
t.Fatalf("Expected all user external auths to be deleted, found %d (%v)", len(externalAuths), err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("verified->no changes", func(t *testing.T) {
|
||||
user, err := app.FindAuthRecordByEmail("users", "test3@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !user.Verified() {
|
||||
t.Fatal("Expected user to be verified")
|
||||
}
|
||||
|
||||
beforeAuths, err := app.FindAllExternalAuthsByRecord(user)
|
||||
if err != nil || len(beforeAuths) == 0 {
|
||||
t.Fatalf("Expected at least one external auth (%v)", err)
|
||||
}
|
||||
|
||||
oldTokenKey := user.TokenKey()
|
||||
|
||||
if err = app.Save(user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if oldTokenKey != user.TokenKey() {
|
||||
t.Fatal("Expected tokenKey to remain unchanged")
|
||||
}
|
||||
|
||||
afterAuths, err := app.FindAllExternalAuthsByRecord(user)
|
||||
if err != nil || len(afterAuths) != len(beforeAuths) {
|
||||
t.Fatalf("Expected %d external auths, found %d (%v)", len(afterAuths), len(beforeAuths), err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -300,3 +300,64 @@ func TestMFAValidateHook(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMFAClearOnPasswordChange(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
user1, err := app.FindAuthRecordByEmail("users", "test@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user2, err := app.FindAuthRecordByEmail("users", "test2@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mfasToCreate := map[*core.Record]int{
|
||||
user1: 3,
|
||||
user2: 2,
|
||||
}
|
||||
for user, total := range mfasToCreate {
|
||||
for range total {
|
||||
mfa := core.NewMFA(app)
|
||||
mfa.SetCollectionRef(user.Collection().Id)
|
||||
mfa.SetRecordRef(user.Id)
|
||||
mfa.SetMethod(core.MFAMethodPassword)
|
||||
if err := app.Save(mfa); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update both users
|
||||
err = app.Save(user1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user2.SetRandomPassword()
|
||||
err = app.Save(user2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expectedMFAs := map[*core.Record]int{
|
||||
user1: 3,
|
||||
user2: 0,
|
||||
}
|
||||
|
||||
for user, expected := range expectedMFAs {
|
||||
mfas, err := app.FindAllMFAsByRecord(user)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(mfas) != expected {
|
||||
t.Fatalf("Expected %d MFAs, got %d", expected, len(mfas))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func (app *BaseApp) registerOTPHooks() {
|
||||
return err
|
||||
}
|
||||
|
||||
if e.Record.Original().TokenKey() != e.Record.TokenKey() {
|
||||
if !e.Record.Original().IsNew() && e.Record.Original().TokenKey() != e.Record.TokenKey() {
|
||||
err := e.App.DeleteAllOTPsByRecord(e.Record)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
|
||||
@@ -300,3 +300,64 @@ func TestOTPValidateHook(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOTPClearOnTokenKeyChange(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
user1, err := app.FindAuthRecordByEmail("users", "test@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user2, err := app.FindAuthRecordByEmail("users", "test2@example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
otpsToCreate := map[*core.Record]int{
|
||||
user1: 3,
|
||||
user2: 2,
|
||||
}
|
||||
for user, total := range otpsToCreate {
|
||||
for range total {
|
||||
otp := core.NewOTP(app)
|
||||
otp.SetCollectionRef(user.Collection().Id)
|
||||
otp.SetRecordRef(user.Id)
|
||||
otp.SetPassword("123456")
|
||||
if err := app.Save(otp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update both users
|
||||
err = app.Save(user1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user2.RefreshTokenKey()
|
||||
err = app.Save(user2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expectedOTPs := map[*core.Record]int{
|
||||
user1: 3,
|
||||
user2: 0,
|
||||
}
|
||||
|
||||
for user, expected := range expectedOTPs {
|
||||
otps, err := app.FindAllOTPsByRecord(user)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(otps) != expected {
|
||||
t.Fatalf("Expected %d OTPs, got %d", expected, len(otps))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user