init
This commit is contained in:
88
internal/app/handlers_auth.go
Normal file
88
internal/app/handlers_auth.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/yourorg/ntfywui/internal/security"
|
||||
"github.com/yourorg/ntfywui/internal/store"
|
||||
)
|
||||
|
||||
func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
next := r.URL.Query().Get("next")
|
||||
if next == "" {
|
||||
next = "/users"
|
||||
}
|
||||
csrf, _ := s.csrfEnsure(w, r)
|
||||
flash := s.popFlash(w, r)
|
||||
s.renderer.Render(w, "login.html", PageData{
|
||||
Title: "Login",
|
||||
CSRF: csrf,
|
||||
Flash: flash,
|
||||
Next: next,
|
||||
})
|
||||
case http.MethodPost:
|
||||
_ = r.ParseForm()
|
||||
user := cleanUser(r.Form.Get("username"))
|
||||
pass := r.Form.Get("password")
|
||||
totp := strings.TrimSpace(r.Form.Get("totp"))
|
||||
next := r.Form.Get("next")
|
||||
if next == "" {
|
||||
next = "/users"
|
||||
}
|
||||
// CSRF checked by middleware in routes (we add it by calling s.csrf wrapper above in routes)
|
||||
a, ok := s.admins.Authenticate(user, pass, totp)
|
||||
if !ok {
|
||||
s.audit.Append(store.AuditEvent{
|
||||
Actor: user,
|
||||
IP: security.RealIP(r, security.RealIPConfig{TrustedProxies: s.cfg.TrustedProxies}),
|
||||
UA: r.UserAgent(),
|
||||
Action: "login_failed",
|
||||
})
|
||||
s.setFlash(w, r, "Login fehlgeschlagen")
|
||||
http.Redirect(w, r, s.abs("/login"), http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
sess, _ := s.sessions.Get(r)
|
||||
if sess == nil {
|
||||
sess = &security.Session{}
|
||||
}
|
||||
sess.User = a.Username
|
||||
sess.Role = string(a.Role)
|
||||
if sess.CSRF == "" {
|
||||
tok, _ := security.NewCSRFToken()
|
||||
sess.CSRF = tok
|
||||
}
|
||||
s.sessions.Save(w, sess)
|
||||
|
||||
s.auditEvent(r, "login_ok", a.Username, map[string]string{"role": string(a.Role)})
|
||||
http.Redirect(w, r, s.abs(next), http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleLogout(w http.ResponseWriter, r *http.Request) {
|
||||
s.auditEvent(r, "logout", "", nil)
|
||||
s.sessions.Clear(w)
|
||||
http.Redirect(w, r, s.abs("/login"), http.StatusFound)
|
||||
}
|
||||
|
||||
func (s *Server) csrfEnsure(w http.ResponseWriter, r *http.Request) (string, error) {
|
||||
sess, ok := s.sessions.Get(r)
|
||||
if !ok {
|
||||
sess = &security.Session{}
|
||||
}
|
||||
if sess.CSRF == "" {
|
||||
tok, err := security.NewCSRFToken()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sess.CSRF = tok
|
||||
_ = s.sessions.Save(w, sess)
|
||||
}
|
||||
return sess.CSRF, nil
|
||||
}
|
||||
Reference in New Issue
Block a user