2019-08-01 06:21:32 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
2020-05-10 21:22:40 +00:00
|
|
|
"io/ioutil"
|
2019-08-01 06:21:32 +00:00
|
|
|
"log"
|
|
|
|
"net/http"
|
2019-08-13 23:35:56 +00:00
|
|
|
"net/url"
|
2019-08-01 06:21:32 +00:00
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
|
2020-04-10 19:41:10 +00:00
|
|
|
"git.coolaj86.com/coolaj86/go-mockid/mockid"
|
2020-05-11 04:40:46 +00:00
|
|
|
"git.rootprojects.org/root/keypairs"
|
2019-08-19 03:34:19 +00:00
|
|
|
|
2020-04-10 19:41:10 +00:00
|
|
|
_ "github.com/joho/godotenv/autoload"
|
2020-04-10 19:29:01 +00:00
|
|
|
)
|
2019-08-19 05:04:55 +00:00
|
|
|
|
2019-08-01 06:21:32 +00:00
|
|
|
func main() {
|
|
|
|
done := make(chan bool)
|
|
|
|
var port int
|
2019-08-13 23:35:56 +00:00
|
|
|
var host string
|
2019-08-01 06:21:32 +00:00
|
|
|
|
|
|
|
portFlag := flag.Int("port", 0, "Port on which the HTTP server should run")
|
2019-08-13 23:35:56 +00:00
|
|
|
urlFlag := flag.String("url", "", "Outward-facing address, such as https://example.com")
|
2019-08-19 03:34:19 +00:00
|
|
|
prefixFlag := flag.String("jwkspath", "", "The path to the JWKs storage directory")
|
2019-08-01 06:21:32 +00:00
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
if nil != portFlag && *portFlag > 0 {
|
|
|
|
port = *portFlag
|
|
|
|
} else {
|
|
|
|
portStr := os.Getenv("PORT")
|
|
|
|
port, _ = strconv.Atoi(portStr)
|
|
|
|
}
|
|
|
|
if port < 1 {
|
|
|
|
fmt.Fprintf(os.Stderr, "You must specify --port or PORT\n")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2020-05-10 21:22:40 +00:00
|
|
|
jwkpath := "./default.jwk.json"
|
|
|
|
jwkb, err := ioutil.ReadFile(jwkpath)
|
|
|
|
if nil != err {
|
|
|
|
panic(fmt.Errorf("read default jwk %v: %w", jwkpath, err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-05-11 04:40:46 +00:00
|
|
|
privkey, err := keypairs.ParseJWKPrivateKey(jwkb)
|
2020-05-10 21:22:40 +00:00
|
|
|
if nil != err {
|
|
|
|
// TODO delete the bad file?
|
|
|
|
panic(fmt.Errorf("unmarshal jwk %v: %w", string(jwkb), err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-08-13 23:35:56 +00:00
|
|
|
if nil != urlFlag && "" != *urlFlag {
|
|
|
|
host = *urlFlag
|
|
|
|
} else {
|
|
|
|
host = "http://localhost:" + strconv.Itoa(port)
|
|
|
|
}
|
2019-08-01 06:21:32 +00:00
|
|
|
|
2020-04-10 19:41:10 +00:00
|
|
|
var jwksPrefix string
|
2019-08-19 03:34:19 +00:00
|
|
|
if nil != prefixFlag && "" != *prefixFlag {
|
|
|
|
jwksPrefix = *prefixFlag
|
|
|
|
} else {
|
|
|
|
jwksPrefix = "public-jwks"
|
|
|
|
}
|
2020-05-10 21:22:40 +00:00
|
|
|
err = os.MkdirAll(jwksPrefix, 0755)
|
2019-08-19 03:34:19 +00:00
|
|
|
if nil != err {
|
|
|
|
fmt.Fprintf(os.Stderr, "couldn't write %q: %s", jwksPrefix, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2020-05-11 04:40:46 +00:00
|
|
|
mockid.Route(jwksPrefix, privkey)
|
2019-08-19 03:34:19 +00:00
|
|
|
|
2020-05-10 21:22:40 +00:00
|
|
|
fs := http.FileServer(http.Dir("./public"))
|
2019-08-13 23:35:56 +00:00
|
|
|
http.Handle("/", fs)
|
|
|
|
/*
|
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
log.Printf(r.Method, r.URL.Path)
|
|
|
|
http.Error(w, "Not Found", http.StatusNotFound)
|
|
|
|
})
|
|
|
|
*/
|
2019-08-01 06:21:32 +00:00
|
|
|
|
|
|
|
fmt.Printf("Serving on port %d\n", port)
|
|
|
|
go func() {
|
|
|
|
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(port), nil))
|
|
|
|
done <- true
|
|
|
|
}()
|
|
|
|
|
2020-05-11 04:40:46 +00:00
|
|
|
// TODO privB := keypairs.MarshalJWKPrivateKey(privkey)
|
|
|
|
privB := mockid.MarshalJWKPrivateKey(privkey)
|
|
|
|
fmt.Printf("Private Key:\n\t%s\n", string(privB))
|
|
|
|
pubB := keypairs.MarshalJWKPublicKey(keypairs.NewPublicKey(privkey.Public()))
|
|
|
|
fmt.Printf("Public Key:\n\t%s\n", string(pubB))
|
|
|
|
protected, payload, token := mockid.GenToken(host, privkey, url.Values{})
|
2019-08-01 06:21:32 +00:00
|
|
|
fmt.Printf("Protected (Header):\n\t%s\n", protected)
|
|
|
|
fmt.Printf("Payload (Claims):\n\t%s\n", payload)
|
|
|
|
fmt.Printf("Access Token:\n\t%s\n", token)
|
|
|
|
|
|
|
|
<-done
|
|
|
|
}
|