Add basic auth, fix xtream path (#40)

Signed-off-by: Pierre-Emmanuel Jacquier <15922119+pierre-emmanuelJ@users.noreply.github.com>
This commit is contained in:
Pierre-Emmanuel Jacquier
2020-05-18 11:20:19 +02:00
committed by GitHub
parent 20f07dc0a1
commit 5fea1d94fc
7 changed files with 38 additions and 20 deletions

View File

@@ -74,12 +74,12 @@ var rootCmd = &cobra.Command{
Port: viper.GetInt64("port"),
},
RemoteURL: remoteHostURL,
XtreamUser: xtreamUser,
XtreamPassword: xtreamPassword,
XtreamUser: config.CredentialString(xtreamUser),
XtreamPassword: config.CredentialString(xtreamPassword),
XtreamBaseURL: xtreamBaseURL,
M3UCacheExpiration: viper.GetInt("m3u-cache-expiration"),
User: viper.GetString("user"),
Password: viper.GetString("password"),
User: config.CredentialString(viper.GetString("user")),
Password: config.CredentialString(viper.GetString("password")),
HTTPS: viper.GetBool("https"),
M3UFileName: viper.GetString("m3u-file-name"),
CustomEndpoint: viper.GetString("custom-endpoint"),

View File

@@ -22,6 +22,19 @@ import (
"net/url"
)
// CredentialString represents an iptv-proxy credential.
type CredentialString string
// PathEscape escapes the credential for an url path.
func (c CredentialString) PathEscape() string {
return url.PathEscape(string(c))
}
// String returns the credential string.
func (c CredentialString) String() string {
return string(c)
}
// HostConfiguration containt host infos
type HostConfiguration struct {
Hostname string
@@ -31,13 +44,13 @@ type HostConfiguration struct {
// ProxyConfig Contain original m3u playlist and HostConfiguration
type ProxyConfig struct {
HostConfig *HostConfiguration
XtreamUser string
XtreamPassword string
XtreamUser CredentialString
XtreamPassword CredentialString
XtreamBaseURL string
M3UCacheExpiration int
M3UFileName string
CustomEndpoint string
RemoteURL *url.URL
HTTPS bool
User, Password string
User, Password CredentialString
}

View File

@@ -111,7 +111,7 @@ func (c *Config) hlsStream(ctx *gin.Context, oriURL *url.URL) {
return
}
body := string(b)
body = strings.ReplaceAll(body, "/"+c.XtreamUser+"/"+c.XtreamPassword+"/", "/"+c.User+"/"+c.Password+"/")
body = strings.ReplaceAll(body, "/"+c.XtreamUser.String()+"/"+c.XtreamPassword.String()+"/", "/"+c.User.String()+"/"+c.Password.String()+"/")
ctx.Data(http.StatusOK, hlsResp.Header.Get("Content-Type"), []byte(body))
return
}
@@ -140,7 +140,7 @@ func (c *Config) authenticate(ctx *gin.Context) {
ctx.AbortWithError(http.StatusBadRequest, err)
return
}
if c.ProxyConfig.User != authReq.Username || c.ProxyConfig.Password != authReq.Password {
if c.ProxyConfig.User.String() != authReq.Username || c.ProxyConfig.Password.String() != authReq.Password {
ctx.AbortWithStatus(http.StatusUnauthorized)
}
}
@@ -162,7 +162,7 @@ func (c *Config) appAuthenticate(ctx *gin.Context) {
return
}
log.Printf("[iptv-proxy] %v | %s |App Auth\n", time.Now().Format("2006/01/02 - 15:04:05"), ctx.ClientIP())
if c.ProxyConfig.User != q["username"][0] || c.ProxyConfig.Password != q["password"][0] {
if c.ProxyConfig.User.String() != q["username"][0] || c.ProxyConfig.Password.String() != q["password"][0] {
ctx.AbortWithStatus(http.StatusUnauthorized)
}

View File

@@ -34,8 +34,8 @@ func (c *Config) routes(r *gin.RouterGroup) {
if c.ProxyConfig.XtreamBaseURL != "" {
c.xtreamRoutes(r)
if strings.Contains(c.XtreamBaseURL, c.RemoteURL.Host) &&
c.XtreamUser == c.RemoteURL.Query().Get("username") &&
c.XtreamPassword == c.RemoteURL.Query().Get("password") {
c.XtreamUser.String() == c.RemoteURL.Query().Get("username") &&
c.XtreamPassword.String() == c.RemoteURL.Query().Get("password") {
r.GET("/"+c.M3UFileName, c.authenticate, c.xtreamGetAuto)
// XXX Private need: for external Android app

View File

@@ -22,7 +22,7 @@ import (
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/jamesnetherton/m3u"
"github.com/pierre-emmanuelJ/iptv-proxy/pkg/config"
@@ -136,17 +136,22 @@ func (c *Config) replaceURL(uri string, xtream bool) (string, error) {
path := oriURL.EscapedPath()
if xtream {
path = fmt.Sprintf("/%s", filepath.Base(path))
path = strings.ReplaceAll(path, c.XtreamUser.PathEscape(), c.User.PathEscape())
path = strings.ReplaceAll(path, c.XtreamPassword.PathEscape(), c.Password.PathEscape())
}
basicAuth := oriURL.User.String()
if basicAuth != "" {
basicAuth += "@"
}
newURI := fmt.Sprintf(
"%s://%s:%d%s/%s/%s%s",
"%s://%s%s:%d%s%s",
protocol,
basicAuth,
c.HostConfig.Hostname,
c.HostConfig.Port,
customEnd,
url.QueryEscape(c.User),
url.QueryEscape(c.Password),
path,
)

View File

@@ -160,7 +160,7 @@ func (c *Config) xtreamPlayerAPI(ctx *gin.Context, q url.Values) {
action = q["action"][0]
}
client, err := xtreamapi.New(c.XtreamUser, c.XtreamPassword, c.XtreamBaseURL)
client, err := xtreamapi.New(c.XtreamUser.String(), c.XtreamPassword.String(), c.XtreamBaseURL)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
return
@@ -183,7 +183,7 @@ func (c *Config) xtreamPlayerAPI(ctx *gin.Context, q url.Values) {
}
func (c *Config) xtreamXMLTV(ctx *gin.Context) {
client, err := xtreamapi.New(c.XtreamUser, c.XtreamPassword, c.XtreamBaseURL)
client, err := xtreamapi.New(c.XtreamUser.String(), c.XtreamPassword.String(), c.XtreamBaseURL)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
return

View File

@@ -149,7 +149,7 @@ func (c *Client) Action(config *config.ProxyConfig, action string, q url.Values)
}
respBody, err = c.GetEPG(q["stream_id"][0])
default:
respBody, err = c.login(config.User, config.Password, protocol+"://"+config.HostConfig.Hostname, int(config.HostConfig.Port), protocol)
respBody, err = c.login(config.User.String(), config.Password.String(), protocol+"://"+config.HostConfig.Hostname, int(config.HostConfig.Port), protocol)
}
return