streamdeck-remote-server/main.go

143 lines
2.6 KiB
Go
Raw Normal View History

2019-05-21 04:02:20 +00:00
package main
import (
"github.com/atotto/clipboard"
"github.com/getlantern/systray"
"io/ioutil"
"log"
"math/rand"
"meow.tf/streamdeck-remote-server/icon"
"net/http"
"net/url"
"os"
"strings"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
func main() {
systray.Run(onReady, onExit)
}
func onReady() {
systray.SetIcon(icon.Data)
systray.SetTitle("StreamDeck Remote")
systray.SetTooltip("StreamDeck Remote Server (Running)")
mCopy := systray.AddMenuItem("Copy Token", "Copy the token to the clipboard")
mQuit := systray.AddMenuItem("Quit", "Close StreamDeck Remote Server")
go listenServer()
go func() {
for {
select {
case <-mCopy.ClickedCh:
clipboard.WriteAll(token)
case <-mQuit.ClickedCh:
systray.Quit()
}
}
}()
}
func onExit() {
// clean up here
}
var (
token string
)
func loadToken() {
if _, err := os.Stat("token.txt"); os.IsNotExist(err) {
token = RandStringRunes(32)
f, err := os.Create("token.txt")
if err != nil {
log.Fatalln("Unable to save token:", err)
}
defer f.Close()
f.WriteString(token)
} else {
f, err := os.Open("token.txt")
if err != nil {
log.Fatalln("Unable to open token file:", err)
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
f.Close()
log.Fatalln("Unable to read token file:", err)
}
token = string(b)
}
}
func listenServer() {
loadToken()
if _, err := os.Stat("server.crt"); os.IsNotExist(err) {
err = generateCert("server.crt", "server.key")
if err != nil {
log.Fatalln("Unable to generate certificates:", err)
}
}
mux := http.NewServeMux()
mux.HandleFunc("/url/open", authenticationHandler(requirePost(urlOpenHandler)))
http.ListenAndServeTLS(":4443", "server.crt", "server.key", mux)
}
func authenticationHandler(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Check authorization header
auth := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
if len(auth) != 2 || auth[0] != "Bearer" || auth[1] != token {
log.Println("Authentication failed, got:", auth[1])
http.Error(w, "authorization failed", http.StatusUnauthorized)
return
}
next(w, r)
}
}
func urlOpenHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
urlStr := r.Form.Get("url")
if urlStr == "" {
w.WriteHeader(http.StatusBadRequest)
log.Println("empty url")
return
}
u, err := url.Parse(urlStr)
if err != nil || u.Scheme == "" || u.Host == "" {
w.WriteHeader(http.StatusBadRequest)
log.Println("invalid url scheme/host or err:", err)
return
}
log.Println("Opening URL", urlStr)
openUrl(urlStr)
}