Files
91/backend/internal/auth/auth.go
T
nianzhibai 3506328441 Add PikPak drive support
Add PikPak backend driver, fixed tag matching, cached transcode playback, fast cover handling, and LF normalization.
2026-05-10 23:55:04 +08:00

82 lines
1.8 KiB
Go

package auth
import (
"crypto/rand"
"crypto/subtle"
"encoding/hex"
"net/http"
"time"
"github.com/video-site/backend/internal/catalog"
)
const (
sessionCookie = "vs_admin"
sessionTTL = 24 * time.Hour
)
type Authenticator struct {
Username string
Password string
Catalog *catalog.Catalog
}
func (a *Authenticator) Login(w http.ResponseWriter, r *http.Request, user, pass string) (bool, error) {
if subtle.ConstantTimeCompare([]byte(user), []byte(a.Username)) != 1 ||
subtle.ConstantTimeCompare([]byte(pass), []byte(a.Password)) != 1 {
return false, nil
}
token, err := randomToken()
if err != nil {
return false, err
}
if err := a.Catalog.CreateSession(r.Context(), token, sessionTTL); err != nil {
return false, err
}
http.SetCookie(w, &http.Cookie{
Name: sessionCookie,
Value: token,
Path: "/",
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
Expires: time.Now().Add(sessionTTL),
})
return true, nil
}
func (a *Authenticator) Logout(w http.ResponseWriter, r *http.Request) {
if c, err := r.Cookie(sessionCookie); err == nil {
_ = a.Catalog.DeleteSession(r.Context(), c.Value)
}
http.SetCookie(w, &http.Cookie{
Name: sessionCookie,
Value: "",
Path: "/",
Expires: time.Unix(0, 0),
})
}
func (a *Authenticator) Required(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
c, err := r.Cookie(sessionCookie)
if err != nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
ok, err := a.Catalog.ValidateSession(r.Context(), c.Value)
if err != nil || !ok {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func randomToken() (string, error) {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return "", err
}
return hex.EncodeToString(b), nil
}