mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
fix auth play
This commit is contained in:
@@ -36,6 +36,17 @@ func stream(c *gin.Context) {
|
||||
_, play := c.GetQuery("play")
|
||||
title := c.Query("title")
|
||||
poster := c.Query("poster")
|
||||
notAuth := c.GetBool("not_auth")
|
||||
|
||||
if notAuth && play {
|
||||
streamNoAuth(c)
|
||||
return
|
||||
}
|
||||
if notAuth {
|
||||
c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if link == "" {
|
||||
c.AbortWithError(http.StatusBadRequest, errors.New("link should not be empty"))
|
||||
@@ -111,3 +122,68 @@ func stream(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func streamNoAuth(c *gin.Context) {
|
||||
link := c.Query("link")
|
||||
indexStr := c.Query("index")
|
||||
_, preload := c.GetQuery("preload")
|
||||
title := c.Query("title")
|
||||
poster := c.Query("poster")
|
||||
|
||||
// c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
|
||||
// c.AbortWithStatus(http.StatusUnauthorized)
|
||||
|
||||
if link == "" {
|
||||
c.AbortWithError(http.StatusBadRequest, errors.New("link should not be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
if title == "" {
|
||||
title = c.Param("fname")
|
||||
title, _ = url.PathUnescape(title)
|
||||
title = strings.TrimLeft(title, "/")
|
||||
} else {
|
||||
title, _ = url.QueryUnescape(title)
|
||||
}
|
||||
|
||||
link, _ = url.QueryUnescape(link)
|
||||
poster, _ = url.QueryUnescape(poster)
|
||||
|
||||
spec, err := utils.ParseLink(link)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
tor := torr.GetTorrent(spec.InfoHash.HexString())
|
||||
if tor == nil {
|
||||
c.AbortWithError(http.StatusNotFound, errors.New("Torrent not found"))
|
||||
return
|
||||
}
|
||||
|
||||
if !tor.GotInfo() {
|
||||
c.AbortWithError(http.StatusInternalServerError, errors.New("timeout connection torrent"))
|
||||
return
|
||||
}
|
||||
|
||||
// find file
|
||||
index := -1
|
||||
if len(tor.Files()) == 1 {
|
||||
index = 1
|
||||
} else {
|
||||
ind, err := strconv.Atoi(indexStr)
|
||||
if err == nil {
|
||||
index = ind
|
||||
}
|
||||
}
|
||||
if index == -1 { // if file index not set and play file exec
|
||||
c.AbortWithError(http.StatusBadRequest, errors.New("\"index\" is empty or wrong"))
|
||||
return
|
||||
}
|
||||
// preload torrent
|
||||
if preload {
|
||||
torr.Preload(tor, index)
|
||||
}
|
||||
|
||||
tor.Stream(index, c.Request, c.Writer)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
@@ -19,7 +24,7 @@ func SetupAuth(engine *gin.Engine) *gin.RouterGroup {
|
||||
if accs == nil {
|
||||
return nil
|
||||
}
|
||||
return engine.Group("/", gin.BasicAuth(accs))
|
||||
return engine.Group("/", BasicAuth(accs))
|
||||
}
|
||||
|
||||
func getAccounts() gin.Accounts {
|
||||
@@ -34,3 +39,62 @@ func getAccounts() gin.Accounts {
|
||||
}
|
||||
return accs
|
||||
}
|
||||
|
||||
type authPair struct {
|
||||
value string
|
||||
user string
|
||||
}
|
||||
type authPairs []authPair
|
||||
|
||||
func (a authPairs) searchCredential(authValue string) (string, bool) {
|
||||
if authValue == "" {
|
||||
return "", false
|
||||
}
|
||||
for _, pair := range a {
|
||||
if pair.value == authValue {
|
||||
return pair.user, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func BasicAuth(accounts gin.Accounts) gin.HandlerFunc {
|
||||
pairs := processAccounts(accounts)
|
||||
return func(c *gin.Context) {
|
||||
user, found := pairs.searchCredential(c.Request.Header.Get("Authorization"))
|
||||
if !found {
|
||||
if strings.HasPrefix(c.FullPath(), "/stream") {
|
||||
c.Set("not_auth", true)
|
||||
return
|
||||
}
|
||||
c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
c.Set(gin.AuthUserKey, user)
|
||||
}
|
||||
}
|
||||
|
||||
func processAccounts(accounts gin.Accounts) authPairs {
|
||||
pairs := make(authPairs, 0, len(accounts))
|
||||
for user, password := range accounts {
|
||||
value := authorizationHeader(user, password)
|
||||
pairs = append(pairs, authPair{
|
||||
value: value,
|
||||
user: user,
|
||||
})
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
func authorizationHeader(user, password string) string {
|
||||
base := user + ":" + password
|
||||
return "Basic " + base64.StdEncoding.EncodeToString(StringToBytes(base))
|
||||
}
|
||||
|
||||
func StringToBytes(s string) (b []byte) {
|
||||
sh := *(*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
bh.Data, bh.Len, bh.Cap = sh.Data, sh.Len, sh.Len
|
||||
return b
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user