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
@@ -2,6 +2,31 @@ package store
import "testing"
func TestAuthUserFromOIDCProjectionIncludesProfile(t *testing.T) {
projected := authUserFromOIDCProjection(GatewayUser{
ID: "gateway-user", ExternalUserID: "external-user", Username: "alice",
DisplayName: "王小明", Email: "alice@example.test", Phone: "+8613800000000",
AvatarURL: "https://static.example.test/avatar.png",
}, "default")
if projected.DisplayName != "王小明" || projected.Email != "alice@example.test" ||
projected.Phone != "+8613800000000" || projected.AvatarURL != "https://static.example.test/avatar.png" {
t.Fatalf("OIDC profile was not projected: %#v", projected)
}
}
func TestNormalizeOIDCUserInputBoundsProfileClaims(t *testing.T) {
input := normalizeOIDCUserInput(ResolveOrProvisionOIDCUserInput{
DisplayName: " 王小明 ",
Email: " alice@example.test ",
Phone: " +8613800000000 ",
AvatarURL: " https://static.example.test/avatar.png ",
})
if input.DisplayName != "王小明" || input.Email != "alice@example.test" ||
input.Phone != "+8613800000000" || input.AvatarURL != "https://static.example.test/avatar.png" {
t.Fatalf("OIDC profile was not normalized: %#v", input)
}
}
func TestOIDCProjectionKindRequiresExplicitCompatibleContext(t *testing.T) {
applicationID := "11111111-1111-4111-8111-111111111111"
tests := []struct {