This commit is contained in:
cangui 2025-06-18 19:28:57 +02:00
parent 9407799fa6
commit a5a890537b

View File

@ -6,11 +6,13 @@ import (
"app/shelfly/internal/login" "app/shelfly/internal/login"
"app/shelfly/internal/users" "app/shelfly/internal/users"
"app/shelfly/renders" "app/shelfly/renders"
"encoding/base64"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -24,8 +26,23 @@ type spaHandler struct {
} }
// Routes non protégées // Routes non protégées
func RoutesPublic(r *mux.Router, bd *gorm.DB) { func checkAuth(authHeader, username, password string) bool {
const prefix = "Basic "
if !strings.HasPrefix(authHeader, prefix) {
return false
}
decoded, err := base64.StdEncoding.DecodeString(authHeader[len(prefix):])
if err != nil {
return false
}
pair := strings.SplitN(string(decoded), ":", 2)
if len(pair) != 2 {
return false
}
return pair[0] == username && pair[1] == password
}
func RoutesPublic(r *mux.Router, bd *gorm.DB) {
// Fichiers statiques (CSS, JS, etc.) // Fichiers statiques (CSS, JS, etc.)
staticDir := "./templates/assets/" staticDir := "./templates/assets/"
r.PathPrefix("/templates/assets/").Handler( r.PathPrefix("/templates/assets/").Handler(
@ -34,11 +51,11 @@ func RoutesPublic(r *mux.Router, bd *gorm.DB) {
// Page de login // Page de login
r.HandleFunc("/login", renders.Login) r.HandleFunc("/login", renders.Login)
// Endpoint d'API pour se logger
r.HandleFunc("/api/login", login.LoginHandler(bd)).Methods("POST") r.HandleFunc("/api/login", login.LoginHandler(bd)).Methods("POST")
r.HandleFunc("/api/scan/{id}", library.ScanFolder(bd)).Methods("GET") r.HandleFunc("/api/scan/{id}", library.ScanFolder(bd)).Methods("GET")
r.HandleFunc("/api/download/stream", renders.HandleJobsStream(bd)) r.HandleFunc("/api/download/stream", renders.HandleJobsStream(bd))
// Génération playlist
r.HandleFunc("/playlist.m3u", func(w http.ResponseWriter, r *http.Request) { r.HandleFunc("/playlist.m3u", func(w http.ResponseWriter, r *http.Request) {
uploadDir := "/app/upload" uploadDir := "/app/upload"
@ -52,9 +69,7 @@ func RoutesPublic(r *mux.Router, bd *gorm.DB) {
if info.IsDir() { if info.IsDir() {
return nil return nil
} }
// On construit l'URL HTTP complète
relPath, _ := filepath.Rel(uploadDir, path) relPath, _ := filepath.Rel(uploadDir, path)
// Important : remplacer \ par / pour Windows
relPath = filepath.ToSlash(relPath) relPath = filepath.ToSlash(relPath)
fileURL := fmt.Sprintf("https://media.canguidev.fr/upload/%s", relPath) fileURL := fmt.Sprintf("https://media.canguidev.fr/upload/%s", relPath)
fmt.Fprintln(w, fileURL) fmt.Fprintln(w, fileURL)
@ -65,13 +80,38 @@ func RoutesPublic(r *mux.Router, bd *gorm.DB) {
http.Error(w, "Erreur lors de la génération de la playlist", http.StatusInternalServerError) http.Error(w, "Erreur lors de la génération de la playlist", http.StatusInternalServerError)
} }
}) })
// WebDAV sécurisé
username := "tonuser" // ton login
password := "tonpassword" // ton password
webdavHandler := &webdav.Handler{ webdavHandler := &webdav.Handler{
Prefix: "/webdav/", Prefix: "/webdav/",
FileSystem: webdav.Dir("/app/upload"), FileSystem: webdav.Dir("/app/upload"),
LockSystem: webdav.NewMemLS(), LockSystem: webdav.NewMemLS(),
} }
r.PathPrefix("/webdav/").Handler(http.StripPrefix("/webdav/", webdavHandler))
r.PathPrefix("/webdav/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// Authentification
auth := req.Header.Get("Authorization")
if auth == "" || !checkAuth(auth, username, password) {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Protection lecture seule
if req.Method != "GET" && req.Method != "HEAD" && req.Method != "OPTIONS" && req.Method != "PROPFIND" {
http.Error(w, "Read-Only", http.StatusForbidden)
return
}
// Headers WebDAV que VLC attend
w.Header().Set("DAV", "1,2")
w.Header().Set("MS-Author-Via", "DAV")
webdavHandler.ServeHTTP(w, req)
}))
} }
// Routes protégées // Routes protégées