up
This commit is contained in:
parent
9407799fa6
commit
a5a890537b
@ -6,11 +6,13 @@ import (
|
||||
"app/shelfly/internal/login"
|
||||
"app/shelfly/internal/users"
|
||||
"app/shelfly/renders"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
@ -24,8 +26,23 @@ type spaHandler struct {
|
||||
}
|
||||
|
||||
// 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.)
|
||||
staticDir := "./templates/assets/"
|
||||
r.PathPrefix("/templates/assets/").Handler(
|
||||
@ -34,11 +51,11 @@ func RoutesPublic(r *mux.Router, bd *gorm.DB) {
|
||||
|
||||
// Page de login
|
||||
r.HandleFunc("/login", renders.Login)
|
||||
|
||||
// Endpoint d'API pour se logger
|
||||
r.HandleFunc("/api/login", login.LoginHandler(bd)).Methods("POST")
|
||||
r.HandleFunc("/api/scan/{id}", library.ScanFolder(bd)).Methods("GET")
|
||||
r.HandleFunc("/api/download/stream", renders.HandleJobsStream(bd))
|
||||
|
||||
// Génération playlist
|
||||
r.HandleFunc("/playlist.m3u", func(w http.ResponseWriter, r *http.Request) {
|
||||
uploadDir := "/app/upload"
|
||||
|
||||
@ -52,9 +69,7 @@ func RoutesPublic(r *mux.Router, bd *gorm.DB) {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
// On construit l'URL HTTP complète
|
||||
relPath, _ := filepath.Rel(uploadDir, path)
|
||||
// Important : remplacer \ par / pour Windows
|
||||
relPath = filepath.ToSlash(relPath)
|
||||
fileURL := fmt.Sprintf("https://media.canguidev.fr/upload/%s", relPath)
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
// WebDAV sécurisé
|
||||
username := "tonuser" // ton login
|
||||
password := "tonpassword" // ton password
|
||||
|
||||
webdavHandler := &webdav.Handler{
|
||||
Prefix: "/webdav/",
|
||||
FileSystem: webdav.Dir("/app/upload"),
|
||||
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user