Reverse Proxy with SSL support, Generated client Configs, JWT client to server auth, closes #13

This commit is contained in:
2018-02-07 21:41:00 -05:00
parent 0abe1620c6
commit d6288f4aaa
17 changed files with 1816 additions and 1222 deletions

View File

@@ -0,0 +1,60 @@
package engine
import (
"crypto/rand"
"math/big"
"github.com/dgrijalva/jwt-go"
"github.com/sirupsen/logrus"
)
type AuthRequest struct {
MessageType string `json:"MessageType"`
AuthString string `json:"AuthString"`
}
//GoTorrentClaims stores the name of the client (usually user entered) and any standard jwt claims we want to define
type GoTorrentClaims struct {
ClientName string `json:"clientName"`
jwt.StandardClaims
}
//GenerateToken creates a signed token for a client to use to communicate with the server
func GenerateToken(claims GoTorrentClaims, signingKey []byte) string {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signedString, err := token.SignedString(signingKey)
if err != nil {
Logger.WithFields(logrus.Fields{"error": err}).Fatal("Error signing authentication Token!")
}
return signedString
}
//GenerateSigningKey creates a random key that will be used for JSON Web Token authentication
func GenerateSigningKey() []byte {
keyString, err := generateRandomASCIIString(24)
key := []byte(keyString)
if err != nil {
Logger.WithFields(logrus.Fields{"error": err}).Fatal("Error generating signing key!")
}
return key
}
func generateRandomASCIIString(length int) (string, error) {
result := ""
for {
if len(result) >= length {
return result, nil
}
num, err := rand.Int(rand.Reader, big.NewInt(int64(127)))
if err != nil {
return "", err
}
n := num.Int64()
// Make sure that the number/byte/letter is inside
// the range of printable ASCII characters (excluding space and DEL)
if n > 32 && n < 127 {
result += string(n)
}
}
}

View File

@@ -0,0 +1,50 @@
package engine
import (
"io/ioutil"
"os"
)
var (
baseFile = `
var authMessage = {
MessageType: "authRequest",
Payload: [ClientAuthString]
}
var kickStart = {
MessageType: "torrentListRequest"
}
ws.onopen = function()
{
ws.send(JSON.stringify(authMessage));
console.log("Sending authentication message...", JSON.stringify(authMessage))
ws.send(JSON.stringify(kickStart)); //sending out the first ping
console.log("Kicking off websocket to server.....", JSON.stringify(kickStart))
};`
)
//GenerateClientConfigFile runs at first run (no db client detected) to generate a js file for connecting
func GenerateClientConfigFile(config FullClientSettings, authString string) {
os.Remove("public/static/js/kickwebsocket-generated.js")
var clientFile string
if config.UseProxy {
clientFile = `
ClientAuthString = "` + authString + `"
var ws = new WebSocket("wss://` + config.BaseURL + `websocket")
` + baseFile
} else {
clientFile = `
IP = "` + config.HTTPAddrIP + `"
Port = "` + config.WebsocketClientPort + `"
ClientAuthString = "` + authString + `"
var ws = new WebSocket(` + "`" + `ws://${IP}:${Port}/websocket` + "`" + `); //creating websocket
` + baseFile
}
clientFileBytes := []byte(clientFile)
ioutil.WriteFile("public/static/js/kickwebsocket-generated.js", clientFileBytes, 0755)
}

View File

@@ -41,7 +41,7 @@ type RSSFeedsNames struct {
}
//TorrentList struct contains the torrent list that is sent to the client
type TorrentList struct { //helps create the JSON structure that react expects to recieve
type TorrentList struct { //helps create the JSON structure that react expects to receive
MessageType string `json:"MessageType"`
Totaltorrents int `json:"total"`
ClientDBstruct []ClientDB `json:"data"`

View File

@@ -3,6 +3,7 @@ package engine
import (
"fmt"
"path/filepath"
"strings"
"golang.org/x/time/rate"
@@ -14,16 +15,20 @@ import (
//FullClientSettings contains all of the settings for our entire application
type FullClientSettings struct {
LoggingLevel logrus.Level
LoggingOutput string
HTTPAddr string
Version int
TorrentConfig torrent.Config
TFileUploadFolder string
SeedRatioStop float64
PushBulletToken string
DefaultMoveFolder string
TorrentWatchFolder string
LoggingLevel logrus.Level
LoggingOutput string
HTTPAddr string
HTTPAddrIP string
UseProxy bool
WebsocketClientPort string
BaseURL string
Version int
TorrentConfig torrent.Config
TFileUploadFolder string
SeedRatioStop float64
PushBulletToken string
DefaultMoveFolder string
TorrentWatchFolder string
}
//default is called if there is a parsing error
@@ -98,9 +103,17 @@ func FullClientSettingsNew() FullClientSettings {
}
var httpAddr string
var baseURL string
var websocketClientPort string
httpAddrIP := viper.GetString("serverConfig.ServerAddr")
httpAddrPort := viper.GetString("serverConfig.ServerPort")
proxySet := viper.GetBool("reverseProxy.ProxyEnabled")
websocketClientPort = strings.TrimLeft(viper.GetString("serverConfig.ServerPort"), ":") //Trimming off the colon in front of the port
if proxySet {
baseURL = viper.GetString("reverseProxy.BaseURL")
fmt.Println("WebsocketClientPort", viper.GetString("serverConfig.ServerPort"))
}
seedRatioStop := viper.GetFloat64("serverConfig.SeedRatioStop")
httpAddr = httpAddrIP + httpAddrPort
pushBulletToken := viper.GetString("notifications.PushBulletToken")
@@ -192,15 +205,19 @@ func FullClientSettingsNew() FullClientSettings {
}
Config := FullClientSettings{
LoggingLevel: logLevel,
LoggingOutput: logOutput,
SeedRatioStop: seedRatioStop,
HTTPAddr: httpAddr,
TorrentConfig: tConfig,
TFileUploadFolder: "uploadedTorrents",
PushBulletToken: pushBulletToken,
DefaultMoveFolder: defaultMoveFolderAbs,
TorrentWatchFolder: torrentWatchFolderAbs,
LoggingLevel: logLevel,
LoggingOutput: logOutput,
SeedRatioStop: seedRatioStop,
HTTPAddr: httpAddr,
HTTPAddrIP: httpAddrIP,
UseProxy: proxySet,
WebsocketClientPort: websocketClientPort,
TorrentConfig: tConfig,
BaseURL: baseURL,
TFileUploadFolder: "uploadedTorrents",
PushBulletToken: pushBulletToken,
DefaultMoveFolder: defaultMoveFolderAbs,
TorrentWatchFolder: torrentWatchFolderAbs,
}
return Config