adding ability to generate API keys
This commit is contained in:
14
config.toml
14
config.toml
@@ -1,14 +1,14 @@
|
|||||||
[serverConfig]
|
[serverConfig]
|
||||||
|
|
||||||
ServerPort = ":8000" #leave format as is it expects a string with colon
|
ServerPort = ":8000" #leave format as is it expects a string with colon
|
||||||
ServerAddr = "192.168.1.8" #Put in the IP address you want to bind to
|
ServerAddr = "192.168.1.100" #Put in the IP address you want to bind to
|
||||||
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
||||||
LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log
|
LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log
|
||||||
|
|
||||||
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
||||||
|
|
||||||
#Relative or absolute path accepted, the server will convert any relative path to an absolute path.
|
#Relative or absolute path accepted, the server will convert any relative path to an absolute path.
|
||||||
DefaultMoveFolder = 'Z:\downloads' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here
|
DefaultMoveFolder = 'downloads' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here
|
||||||
TorrentWatchFolder = 'torrentUpload' #folder path that is watched for .torrent files and adds them automatically every 5 minutes
|
TorrentWatchFolder = 'torrentUpload' #folder path that is watched for .torrent files and adds them automatically every 5 minutes
|
||||||
|
|
||||||
#Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start).
|
#Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start).
|
||||||
@@ -25,24 +25,24 @@
|
|||||||
|
|
||||||
[notifications]
|
[notifications]
|
||||||
|
|
||||||
PushBulletToken = "o.8sUHemPkTCaty3u7KnyvEBN19EkeT63g" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
PushBulletToken = "" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
||||||
|
|
||||||
[reverseProxy]
|
[reverseProxy]
|
||||||
#This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually)
|
#This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually)
|
||||||
ProxyEnabled = true #bool, either false or true
|
ProxyEnabled = false #bool, either false or true
|
||||||
#URL is CASE SENSITIVE
|
#URL is CASE SENSITIVE
|
||||||
BaseURL = "derajnet.duckdns.org/gopher/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/"
|
BaseURL = "domain.com/subroute/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/"
|
||||||
|
|
||||||
[EncryptionPolicy]
|
[EncryptionPolicy]
|
||||||
|
|
||||||
DisableEncryption = false
|
DisableEncryption = false
|
||||||
ForceEncryption = false
|
ForceEncryption = false
|
||||||
PreferNoEncryption = false
|
PreferNoEncryption = true
|
||||||
|
|
||||||
[torrentClientConfig]
|
[torrentClientConfig]
|
||||||
DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents
|
DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents
|
||||||
|
|
||||||
Seed = false #boolean #seed after download
|
Seed = true #boolean #seed after download
|
||||||
|
|
||||||
# Never send chunks to peers.
|
# Never send chunks to peers.
|
||||||
NoUpload = false #boolean
|
NoUpload = false #boolean
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
[serverConfig]
|
[serverConfig]
|
||||||
|
|
||||||
ServerPort = ":8000" #leave format as is it expects a string with colon
|
ServerPort = ":8000" #leave format as is it expects a string with colon
|
||||||
ServerAddr = "192.168.1.100" #Put in the IP address you want to bind to
|
ServerAddr = "192.168.1.8" #Put in the IP address you want to bind to
|
||||||
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
||||||
LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log
|
LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log
|
||||||
|
|
||||||
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
||||||
|
|
||||||
#Relative or absolute path accepted, the server will convert any relative path to an absolute path.
|
#Relative or absolute path accepted, the server will convert any relative path to an absolute path.
|
||||||
DefaultMoveFolder = 'downloads' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here
|
DefaultMoveFolder = 'Z:\downloads' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here
|
||||||
TorrentWatchFolder = 'torrentUpload' #folder path that is watched for .torrent files and adds them automatically every 5 minutes
|
TorrentWatchFolder = 'torrentUpload' #folder path that is watched for .torrent files and adds them automatically every 5 minutes
|
||||||
|
|
||||||
#Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start).
|
#Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start).
|
||||||
@@ -25,24 +25,24 @@
|
|||||||
|
|
||||||
[notifications]
|
[notifications]
|
||||||
|
|
||||||
PushBulletToken = "" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
PushBulletToken = "o.8sUHemPkTCaty3u7KnyvEBN19EkeT63g" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
||||||
|
|
||||||
[reverseProxy]
|
[reverseProxy]
|
||||||
#This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually)
|
#This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually)
|
||||||
ProxyEnabled = false #bool, either false or true
|
ProxyEnabled = false #bool, either false or true
|
||||||
#URL is CASE SENSITIVE
|
#URL is CASE SENSITIVE
|
||||||
BaseURL = "domain.com/subroute/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/"
|
BaseURL = "derajnet.duckdns.org/gopher/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/"
|
||||||
|
|
||||||
[EncryptionPolicy]
|
[EncryptionPolicy]
|
||||||
|
|
||||||
DisableEncryption = false
|
DisableEncryption = false
|
||||||
ForceEncryption = false
|
ForceEncryption = false
|
||||||
PreferNoEncryption = true
|
PreferNoEncryption = false
|
||||||
|
|
||||||
[torrentClientConfig]
|
[torrentClientConfig]
|
||||||
DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents
|
DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents
|
||||||
|
|
||||||
Seed = true #boolean #seed after download
|
Seed = false #boolean #seed after download
|
||||||
|
|
||||||
# Never send chunks to peers.
|
# Never send chunks to peers.
|
||||||
NoUpload = false #boolean
|
NoUpload = false #boolean
|
||||||
|
@@ -21,6 +21,7 @@ let serverMessage = [];
|
|||||||
let serverPushMessage = [];
|
let serverPushMessage = [];
|
||||||
let webSocketState = false;
|
let webSocketState = false;
|
||||||
let settingsFile = [];
|
let settingsFile = [];
|
||||||
|
let tokenReturn = "";
|
||||||
|
|
||||||
var torrentListRequest = {
|
var torrentListRequest = {
|
||||||
MessageType: "torrentListRequest"
|
MessageType: "torrentListRequest"
|
||||||
@@ -29,7 +30,7 @@ var torrentListRequest = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//websocket is started in kickwebsocket.js and is picked up here so "ws" is already defined 22
|
//websocket is started in kickwebsocket.js and is picked up here so "ws" is already defined
|
||||||
ws.onmessage = function (evt) { //When we recieve a message from the websocket
|
ws.onmessage = function (evt) { //When we recieve a message from the websocket
|
||||||
var serverMessage = JSON.parse(evt.data)
|
var serverMessage = JSON.parse(evt.data)
|
||||||
console.log("message", serverMessage.MessageType)
|
console.log("message", serverMessage.MessageType)
|
||||||
@@ -134,6 +135,10 @@ ws.onmessage = function (evt) { //When we recieve a message from the websocket
|
|||||||
settingsFile = [];
|
settingsFile = [];
|
||||||
console.log("Settings File Returned", serverMessage)
|
console.log("Settings File Returned", serverMessage)
|
||||||
settingsFile = serverMessage.Config
|
settingsFile = serverMessage.Config
|
||||||
|
|
||||||
|
case "TokenReturn":
|
||||||
|
tokenReturn = serverMessage.TokenReturn
|
||||||
|
console.log("Token Returned", serverMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -222,10 +227,15 @@ class BackendSocket extends React.Component {
|
|||||||
console.log("PROPSSERVER", this.props.serverPushMessage, "SERVERPUSH", serverPushMessage)
|
console.log("PROPSSERVER", this.props.serverPushMessage, "SERVERPUSH", serverPushMessage)
|
||||||
this.props.newServerMessage(serverPushMessage)
|
this.props.newServerMessage(serverPushMessage)
|
||||||
}
|
}
|
||||||
if (this.props.settingsModalOpen) { //TODO don't really need to updaate every tick currently until we can edit config
|
if (this.props.settingsModalOpen) { //TODO don't really need to update every tick currently until we can edit config
|
||||||
this.props.newSettingsFile(settingsFile)
|
this.props.newSettingsFile(settingsFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tokenReturn != ""){ //If we get a return token
|
||||||
|
console.log("Dispatching token return", tokenReturn)
|
||||||
|
this.props.newTokenReturn(tokenReturn)
|
||||||
|
}
|
||||||
|
|
||||||
ws.send(JSON.stringify(torrentListRequest))//talking to the server to get the torrent list
|
ws.send(JSON.stringify(torrentListRequest))//talking to the server to get the torrent list
|
||||||
if (ws.readyState === ws.CLOSED){ //if our websocket gets closed inform the user
|
if (ws.readyState === ws.CLOSED){ //if our websocket gets closed inform the user
|
||||||
webSocketState = false
|
webSocketState = false
|
||||||
@@ -264,6 +274,9 @@ class BackendSocket extends React.Component {
|
|||||||
if (nextProps.selectionHashes.length === 1){ //if we have a selection pass it on for the tabs to verify
|
if (nextProps.selectionHashes.length === 1){ //if we have a selection pass it on for the tabs to verify
|
||||||
this.selectionHandler(nextProps.selectionHashes, nextProps.selectedTab)
|
this.selectionHandler(nextProps.selectionHashes, nextProps.selectedTab)
|
||||||
}
|
}
|
||||||
|
if (nextProps.tokenReturn != this.props.tokenReturn){ //clearing out the token if we switch from the API tab
|
||||||
|
tokenReturn = nextProps.tokenReturn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,6 +300,7 @@ const mapStateToProps = state => {
|
|||||||
RSSTorrentList: state.RSSTorrentList,
|
RSSTorrentList: state.RSSTorrentList,
|
||||||
serverPushMessage: state.serverPushMessage,
|
serverPushMessage: state.serverPushMessage,
|
||||||
settingsModalOpen: state.settingsModalOpen,
|
settingsModalOpen: state.settingsModalOpen,
|
||||||
|
tokenReturn: state.tokenReturn,
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -301,9 +315,8 @@ const mapDispatchToProps = dispatch => {
|
|||||||
RSSTorrentList: (RSSTorrentList) => dispatch({type: actionTypes.RSS_TORRENT_LIST, RSSTorrentList}),
|
RSSTorrentList: (RSSTorrentList) => dispatch({type: actionTypes.RSS_TORRENT_LIST, RSSTorrentList}),
|
||||||
newServerMessage: (serverPushMessage) => dispatch({type: actionTypes.SERVER_MESSAGE, serverPushMessage}),
|
newServerMessage: (serverPushMessage) => dispatch({type: actionTypes.SERVER_MESSAGE, serverPushMessage}),
|
||||||
webSocketStateUpdate: (webSocketState) => dispatch({type: actionTypes.WEBSOCKET_STATE, webSocketState}),
|
webSocketStateUpdate: (webSocketState) => dispatch({type: actionTypes.WEBSOCKET_STATE, webSocketState}),
|
||||||
newSettingsFile: (settingsFile) => dispatch({type: actionTypes.NEW_SETTINGS_FILE, settingsFile})
|
newSettingsFile: (settingsFile) => dispatch({type: actionTypes.NEW_SETTINGS_FILE, settingsFile}),
|
||||||
//changeSelection: (selection) => dispatch({type: actionTypes.CHANGE_SELECTION, selection}),//forcing an update to the buttons
|
newTokenReturn: (tokenReturn) => dispatch({type: actionTypes.TOKEN_RETURN, tokenReturn}),
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,14 +3,18 @@ import ReactDOM from 'react-dom';
|
|||||||
import { withStyles } from 'material-ui/styles';
|
import { withStyles } from 'material-ui/styles';
|
||||||
import Paper from 'material-ui/Paper';
|
import Paper from 'material-ui/Paper';
|
||||||
import Grid from 'material-ui/Grid';
|
import Grid from 'material-ui/Grid';
|
||||||
|
import Button from 'material-ui/Button';
|
||||||
|
import TextField from 'material-ui/TextField';
|
||||||
|
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
|
import * as actionTypes from '../../../../store/actions';
|
||||||
|
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
root: {
|
root: {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
marginTop: 0,
|
marginTop: 0,
|
||||||
|
padding: 10,
|
||||||
},
|
},
|
||||||
paper: {
|
paper: {
|
||||||
padding: 16,
|
padding: 16,
|
||||||
@@ -23,19 +27,48 @@ const styles = theme => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
class APISettingsTab extends React.PureComponent {
|
class APISettingsTab extends React.Component {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
clientName: "",
|
||||||
|
};
|
||||||
|
|
||||||
requestNewKey = (keyName) => {
|
generateKey = (event) => {
|
||||||
|
let newAuthTokenRequest = {
|
||||||
|
MessageType: "newAuthToken",
|
||||||
|
Payload: {"ClientName": this.state.clientName}
|
||||||
|
}
|
||||||
|
console.log("Sending New Auth Request: ", newAuthTokenRequest);
|
||||||
|
ws.send(JSON.stringify(newAuthTokenRequest));
|
||||||
|
this.setState({clientName: ""})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setClientName = (event) => {
|
||||||
|
this.setState({clientName: event.target.value})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount = () => {
|
||||||
|
this.props.newTokenReturn("")
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes } = this.props;
|
const { classes } = this.props;
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
Not yet implemented!
|
<TextField style ={{width: '50%', paddingRight: '10px'}} id="clientName" type="text" label="Client Name" placeholder="Client Name associated with the key" onChange={this.setClientName} />
|
||||||
|
<Button variant="raised" color="primary" onClick={this.generateKey}>
|
||||||
|
Generate Key
|
||||||
|
</Button>
|
||||||
|
<Paper style = {{padding: '10px'}}> <span className={classes.floatLeft}>{this.props.tokenReturn} </span></Paper>
|
||||||
|
<Grid container spacing={16}>
|
||||||
|
|
||||||
|
<Grid item xs={12} sm={4}>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -44,9 +77,15 @@ class APISettingsTab extends React.PureComponent {
|
|||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
settingsFile: state.settingsFile,
|
tokenReturn: state.tokenReturn,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withStyles(styles)(connect(mapStateToProps)(APISettingsTab))
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
newTokenReturn: (tokenReturn) => dispatch({type: actionTypes.TOKEN_RETURN, tokenReturn}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(APISettingsTab))
|
||||||
|
|
||||||
|
@@ -15,3 +15,4 @@ export const NEW_SETTINGS_FILE = 'NEW_SETTINGS_FILE';
|
|||||||
export const RSS_TORRENT_LIST = 'RSS_TORRENT_LIST';
|
export const RSS_TORRENT_LIST = 'RSS_TORRENT_LIST';
|
||||||
export const SERVER_MESSAGE = 'SERVER_MESSAGE';
|
export const SERVER_MESSAGE = 'SERVER_MESSAGE';
|
||||||
export const WEBSOCKET_STATE = 'WEBSOCKET_STATE';
|
export const WEBSOCKET_STATE = 'WEBSOCKET_STATE';
|
||||||
|
export const TOKEN_RETURN = 'TOKEN_RETURN';
|
@@ -130,6 +130,13 @@ const reducer = (state = initialState, action) => {
|
|||||||
serverPushMessage: action.serverPushMessage
|
serverPushMessage: action.serverPushMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case actionTypes.TOKEN_RETURN:
|
||||||
|
console.log("New token return", action.tokenReturn)
|
||||||
|
return {
|
||||||
|
... state,
|
||||||
|
tokenReturn: action.tokenReturn
|
||||||
|
}
|
||||||
|
|
||||||
case actionTypes.SET_BUTTON_STATE:
|
case actionTypes.SET_BUTTON_STATE:
|
||||||
if (action.buttonState.length === 0) { //if selection is empty buttons will be default and selectionHashes will be blanked out and pushed to redux
|
if (action.buttonState.length === 0) { //if selection is empty buttons will be default and selectionHashes will be blanked out and pushed to redux
|
||||||
let buttonStateFinal = state.buttonStateDefault //if no selection dispatch that to redux
|
let buttonStateFinal = state.buttonStateDefault //if no selection dispatch that to redux
|
||||||
|
2
main.go
2
main.go
@@ -265,7 +265,7 @@ func main() {
|
|||||||
Logger.WithFields(logrus.Fields{"clientName": payloadData["ClientName"].(string)}).Info("New Auth Token creation request")
|
Logger.WithFields(logrus.Fields{"clientName": payloadData["ClientName"].(string)}).Info("New Auth Token creation request")
|
||||||
fmt.Println("Signing Key", signingKey)
|
fmt.Println("Signing Key", signingKey)
|
||||||
token := Settings.GenerateToken(claims, signingKey)
|
token := Settings.GenerateToken(claims, signingKey)
|
||||||
tokenReturn := Settings.TokenReturn{TokenReturn: token}
|
tokenReturn := Settings.TokenReturn{MessageType: "TokenReturn", TokenReturn: token}
|
||||||
tokensDB := Storage.FetchJWTTokens(db)
|
tokensDB := Storage.FetchJWTTokens(db)
|
||||||
tokensDB.TokenNames = append(tokens.TokenNames, Storage.SingleToken{payloadData["ClientName"].(string)})
|
tokensDB.TokenNames = append(tokens.TokenNames, Storage.SingleToken{payloadData["ClientName"].(string)})
|
||||||
db.Update(&tokensDB) //adding the new token client name to the database
|
db.Update(&tokensDB) //adding the new token client name to the database
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -8,12 +8,15 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//AuthRequest is a struct sent by a client with an authstring (JWT Token) to validate they have access to the server
|
||||||
type AuthRequest struct {
|
type AuthRequest struct {
|
||||||
MessageType string `json:"MessageType"`
|
MessageType string `json:"MessageType"`
|
||||||
AuthString string `json:"AuthString"`
|
AuthString string `json:"AuthString"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TokenReturn is a struct sent by the server to a client with a new generated authstring
|
||||||
type TokenReturn struct {
|
type TokenReturn struct {
|
||||||
|
MessageType string `json:"MessageType"`
|
||||||
TokenReturn string `json:"TokenReturn"`
|
TokenReturn string `json:"TokenReturn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user