up
This commit is contained in:
parent
9407799fa6
commit
a5a890537b
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
webdavHandler := &webdav.Handler{
|
|
||||||
|
// WebDAV sécurisé
|
||||||
|
username := "tonuser" // ton login
|
||||||
|
password := "tonpassword" // ton password
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user