up
This commit is contained in:
parent
86fbed85a9
commit
94b9e74b08
@ -4,18 +4,18 @@ import (
|
|||||||
"app/shelfly/internal/download"
|
"app/shelfly/internal/download"
|
||||||
"app/shelfly/internal/library"
|
"app/shelfly/internal/library"
|
||||||
"app/shelfly/internal/login"
|
"app/shelfly/internal/login"
|
||||||
|
"app/shelfly/internal/models"
|
||||||
"app/shelfly/internal/users"
|
"app/shelfly/internal/users"
|
||||||
"app/shelfly/renders"
|
"app/shelfly/renders"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"app/shelfly/internal/models"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"golang.org/x/net/webdav"
|
"golang.org/x/net/webdav"
|
||||||
@ -35,6 +35,7 @@ func checkUserCredentials(db *gorm.DB, email string, password string) bool {
|
|||||||
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type spaHandler struct {
|
type spaHandler struct {
|
||||||
staticPath string
|
staticPath string
|
||||||
indexPath string
|
indexPath string
|
||||||
@ -97,55 +98,55 @@ 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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
r.PathPrefix("/webdav/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
r.PathPrefix("/webdav/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
authHeader := req.Header.Get("Authorization")
|
authHeader := req.Header.Get("Authorization")
|
||||||
if authHeader == "" {
|
if authHeader == "" {
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authentification HTTP Basic en base de données
|
// Authentification HTTP Basic en base de données
|
||||||
email, password, ok := req.BasicAuth()
|
email, password, ok := req.BasicAuth()
|
||||||
if !ok {
|
if !ok {
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("✅ email saisi: %s", email)
|
log.Printf("✅ email saisi: %s", email)
|
||||||
log.Printf("✅ password saisi: %s", password)
|
log.Printf("✅ password saisi: %s", password)
|
||||||
|
|
||||||
var user models.User
|
var user models.User
|
||||||
result := bd.Where("email = ?", email).First(&user)
|
result := bd.Where("email = ?", email).First(&user)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Ici on autorise TOUTES les méthodes WebDAV (lecture/écriture/suppression)
|
// ✅ Ici on autorise TOUTES les méthodes WebDAV (lecture/écriture/suppression)
|
||||||
log.Printf("✅ WebDAV FULL ACCESS for user: %s", email)
|
log.Printf("✅ WebDAV FULL ACCESS for user: %s", email)
|
||||||
|
|
||||||
// Headers WebDAV que certains clients attendent
|
// Headers WebDAV que certains clients attendent
|
||||||
w.Header().Set("DAV", "1,2")
|
w.Header().Set("DAV", "1,2")
|
||||||
w.Header().Set("MS-Author-Via", "DAV")
|
w.Header().Set("MS-Author-Via", "DAV")
|
||||||
|
|
||||||
// Handler WebDAV complet
|
// Handler WebDAV complet
|
||||||
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(),
|
||||||
}
|
}
|
||||||
|
|
||||||
webdavHandler.ServeHTTP(w, req)
|
webdavHandler.ServeHTTP(w, req)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// WebDAV sécurisé
|
// WebDAV sécurisé
|
||||||
// username := "tonuser" // ton login
|
// username := "tonuser" // ton login
|
||||||
@ -223,16 +224,39 @@ func RoutesProtected(r *mux.Router, bd *gorm.DB) {
|
|||||||
r.HandleFunc("/validate-path", download.PathValidationHandler)
|
r.HandleFunc("/validate-path", download.PathValidationHandler)
|
||||||
|
|
||||||
r.HandleFunc("/folders", renders.StreamHandler)
|
r.HandleFunc("/folders", renders.StreamHandler)
|
||||||
r.HandleFunc("/folders/detail", renders.DetailHandler).Methods("GET")
|
r.HandleFunc("/folders/detail", renders.DetailHandler).Methods("GET")
|
||||||
|
|
||||||
r.HandleFunc("/api/paths/{id:[0-9]+}/media", renders.PathMedia(bd)).Methods("GET")
|
r.HandleFunc("/api/paths/{id:[0-9]+}/media", renders.PathMedia(bd)).Methods("GET")
|
||||||
// r.HandleFunc("/stream/{partID:[0-9]+}", renders.Stream(bd)).Methods("GET")
|
// r.HandleFunc("/stream/{partID:[0-9]+}", renders.Stream(bd)).Methods("GET")
|
||||||
r.HandleFunc("/media/{partID:[0-9]+}", renders.MediaDetail(bd)).Methods("GET")
|
r.HandleFunc("/media/{partID:[0-9]+}", renders.MediaDetail(bd)).Methods("GET")
|
||||||
r.HandleFunc("/hls/{partID:[0-9]+}/{file}", renders.HLSStream(bd)).Methods("GET")
|
r.HandleFunc("/hls/{partID:[0-9]+}/{file}", renders.HLSStream(bd)).Methods("GET")
|
||||||
r.HandleFunc("/hls/{partID:[0-9]+}/", renders.HLSStream(bd)).Methods("GET")
|
r.HandleFunc("/hls/{partID:[0-9]+}/", renders.HLSStream(bd)).Methods("GET")
|
||||||
//API Scan folder
|
//API Scan folder
|
||||||
|
// —————— JSON API routes ——————
|
||||||
|
r.HandleFunc("/api/dashboard", renders.DashboardJSON(db)).Methods("GET")
|
||||||
|
r.HandleFunc("/api/menu-library", renders.MenuLibraryJSON(db)).Methods("GET")
|
||||||
|
r.HandleFunc("/api/settings", renders.SettingsJSON()).Methods("GET")
|
||||||
|
r.HandleFunc("/api/library", renders.LibraryJSON()).Methods("GET")
|
||||||
|
|
||||||
|
r.HandleFunc("/api/godownloader/download", renders.GoDownloadJSON()).Methods("GET")
|
||||||
|
r.HandleFunc("/api/godownloader/linkcollectors", renders.GoDownloadLinkCollectorsJSON()).Methods("GET")
|
||||||
|
r.HandleFunc("/api/godownloader/settings/delete", renders.GoDownloadSettingDeleteJSON(db)).Methods("POST")
|
||||||
|
r.HandleFunc("/api/godownloader/settings/toggle", renders.GoDownloadSettingToggleActiveJSON(db)).Methods("POST")
|
||||||
|
r.HandleFunc("/api/godownloader/settings", renders.GoDownloadSettingJSON(db)).Methods("GET", "POST")
|
||||||
|
r.HandleFunc("/api/godownloader/settings/table", renders.GoDownloadPartialTableJSON(db)).Methods("GET")
|
||||||
|
|
||||||
|
r.HandleFunc("/api/godownloader2", renders.GoDownload2JSON(db)).Methods("GET")
|
||||||
|
|
||||||
|
r.HandleFunc("/api/add-job", renders.HandleAddJobJSON(db)).Methods("POST")
|
||||||
|
r.HandleFunc("/api/jobs/list", renders.HandleListJobsPartialJSON(db)).Methods("GET")
|
||||||
|
r.HandleFunc("/api/add-jobs-multiple", renders.HandleAddJobsMultipleJSON(db)).Methods("POST")
|
||||||
|
|
||||||
|
r.HandleFunc("/api/stream", renders.StreamHandlerJSON()).Methods("GET")
|
||||||
|
|
||||||
|
r.HandleFunc("/api/pathmedia/{id}", renders.PathMediaJSON(db)).Methods("GET")
|
||||||
|
r.HandleFunc("/api/media/detail/{partID}", renders.MediaDetailJSON(db)).Methods("GET")
|
||||||
}
|
}
|
||||||
|
|
||||||
// func RoutesProtected(r *mux.Router, db *gorm.DB) {
|
// func RoutesProtected(r *mux.Router, db *gorm.DB) {
|
||||||
// // —————— HTML routes ——————
|
// // —————— HTML routes ——————
|
||||||
// r.HandleFunc("/login", Login).Methods("GET")
|
// r.HandleFunc("/login", Login).Methods("GET")
|
||||||
@ -289,9 +313,9 @@ r.HandleFunc("/hls/{partID:[0-9]+}/", renders.HLSStream(bd)).Methods("GET")
|
|||||||
|
|
||||||
// r.HandleFunc("/api/stream", StreamHandlerJSON()).Methods("GET")
|
// r.HandleFunc("/api/stream", StreamHandlerJSON()).Methods("GET")
|
||||||
|
|
||||||
// r.HandleFunc("/api/pathmedia/{id}", PathMediaJSON(db)).Methods("GET")
|
// r.HandleFunc("/api/pathmedia/{id}", PathMediaJSON(db)).Methods("GET")
|
||||||
// r.HandleFunc("/api/media/detail/{partID}", MediaDetailJSON(db)).Methods("GET")
|
// r.HandleFunc("/api/media/detail/{partID}", MediaDetailJSON(db)).Methods("GET")
|
||||||
// }
|
// }
|
||||||
func StreamHandler(w http.ResponseWriter, r *http.Request) {
|
func StreamHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "text/event-stream")
|
w.Header().Set("Content-Type", "text/event-stream")
|
||||||
w.Header().Set("Cache-Control", "no-cache")
|
w.Header().Set("Cache-Control", "no-cache")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user