Full web : fichiers restants
This commit is contained in:
1 parent
ec3b7c9a01
commit
4826fa5b82
26 files changed
+2537
-793
No files matched your search
+52
-2
@@ -183,7 +183,7 @@ func sessionKey(dir string) []byte {
|
||||
// public paths: reachable without a session.
|
||||
func public(p string) bool {
|
||||
switch p {
|
||||
case "/healthz", loginPage, "/style.css", "/boot.js", "/login.js", "/favicon.svg", "/auth/config", "/auth/login", "/auth/logout", "/auth/oidc":
|
||||
case "/healthz", loginPage, "/style.css", "/boot.js", "/login.js", "/favicon.svg", "/auth/config", "/auth/login", "/auth/logout", "/auth/oidc", "/auth/setup":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -197,6 +197,9 @@ func (a *Auth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.URL.Path == "/auth/logout":
|
||||
a.handleLogout(w, r)
|
||||
return
|
||||
case r.URL.Path == "/auth/setup":
|
||||
a.handleSetup(w, r)
|
||||
return
|
||||
case r.URL.Path == "/auth/oidc" && a.cfg.OIDCEnabled():
|
||||
a.startLogin(w, r)
|
||||
return
|
||||
@@ -204,7 +207,8 @@ func (a *Auth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
a.handleCallback(w, r)
|
||||
return
|
||||
case r.URL.Path == "/auth/config":
|
||||
writeJSON(w, http.StatusOK, map[string]any{"local": a.cfg.Local, "oidc": a.cfg.OIDCEnabled(), "demo": a.cfg.Demo})
|
||||
writeJSON(w, http.StatusOK, map[string]any{"local": a.cfg.Local, "oidc": a.cfg.OIDCEnabled(), "demo": a.cfg.Demo,
|
||||
"setup": a.needSetup(r.Context())})
|
||||
return
|
||||
}
|
||||
id, ok := a.sessionIdentity(r)
|
||||
@@ -299,6 +303,52 @@ func (a *Auth) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, ret, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// needSetup: local accounts enabled and none yet, the login page asks for the
|
||||
// first administrator.
|
||||
func (a *Auth) needSetup(ctx context.Context) bool {
|
||||
if !a.cfg.Local {
|
||||
return false
|
||||
}
|
||||
n, err := a.store.CountUsers(ctx)
|
||||
return err == nil && n == 0
|
||||
}
|
||||
|
||||
// handleSetup creates the first administrator on an empty database, then opens
|
||||
// its session. Refused as soon as an account exists.
|
||||
func (a *Auth) handleSetup(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost || !a.needSetup(r.Context()) {
|
||||
http.Redirect(w, r, loginPage, http.StatusFound)
|
||||
return
|
||||
}
|
||||
user, pass := strings.TrimSpace(r.PostFormValue("user")), r.PostFormValue("pass")
|
||||
fail := func(code string) {
|
||||
http.Redirect(w, r, loginPage+"?"+url.Values{"setup": {code}}.Encode(), http.StatusSeeOther)
|
||||
}
|
||||
if pass != r.PostFormValue("pass2") {
|
||||
fail("mismatch")
|
||||
return
|
||||
}
|
||||
if err := a.store.CreateFirstAdmin(r.Context(), user, pass); err != nil {
|
||||
log.Printf("auth: first administrator: %v", err)
|
||||
if errors.Is(err, store.ErrSetupDone) {
|
||||
http.Redirect(w, r, loginPage, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
fail("invalid")
|
||||
return
|
||||
}
|
||||
u, err := a.store.User(r.Context(), user)
|
||||
if err != nil {
|
||||
fail("invalid")
|
||||
return
|
||||
}
|
||||
id := Identity{User: u.Name, Role: u.Role, Mode: "local"}
|
||||
log.Printf("auth: first administrator %q created from %s", u.Name, clientIP(r))
|
||||
a.audit(r, id, "setup", u.Name, true, "premier administrateur créé")
|
||||
a.setSession(w, r, session{User: u.Name, Role: u.Role, Mode: "local", Epoch: u.Epoch})
|
||||
http.Redirect(w, r, "/#clusters", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// handleLogout ends the session; with OIDC the provider's session ends on its logout page if it has one.
|
||||
func (a *Auth) handleLogout(w http.ResponseWriter, r *http.Request) {
|
||||
id, ok := a.sessionIdentity(r)
|
||||
|
||||
Reference in new issue
Block a user