fix(backend): Error-Logging in Screen-User-Handlern + Tenant-Lookup-Refactoring
Fehlende slog.Error-Aufrufe in HandleAddUserToScreen, HandleCreateScreenUser, HandleDeleteScreenUser und HandleRemoveUserFromScreen ergänzt — DB-Fehler wurden bisher komplett geschluckt und waren nicht diagnostizierbar. Tenant-Lookup in EnsureAdminUser und CreateScreenUser aus SQL-Subqueries in eigene Queries extrahiert für bessere Fehlermeldungen bei fehlendem Tenant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
73c3d74098
commit
c470ec532b
2 changed files with 32 additions and 15 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -202,6 +203,8 @@ func HandleCreateScreenUser(auth *store.AuthStore) http.HandlerFunc {
|
|||
|
||||
_, err := auth.CreateScreenUser(r.Context(), tenantSlug, username, password)
|
||||
if err != nil {
|
||||
slog.Error("create screen user failed", "event", "create_screen_user_failed",
|
||||
"tenant_slug", tenantSlug, "username", username, "err", err)
|
||||
http.Redirect(w, r, "/admin?tab=users&msg=error_exists", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
|
@ -214,6 +217,8 @@ func HandleDeleteScreenUser(auth *store.AuthStore) http.HandlerFunc {
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
userID := r.PathValue("userID")
|
||||
if err := auth.DeleteUser(r.Context(), userID); err != nil {
|
||||
slog.Error("delete screen user failed", "event", "delete_screen_user_failed",
|
||||
"user_id", userID, "err", err)
|
||||
http.Error(w, "Fehler beim Löschen", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
|
@ -235,6 +240,8 @@ func HandleAddUserToScreen(screens *store.ScreenStore) http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
if err := screens.AddUserToScreen(r.Context(), userID, screenID); err != nil {
|
||||
slog.Error("add user to screen failed", "event", "add_user_to_screen_failed",
|
||||
"screen_id", screenID, "user_id", userID, "err", err)
|
||||
http.Redirect(w, r, "/admin?msg=error_db", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
|
@ -248,6 +255,8 @@ func HandleRemoveUserFromScreen(screens *store.ScreenStore) http.HandlerFunc {
|
|||
screenID := r.PathValue("screenID")
|
||||
userID := r.PathValue("userID")
|
||||
if err := screens.RemoveUserFromScreen(r.Context(), userID, screenID); err != nil {
|
||||
slog.Error("remove user from screen failed", "event", "remove_user_from_screen_failed",
|
||||
"screen_id", screenID, "user_id", userID, "err", err)
|
||||
http.Error(w, "db error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,15 +136,19 @@ func (s *AuthStore) EnsureAdminUser(ctx context.Context, tenantSlug, password st
|
|||
return fmt.Errorf("auth: hash password: %w", err)
|
||||
}
|
||||
|
||||
var tenantID string
|
||||
err = s.pool.QueryRow(ctx, `select id from tenants where slug = $1`, tenantSlug).Scan(&tenantID)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
return fmt.Errorf("auth: tenant not found: %s", tenantSlug)
|
||||
}
|
||||
return fmt.Errorf("auth: resolve tenant: %w", err)
|
||||
}
|
||||
|
||||
_, err = s.pool.Exec(ctx,
|
||||
`insert into users(tenant_id, username, password_hash, role)
|
||||
values(
|
||||
(select id from tenants where slug = $1),
|
||||
'admin',
|
||||
$2,
|
||||
'admin'
|
||||
)`,
|
||||
tenantSlug, string(hash))
|
||||
values($1, 'admin', $2, 'admin')`,
|
||||
tenantID, string(hash))
|
||||
if err != nil {
|
||||
return fmt.Errorf("auth: create admin user: %w", err)
|
||||
}
|
||||
|
|
@ -156,6 +160,15 @@ func (s *AuthStore) EnsureAdminUser(ctx context.Context, tenantSlug, password st
|
|||
// Returns pgx.ErrNoRows if the tenant does not exist, or a wrapped error if
|
||||
// the username is already taken (unique constraint violation).
|
||||
func (s *AuthStore) CreateScreenUser(ctx context.Context, tenantSlug, username, password string) (*User, error) {
|
||||
var tenantID string
|
||||
err := s.pool.QueryRow(ctx, `select id from tenants where slug = $1`, tenantSlug).Scan(&tenantID)
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
return nil, fmt.Errorf("auth: tenant not found: %s", tenantSlug)
|
||||
}
|
||||
return nil, fmt.Errorf("auth: resolve tenant: %w", err)
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), 12)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("auth: hash password: %w", err)
|
||||
|
|
@ -163,14 +176,9 @@ func (s *AuthStore) CreateScreenUser(ctx context.Context, tenantSlug, username,
|
|||
|
||||
row := s.pool.QueryRow(ctx,
|
||||
`insert into users(tenant_id, username, password_hash, role)
|
||||
values(
|
||||
(select id from tenants where slug = $1),
|
||||
$2, $3, 'screen_user'
|
||||
)
|
||||
returning id, tenant_id, coalesce(
|
||||
(select slug from tenants where id = tenant_id), ''
|
||||
), username, password_hash, role, created_at`,
|
||||
tenantSlug, username, string(hash))
|
||||
values($1, $2, $3, 'screen_user')
|
||||
returning id, tenant_id, $4::text, username, password_hash, role, created_at`,
|
||||
tenantID, username, string(hash), tenantSlug)
|
||||
u, err := scanUserWithSlug(row)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("auth: create screen user: %w", err)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue