Add basic auth and fix repair issues

This commit is contained in:
Ben Sarmiento
2024-01-09 16:53:12 +01:00
parent eb3f2785ce
commit 91f6d35831
7 changed files with 73 additions and 39 deletions

View File

@@ -11,6 +11,8 @@ type ConfigInterface interface {
EnableRepair() bool
GetHost() string
GetPort() string
GetUsername() string
GetPassword() string
GetDirectories() []string
MeetsConditions(directory, torrentName string, torrentSize int64, torrentIDs, fileNames []string, fileSizes []int64) bool
GetOnLibraryUpdate() string
@@ -34,6 +36,8 @@ type ZurgConfig struct {
Host string `yaml:"host" json:"host"`
Port string `yaml:"port" json:"port"`
Username string `yaml:"username" json:"username"`
Password string `yaml:"password" json:"password"`
NumOfWorkers int `yaml:"concurrent_workers" json:"concurrent_workers"`
RefreshEverySeconds int `yaml:"check_for_changes_every_secs" json:"check_for_changes_every_secs"`
@@ -78,6 +82,14 @@ func (z *ZurgConfig) GetPort() string {
return z.Port
}
func (z *ZurgConfig) GetUsername() string {
return z.Username
}
func (z *ZurgConfig) GetPassword() string {
return z.Password
}
func (z *ZurgConfig) GetNumOfWorkers() int {
if z.NumOfWorkers == 0 {
return 50

View File

@@ -0,0 +1,17 @@
package handlers
import "net/http"
func (hs *Handlers) basicAuth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if !ok || username != hs.cfg.GetUsername() || password != hs.cfg.GetPassword() {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted"`)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(http.StatusText(http.StatusUnauthorized)))
return
}
next.ServeHTTP(w, r)
})
}

View File

@@ -151,7 +151,7 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
</tr>
<tr>
<td>Premium</td>
<td>%d seconds</td>
<td>%d days</td>
</tr>
<tr>
<td>Expiration</td>
@@ -267,28 +267,28 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
response.UserInfo.Points,
response.UserInfo.Locale,
response.UserInfo.Type,
response.UserInfo.Premium,
response.UserInfo.Expiration,
response.UserInfo.Premium/86400,
strings.Replace(response.UserInfo.Expiration, "Z", "+01:00", 1),
response.Config.Version,
strings.Replace(response.Config.Token, response.Config.Token[len(response.Config.Token)-48:], "*****", 1),
response.Config.Host,
response.Config.Port,
response.Config.NumOfWorkers,
response.Config.RefreshEverySeconds,
response.Config.RetainRDTorrentName,
response.Config.RetainFolderNameExtension,
response.Config.CanRepair,
response.Config.DeleteRarFiles,
response.Config.RealDebridTimeout,
response.Config.UseDownloadCache,
response.Config.RateLimitSleepSeconds,
response.Config.RetriesUntilFailed,
response.Config.GetHost(),
response.Config.GetPort(),
response.Config.GetNumOfWorkers(),
response.Config.GetRefreshEverySeconds(),
response.Config.EnableRetainRDTorrentName(),
response.Config.EnableRetainFolderNameExtension(),
response.Config.EnableRepair(),
response.Config.ShouldDeleteRarFiles(),
response.Config.GetRealDebridTimeout(),
response.Config.EnableDownloadCache(),
response.Config.GetRateLimitSleepSeconds(),
response.Config.GetRetriesUntilFailed(),
strings.Join(response.Config.PreferredHosts, ", "),
response.Config.NetworkBufferSize,
response.Config.ServeFromRclone,
response.Config.VerifyDownloadLink,
response.Config.ForceIPv6,
response.Config.OnLibraryUpdate,
response.Config.GetNetworkBufferSize(),
response.Config.ShouldServeFromRclone(),
response.Config.ShouldVerifyDownloadLink(),
response.Config.ShouldForceIPv6(),
response.Config.GetOnLibraryUpdate(),
)
fmt.Fprint(resp, out)

View File

@@ -0,0 +1,13 @@
package handlers
import "net/http"
func (hs *Handlers) options(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}

View File

@@ -39,7 +39,10 @@ func AttachHandlers(router *chi.Mux, downloader *universal.Downloader, torMgr *t
log: log,
}
router.Use(optionsMiddleware)
if cfg.GetUsername() != "" {
router.Use(hs.basicAuth)
}
router.Use(hs.options)
router.Get("/", hs.handleHome)
// version
@@ -283,16 +286,6 @@ func (hs *Handlers) moveTorrentHandler(resp http.ResponseWriter, req *http.Reque
resp.WriteHeader(http.StatusNoContent)
}
func optionsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
// universal handlers
func (hs *Handlers) handleDownloadFile(resp http.ResponseWriter, req *http.Request) {

View File

@@ -133,11 +133,11 @@ func (t *TorrentManager) repair(torrent *Torrent) {
if t.reinsertTorrent(torrent, "") {
t.log.Infof("Successfully downloaded torrent %s to repair it", torrent.AccessKey)
return
} else if !torrent.Unfixable {
t.log.Warnf("Failed to repair by reinserting torrent %s, will only redownload broken files...", torrent.AccessKey)
} else {
} else if torrent.Unfixable {
t.log.Warnf("Cannot repair torrent %s", torrent.AccessKey)
return
} else {
t.log.Warnf("Failed to repair by reinserting torrent %s, will only redownload broken files...", torrent.AccessKey)
}
} else {
t.log.Warnf("Torrent %s is not older than %d hours to be repaired by reinsertion, will only redownload broken files...", torrent.AccessKey, EXPIRED_LINK_TOLERANCE_HOURS)
@@ -210,9 +210,7 @@ func (t *TorrentManager) repair(torrent *Torrent) {
})
t.log.Debugf("During repair, zurg found %d broken files for torrent %s", len(brokenFiles), torrent.AccessKey)
// todo: to verify removed logic when there's only 1 selected file selected and it's broken
if len(brokenFiles) == 1 && torrent.SelectedFiles.Count() > 1 {
if len(brokenFiles) == 1 && torrent.SelectedFiles.Count() > 2 {
// if we download a single file, it will be named differently
// so we need to download 1 extra file to preserve the name
// this is only relevant if we enable retain_rd_torrent_name
@@ -227,7 +225,7 @@ func (t *TorrentManager) repair(torrent *Torrent) {
}
if len(brokenFiles) > 0 {
t.log.Infof("Redownloading the %d broken files for torrent %s", len(brokenFiles), torrent.AccessKey)
t.log.Infof("Redownloading %dof%d files for torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), torrent.AccessKey)
brokenFileIDs := strings.Join(getFileIDs(brokenFiles), ",")
if t.reinsertTorrent(torrent, brokenFileIDs) {
t.log.Infof("Successfully downloaded torrent %s to repair it", torrent.AccessKey)