fix auth play

This commit is contained in:
YouROK
2021-03-04 11:11:23 +03:00
parent 3302ad6371
commit c74c4790b0
2 changed files with 141 additions and 1 deletions

View File

@@ -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)
}

View File

@@ -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
}