fix: unify email identity sync and retry first-bind defaults

This commit is contained in:
IanShaw027
2026-04-21 01:00:59 +08:00
parent 7a9488ff37
commit ea27ac6fd7
7 changed files with 154 additions and 78 deletions

View File

@@ -5,6 +5,7 @@ package service_test
import (
"context"
"database/sql"
"errors"
"testing"
"time"
@@ -34,6 +35,24 @@ func (s *authIdentityDefaultSubAssignerStub) AssignOrExtendSubscription(
return &service.UserSubscription{UserID: input.UserID, GroupID: input.GroupID}, true, nil
}
type flakyAuthIdentityDefaultSubAssignerStub struct {
failuresRemaining int
calls []*service.AssignSubscriptionInput
}
func (s *flakyAuthIdentityDefaultSubAssignerStub) AssignOrExtendSubscription(
_ context.Context,
input *service.AssignSubscriptionInput,
) (*service.UserSubscription, bool, error) {
cloned := *input
s.calls = append(s.calls, &cloned)
if s.failuresRemaining > 0 {
s.failuresRemaining--
return nil, false, errors.New("temporary assign failure")
}
return &service.UserSubscription{UserID: input.UserID, GroupID: input.GroupID}, true, nil
}
type authIdentitySettingRepoStub struct {
values map[string]string
}
@@ -333,6 +352,55 @@ func TestAuthServiceLogin_DoesNotApplyEmailFirstBindDefaultsWhenIdentityAlreadyE
require.Equal(t, 0, countProviderGrantRecords(t, client, user.ID, "email", "first_bind"))
}
func TestAuthServiceLogin_RetriesEmailFirstBindDefaultsAfterPreviousFailure(t *testing.T) {
assigner := &flakyAuthIdentityDefaultSubAssignerStub{failuresRemaining: 1}
svc, _, client := newAuthServiceWithEnt(t, map[string]string{
service.SettingKeyRegistrationEnabled: "true",
service.SettingKeyAuthSourceDefaultEmailBalance: "8.5",
service.SettingKeyAuthSourceDefaultEmailConcurrency: "4",
service.SettingKeyAuthSourceDefaultEmailSubscriptions: `[{"group_id":11,"validity_days":30}]`,
service.SettingKeyAuthSourceDefaultEmailGrantOnFirstBind: "true",
}, assigner)
ctx := context.Background()
passwordHash, err := svc.HashPassword("password")
require.NoError(t, err)
user, err := client.User.Create().
SetEmail("retry-first-bind@example.com").
SetUsername("retry-user").
SetPasswordHash(passwordHash).
SetBalance(1.5).
SetConcurrency(2).
SetRole(service.RoleUser).
SetStatus(service.StatusActive).
Save(ctx)
require.NoError(t, err)
token, gotUser, err := svc.Login(ctx, user.Email, "password")
require.NoError(t, err)
require.NotEmpty(t, token)
require.NotNil(t, gotUser)
storedUser, err := client.User.Get(ctx, user.ID)
require.NoError(t, err)
require.Equal(t, 1.5, storedUser.Balance)
require.Equal(t, 2, storedUser.Concurrency)
require.Len(t, assigner.calls, 1)
require.Equal(t, 0, countProviderGrantRecords(t, client, user.ID, "email", "first_bind"))
token, gotUser, err = svc.Login(ctx, user.Email, "password")
require.NoError(t, err)
require.NotEmpty(t, token)
require.NotNil(t, gotUser)
storedUser, err = client.User.Get(ctx, user.ID)
require.NoError(t, err)
require.Equal(t, 10.0, storedUser.Balance)
require.Equal(t, 6, storedUser.Concurrency)
require.Len(t, assigner.calls, 2)
require.Equal(t, 1, countProviderGrantRecords(t, client, user.ID, "email", "first_bind"))
}
func countProviderGrantRecords(
t *testing.T,
client *dbent.Client,