mirror of
https://github.com/anand34577/ferrum.git
synced 2026-09-16 23:55:09 +00:00
d04b769670
- Fleet Overview's Storage KPI and per-connection totals (internal/api/ overview.go) were summing shared storage once per node that mounts it, since PVE's own Shared flag is unreliable for storage added per-node without ticking it. New dedupeSharedStorage collapses those by an exact (name, total, used) match within a connection; local-only plugin types are never touched. Mirrored on the Storage page, which also now disambiguates same-named local pools (e.g. every node's "local-lvm") by node so a bar chart's category axis never gets duplicate labels. - Sign-out: React Query keeps a query's last-successful data through a failed refetch, so the cached signed-in user survived the post-logout 401 and the app never noticed. signOut() now pins ["auth","me"] to null directly instead of invalidating-and-hoping a refetch lands in time. - SMTP: net/smtp.SendMail opportunistically attempts STARTTLS whenever the server advertises it regardless of the admin's "Use STARTTLS" toggle, so an internal relay with a bad cert failed sends the admin explicitly asked to be plaintext. A dedicated sendPlain path never attempts TLS. - OIDC: added an "Auto-create new accounts" toggle — when off, a first-time SSO login for an unrecognized identity is refused instead of silently provisioning one. Also added RP-Initiated Logout: signing out of an SSO session now also ends the session at the identity provider when it advertises support for it (end_session_endpoint), via a stored id_token on OIDC sessions (new sessions.oidc_id_token column). - ResourceAreaChart tooltips now fall back to the same yTickFormatter given to the axis when a series has no formatter of its own — fixes raw unformatted numbers in Fleet Trend and every RRD chart built on it (Node/Guest detail) that only ever set the axis formatter.
59 lines
1.7 KiB
Go
59 lines
1.7 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
|
|
"ferrum/internal/auth"
|
|
)
|
|
|
|
// BootstrapSettings loads OIDC and notification settings from the database
|
|
// and applies them (live OIDC client, live Notifier) at startup.
|
|
//
|
|
// seedOIDC is the config.yaml/env OIDC config (internal/config.OIDCConfig,
|
|
// converted by the caller) — config.yaml was the only way to set this up
|
|
// before the Settings UI existed. The very first boot after upgrading copies
|
|
// it into the database once; every boot after that (and every save from the
|
|
// UI) uses the database exclusively, so config.yaml stops being read for
|
|
// OIDC at all once a row exists.
|
|
func (s *Server) BootstrapSettings(ctx context.Context, seedEnabled bool, seedOIDC auth.OIDCConfig) error {
|
|
var exists int
|
|
err := s.db.QueryRowContext(ctx, `SELECT 1 FROM oidc_settings WHERE id = 1`).Scan(&exists)
|
|
if err == sql.ErrNoRows {
|
|
enc, encErr := s.secrets.Encrypt(seedOIDC.ClientSecret)
|
|
if encErr != nil {
|
|
return encErr
|
|
}
|
|
if err := s.saveOIDCRow(ctx, oidcRow{
|
|
enabled: seedEnabled, displayName: seedOIDC.DisplayName, issuerURL: seedOIDC.IssuerURL,
|
|
clientID: seedOIDC.ClientID, clientSecretEnc: enc, redirectURL: seedOIDC.RedirectURL,
|
|
allowAutoProvision: true, // matches the pre-existing always-on behavior config.yaml-only deployments already had
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
|
|
row, err := s.loadOIDCRow(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.applyOIDCRow(row)
|
|
|
|
notifRow, err := s.loadNotificationRow(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := s.applyNotificationRow(notifRow); err != nil {
|
|
return err
|
|
}
|
|
|
|
secRow, err := s.loadSecurityRow(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.applySecurityRow(secRow)
|
|
return nil
|
|
}
|