Rework basic auth

This commit is contained in:
Ben Sarmiento
2024-01-10 23:42:14 +01:00
parent 124de7c01c
commit 0ea5d55b8a
5 changed files with 42 additions and 16 deletions

View File

@@ -14,7 +14,7 @@ docker pull ghcr.io/debridmediamanager/zurg-testing:latest
docker pull ghcr.io/debridmediamanager/zurg-testing:v0.9.3 docker pull ghcr.io/debridmediamanager/zurg-testing:v0.9.3
``` ```
## How to run zurg in 5 steps for Plex ## How to run zurg in 5 steps for Plex with Docker
1. Clone this repo `git clone https://github.com/debridmediamanager/zurg-testing.git` 1. Clone this repo `git clone https://github.com/debridmediamanager/zurg-testing.git`
2. Add your token in `config.yml` 2. Add your token in `config.yml`
@@ -24,6 +24,8 @@ docker pull ghcr.io/debridmediamanager/zurg-testing:v0.9.3
A webdav server is also exposed to your localhost via port `9999`. A webdav server is also exposed to your localhost via port `9999`.
### Note: when using zurg in a server outside of your home network, ensure that "Use my Remote Traffic automatically when needed" is unchecked on your [Account page](https://real-debrid.com/account)
## Why zurg? Why not X? ## Why zurg? Why not X?
- Better performance than anything out there; changes in your library appear instantly ([assuming Plex picks it up fast enough](./plex_update.sh)) - Better performance than anything out there; changes in your library appear instantly ([assuming Plex picks it up fast enough](./plex_update.sh))

View File

@@ -6,9 +6,9 @@ token: YOUR_RD_API_TOKEN # https://real-debrid.com/apitoken
host: "[::]" host: "[::]"
port: 9999 port: 9999
# you can protect zurg server with username+password auth # you can protect zurg's webdav server with username+password auth
username: yowmamasita # webdav_username: yowmamasita
password: 1234 # webdav_password: 1234
# How many requests in parallel should we send to Real-Debrid API? # How many requests in parallel should we send to Real-Debrid API?
concurrent_workers: 20 concurrent_workers: 20

View File

@@ -37,8 +37,8 @@ type ZurgConfig struct {
Host string `yaml:"host" json:"host"` Host string `yaml:"host" json:"host"`
Port string `yaml:"port" json:"port"` Port string `yaml:"port" json:"port"`
Username string `yaml:"username" json:"username"` Username string `yaml:"webdav_username" json:"webdav_username"`
Password string `yaml:"password" json:"password"` Password string `yaml:"webdav_password" json:"webdav_password"`
NumOfWorkers int `yaml:"concurrent_workers" json:"concurrent_workers"` NumOfWorkers int `yaml:"concurrent_workers" json:"concurrent_workers"`
RefreshEverySeconds int `yaml:"check_for_changes_every_secs" json:"check_for_changes_every_secs"` RefreshEverySeconds int `yaml:"check_for_changes_every_secs" json:"check_for_changes_every_secs"`

View File

@@ -1,17 +1,44 @@
package handlers package handlers
import "net/http" import (
"net/http"
"strings"
)
// basicAuth is a middleware that performs basic authentication.
func (hs *Handlers) basicAuth(next http.Handler) http.Handler { func (hs *Handlers) basicAuth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth() if r.Method != "OPTIONS" && needsAuth(r.URL.Path) {
if !ok || username != hs.cfg.GetUsername() || password != hs.cfg.GetPassword() { if !hs.authenticate(r) {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted"`) hs.unauthorized(w)
w.WriteHeader(http.StatusUnauthorized) return
w.Write([]byte(http.StatusText(http.StatusUnauthorized))) }
return
} }
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
}) })
} }
// needsAuth checks if the given path requires authentication.
func needsAuth(path string) bool {
authenticatedPaths := []string{"/dav/", "/infuse/"}
for _, p := range authenticatedPaths {
if strings.HasPrefix(path, p) {
return true
}
}
return false
}
// authenticate performs the basic authentication check.
func (hs *Handlers) authenticate(r *http.Request) bool {
username, password, ok := r.BasicAuth()
return ok && username == hs.cfg.GetUsername() && password == hs.cfg.GetPassword()
}
// unauthorized sends an unauthorized response.
func (hs *Handlers) unauthorized(w http.ResponseWriter) {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted"`)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(http.StatusText(http.StatusUnauthorized)))
}

View File

@@ -35,13 +35,10 @@ func (t *TorrentManager) repairAll() {
if torrent.AnyInProgress() || torrent.Unfixable { if torrent.AnyInProgress() || torrent.Unfixable {
return return
} }
// Check if the current group is full
if currentGroup.Cardinality() >= maxGroupSize { if currentGroup.Cardinality() >= maxGroupSize {
// Create a new group and add it to the hashGroups
currentGroup = mapset.NewSet[string]() currentGroup = mapset.NewSet[string]()
hashGroups = append(hashGroups, currentGroup) hashGroups = append(hashGroups, currentGroup)
} }
// Add the hash to the current group
currentGroup.Add(torrent.Hash) currentGroup.Add(torrent.Hash)
}) })