fix(oidc): 同步认证中心用户资料到本地用户

从已验证的 OIDC Claim 提取用户名、显示名称、邮箱、手机号和头像,并覆盖单租户、多租户及平台用户的 JIT 创建与重复登录同步。\n\n保留 metadata.manualProfile 标记下的人工资料,限制字段长度且仅接收已验证联系方式与 HTTPS 头像。已通过 auth、httpapi、store 测试及临时 PostgreSQL 集成验证。
This commit is contained in:
2026-08-03 15:55:50 +08:00
parent 3c8d9839a4
commit b125599354
10 changed files with 206 additions and 24 deletions
@@ -167,6 +167,10 @@ func (s *Server) resolveOIDCUserProjectionWithTenantContext(
ApplicationID: revision.ApplicationID,
Subject: user.ID,
Username: user.Username,
DisplayName: user.DisplayName,
Email: user.Email,
Phone: user.Phone,
AvatarURL: user.AvatarURL,
Roles: user.Roles,
ContextType: user.ContextType,
TenantID: user.TenantID,
@@ -89,6 +89,10 @@ func TestResolveGatewayUserAddsLocalOIDCContext(t *testing.T) {
request = request.WithContext(auth.WithUser(request.Context(), &auth.User{
ID: "platform-user",
Username: "alice",
DisplayName: "王小明",
Email: "alice@example.test",
Phone: "+8613800000000",
AvatarURL: "https://static.example.test/avatar.png",
Roles: []string{"basic"},
ContextType: "tenant",
TenantID: "external-tenant",
@@ -100,7 +104,9 @@ func TestResolveGatewayUserAddsLocalOIDCContext(t *testing.T) {
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", recorder.Code)
}
if resolver.calls != 1 || resolver.input.Subject != "platform-user" || resolver.input.GatewayTenantKey != "default" || !resolver.input.ProvisioningEnabled {
if resolver.calls != 1 || resolver.input.Subject != "platform-user" || resolver.input.GatewayTenantKey != "default" || !resolver.input.ProvisioningEnabled ||
resolver.input.DisplayName != "王小明" || resolver.input.Email != "alice@example.test" ||
resolver.input.Phone != "+8613800000000" || resolver.input.AvatarURL != "https://static.example.test/avatar.png" {
t.Fatalf("unexpected resolver call: calls=%d input=%+v", resolver.calls, resolver.input)
}
}