Commit a2f4c01
Changed files (9)
cmd/server/main.go
@@ -27,7 +27,7 @@ func main() {
}
server := &http.Server{
Addr: ":8282",
- Handler: web.NewMux(issuer, privateKey),
+ Handler: web.NewRoutes(issuer, privateKey),
ReadTimeout: 0,
WriteTimeout: 0,
IdleTimeout: 0,
pkg/web/http_context.go
@@ -1,6 +1,9 @@
package web
-import "log"
+import (
+ "log"
+ "net/http"
+)
type HttpContext struct {
issuer string
@@ -15,3 +18,22 @@ func NewHttpContext(issuer string, keyData []byte) *HttpContext {
log: log.Default(),
}
}
+
+func (h *HttpContext) Router() *http.ServeMux {
+ mux := http.NewServeMux()
+
+ mux.Handle("/", http.HandlerFunc(h.Default))
+ mux.Handle("/.well-known/", http.StripPrefix("/.well-known", wellKnownMux(h)))
+ mux.Handle("/authorize", http.HandlerFunc(h.Authorize))
+ mux.Handle("/revoke", http.HandlerFunc(http.NotFound))
+ mux.Handle("/token", http.HandlerFunc(h.Token))
+ mux.Handle("/userinfo", http.HandlerFunc(http.NotFound))
+ return mux
+}
+
+func wellKnownMux(h *HttpContext) *http.ServeMux {
+ mux := http.NewServeMux()
+ mux.Handle("/jwks.json", http.HandlerFunc(h.JsonWebKeySets))
+ mux.Handle("/openid-configuration", http.HandlerFunc(h.OpenIdConfiguration))
+ return mux
+}
pkg/web/json_web_key_sets.go
@@ -0,0 +1,36 @@
+package web
+
+import (
+ "crypto/x509"
+ "encoding/json"
+ "encoding/pem"
+ "net/http"
+
+ "github.com/lestrrat-go/jwx/v2/jwk"
+)
+
+type JsonWebKeySet struct {
+ Keys []RsaJsonWebKey `json:"keys"`
+}
+
+type RsaJsonWebKey struct {
+ E string `json:"e"`
+ KeyId string `json:"kid"`
+ KeyType string `json:"kty"`
+ N string `json:"n"`
+ Use string `json:"use"`
+}
+
+func (h *HttpContext) JsonWebKeySets(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ privatePem, _ := pem.Decode(h.keyData)
+ parsedKey, _ := x509.ParsePKCS1PrivateKey(privatePem.Bytes)
+ key, _ := jwk.FromRaw(parsedKey)
+ pubKey, _ := jwk.PublicKeyOf(key)
+ pubKey.Set(jwk.KeyIDKey, "X")
+ pubKey.Set(jwk.KeyUsageKey, "sig")
+
+ set := jwk.NewSet()
+ set.Add(pubKey)
+ json.NewEncoder(w).Encode(set)
+}
pkg/web/json_web_key_sets_test.go
@@ -0,0 +1,43 @@
+package web
+
+import (
+ "bytes"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/json"
+ "encoding/pem"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestJsonWebKeySets(t *testing.T) {
+ key, _ := rsa.GenerateKey(rand.Reader, 1024)
+ b := new(bytes.Buffer)
+ pem.Encode(b, &pem.Block{
+ Type: "RSA PRIVATE KEY",
+ Bytes: x509.MarshalPKCS1PrivateKey(key),
+ })
+
+ h := NewHttpContext("https://example.org", b.Bytes())
+
+ t.Run(".well-known/jwks.json", func(t *testing.T) {
+ w := httptest.NewRecorder()
+ r := httptest.NewRequest("GET", "/.well-known/jwks.json", nil)
+
+ h.Router().ServeHTTP(w, r)
+
+ assert.Equal(t, w.Header().Get("Content-Type"), "application/json")
+
+ var c JsonWebKeySet
+ json.NewDecoder(w.Body).Decode(&c)
+
+ assert.Equal(t, 1, len(c.Keys))
+ assert.Equal(t, "X", c.Keys[0].KeyId)
+ assert.Equal(t, "RSA", c.Keys[0].KeyType)
+ assert.NotEmpty(t, c.Keys[0].E)
+ assert.NotEmpty(t, c.Keys[0].N)
+ })
+}
pkg/web/mux.go
@@ -1,18 +0,0 @@
-package web
-
-import (
- "net/http"
-)
-
-func NewMux(issuer string, keyData []byte) http.Handler {
- h := NewHttpContext(issuer, keyData)
- mux := http.NewServeMux()
- mux.Handle("/", http.HandlerFunc(h.Default))
- mux.Handle("/.well-known/jwks.json", http.HandlerFunc(h.WellKnown))
- mux.Handle("/.well-known/openid-configuration", http.HandlerFunc(h.WellKnown))
- mux.Handle("/authorize", http.HandlerFunc(h.Authorize))
- mux.Handle("/revoke", http.HandlerFunc(http.NotFound))
- mux.Handle("/token", http.HandlerFunc(h.Token))
- mux.Handle("/userinfo", http.HandlerFunc(http.NotFound))
- return mux
-}
pkg/web/well_known.go → pkg/web/open_id_configuration.go
@@ -1,14 +1,9 @@
package web
import (
- "crypto/x509"
_ "embed"
- "encoding/json"
- "encoding/pem"
"net/http"
"text/template"
-
- "github.com/lestrrat-go/jwx/v2/jwk"
)
//go:embed templates/openid-configuration.json
@@ -33,33 +28,7 @@ type OpenIdConfiguration struct {
ClaimsSupported []string `json:"claims_supported"`
}
-type JsonWebKeySet struct {
- Keys []RsaJsonWebKey `json:"keys"`
-}
-
-type RsaJsonWebKey struct {
- E string `json:"e"`
- KeyId string `json:"kid"`
- KeyType string `json:"kty"`
- N string `json:"n"`
- Use string `json:"use"`
-}
-
-func (h *HttpContext) WellKnown(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path == "/.well-known/openid-configuration" {
- w.Header().Set("Content-Type", "application/json")
- tmpl.Execute(w, struct{ Issuer string }{Issuer: h.issuer})
- } else if r.URL.Path == "/.well-known/jwks.json" {
- w.Header().Set("Content-Type", "application/json")
- privatePem, _ := pem.Decode(h.keyData)
- parsedKey, _ := x509.ParsePKCS1PrivateKey(privatePem.Bytes)
- key, _ := jwk.FromRaw(parsedKey)
- pubKey, _ := jwk.PublicKeyOf(key)
- pubKey.Set(jwk.KeyIDKey, "X")
- pubKey.Set(jwk.KeyUsageKey, "sig")
-
- set := jwk.NewSet()
- set.Add(pubKey)
- json.NewEncoder(w).Encode(set)
- }
+func (h *HttpContext) OpenIdConfiguration(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
+ tmpl.Execute(w, struct{ Issuer string }{Issuer: h.issuer})
}
pkg/web/well_known_test.go → pkg/web/open_id_configuration_test.go
@@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestWellKnown(t *testing.T) {
+func TestOpenIdConfiguration(t *testing.T) {
key, _ := rsa.GenerateKey(rand.Reader, 1024)
b := new(bytes.Buffer)
pem.Encode(b, &pem.Block{
@@ -27,7 +27,7 @@ func TestWellKnown(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/.well-known/openid-configuration", nil)
- h.WellKnown(w, r)
+ h.Router().ServeHTTP(w, r)
assert.Equal(t, w.Header().Get("Content-Type"), "application/json")
@@ -64,22 +64,4 @@ func TestWellKnown(t *testing.T) {
"sub",
})
})
-
- t.Run(".well-known/jwks.json", func(t *testing.T) {
- w := httptest.NewRecorder()
- r := httptest.NewRequest("GET", "/.well-known/jwks.json", nil)
-
- h.WellKnown(w, r)
-
- assert.Equal(t, w.Header().Get("Content-Type"), "application/json")
-
- var c JsonWebKeySet
- json.NewDecoder(w.Body).Decode(&c)
-
- assert.Equal(t, 1, len(c.Keys))
- assert.Equal(t, "X", c.Keys[0].KeyId)
- assert.Equal(t, "RSA", c.Keys[0].KeyType)
- assert.NotEmpty(t, c.Keys[0].E)
- assert.NotEmpty(t, c.Keys[0].N)
- })
}
pkg/web/routes.go
@@ -0,0 +1,9 @@
+package web
+
+import (
+ "net/http"
+)
+
+func NewRoutes(issuer string, keyData []byte) http.Handler {
+ return NewHttpContext(issuer, keyData).Router()
+}
Makefile
@@ -22,7 +22,7 @@ server: bin/$(NAME) ## Start server
.PHONY: test
test: ## Run tests
- go test -race $(PACKAGES)
+ go test -v -race $(PACKAGES)
.PHONY: help
help: