From e90d588e30afb0d5857765a46ada9306a7c942b5 Mon Sep 17 00:00:00 2001 From: sysops Date: Thu, 2 Apr 2026 00:41:19 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20UpsertLDAPUser=20=E2=80=94=20email-basie?= =?UTF-8?q?rter=20Match=20vor=20Insert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verhindert duplicate-key-Fehler wenn LDAP-uid (z.B. "patrick") vom gespeicherten username ("patrick@perlbach24.de") abweicht. Erst per Email matchen und updaten, dann neu anlegen falls nicht vorhanden. Co-Authored-By: Claude Sonnet 4.6 --- internal/userstore/userstore.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/userstore/userstore.go b/internal/userstore/userstore.go index 760fc1e..c00937d 100644 --- a/internal/userstore/userstore.go +++ b/internal/userstore/userstore.go @@ -427,7 +427,27 @@ func (s *Store) CleanExpiredTokens() error { // tenantID may be nil for users not associated with a specific tenant. func (s *Store) UpsertLDAPUser(username, email, role string, tenantID *int64) (*User, error) { ctx := context.Background() - _, err := s.pool.Exec(ctx, ` + // First try to update an existing user matched by email (covers the case where + // the stored username differs from the LDAP uid, e.g. "patrick" vs "patrick@domain"). + var u User + err := s.pool.QueryRow(ctx, ` + UPDATE users SET + username = $1, + role = $2, + source = 'ldap', + active = true, + tenant_id = COALESCE($3, tenant_id) + WHERE email = $4 + RETURNING id, username, email, role, source, active, created_at, tenant_id, totp_enabled, totp_reset_at, totp_reset_by + `, username, role, tenantID, email).Scan( + &u.ID, &u.Username, &u.Email, &u.Role, &u.Source, &u.Active, + &u.CreatedAt, &u.TenantID, &u.TOTPEnabled, &u.TOTPResetAt, &u.TOTPResetBy, + ) + if err == nil { + return &u, nil + } + // No existing user with that email — insert fresh. + _, err = s.pool.Exec(ctx, ` INSERT INTO users (username, email, password_hash, role, source, active, created_at, tenant_id) VALUES ($1, $2, '', $3, 'ldap', true, NOW(), $4) ON CONFLICT (username) DO UPDATE SET