| 
									
										
										
										
											2019-08-01 06:21:32 +00:00
										 |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"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" | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	jwkm := map[string]string{} | 
					
						
							|  |  |  | 	err = json.Unmarshal(jwkb, &jwkm) | 
					
						
							|  |  |  | 	if nil != err { | 
					
						
							|  |  |  | 		// TODO delete the bad file? | 
					
						
							|  |  |  | 		panic(fmt.Errorf("unmarshal jwk %v: %w", string(jwkb), err)) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	jwk := &mockid.PrivateJWK{ | 
					
						
							|  |  |  | 		PublicJWK: mockid.PublicJWK{ | 
					
						
							|  |  |  | 			Crv: jwkm["crv"], | 
					
						
							|  |  |  | 			X:   jwkm["x"], | 
					
						
							|  |  |  | 			Y:   jwkm["y"], | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		D: jwkm["d"], | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	priv := mockid.ParseKey(jwk) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-04-10 19:41:10 +00:00
										 |  |  | 	mockid.Route(jwksPrefix, priv, jwk) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	b, _ := json.Marshal(jwk) | 
					
						
							|  |  |  | 	fmt.Printf("Private Key:\n\t%s\n", string(b)) | 
					
						
							|  |  |  | 	b, _ = json.Marshal(jwk.PublicJWK) | 
					
						
							|  |  |  | 	fmt.Printf("Public Key:\n\t%s\n", string(b)) | 
					
						
							| 
									
										
										
										
											2020-04-10 19:29:01 +00:00
										 |  |  | 	protected, payload, token := mockid.GenToken(host, priv, 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 | 
					
						
							|  |  |  | } |