-
Notifications
You must be signed in to change notification settings - Fork 25
/
main.go
108 lines (88 loc) · 2.9 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
import (
"flag"
"fmt"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"log"
"net/http"
"os"
)
type RouteBuilder struct {
Issuer string
InfoLogger *log.Logger
ErrorLogger *log.Logger
KeyStore *KeyStore
}
func (rb RouteBuilder) Build(router *mux.Router) {
keyHandler := KeyHandler{
BasicHandler{
keyStore: rb.KeyStore,
infoLogger: rb.InfoLogger,
errorLogger: rb.ErrorLogger,
},
}
keysRouter := router.Methods("GET").Subrouter()
keysRouter.HandleFunc("/keys", keyHandler.ListKeys)
rb.InfoLogger.Println("GET /keys returns a list of the identifiers of available keys")
keysRouter.HandleFunc(fmt.Sprintf("/keys/{%s}", KeyIDVariableName), keyHandler.GetKey)
rb.InfoLogger.Println("GET /keys/{kid} returns the public key associated with the given key identifier. There is no way to look up the associated private key.")
issueHandler := IssueHandler{
BasicHandler: BasicHandler{
keyStore: rb.KeyStore,
infoLogger: rb.InfoLogger,
errorLogger: rb.ErrorLogger,
},
decoder: schema.NewDecoder(),
issuer: rb.Issuer,
}
issueRouter := router.
Path("/jws").
Queries(KeyIDVariableName, "").
Subrouter()
issueRouter.Methods("GET").
HandlerFunc(issueHandler.SimpleIssue)
rb.InfoLogger.Println("GET /jws?kid={kid} generates a JWT signed with the associated private key. Additional URL parameters are interpreted as reserved claims, e.g. exp")
issueRouter.Methods("PUT", "POST").
Headers("Content-Type", "application/json").
HandlerFunc(issueHandler.IssueUsingBody)
rb.InfoLogger.Println("PUT/POST /jws generates a JWT signed with the associated private key. Additional URL parmaeters are interpreted as reserved claims, e.g. exp")
}
func main() {
infoLogger := log.New(os.Stdout, "[INFO] ", log.LstdFlags|log.LUTC)
errorLogger := log.New(os.Stderr, "[ERROR] ", log.LstdFlags|log.LUTC)
var configurationFileName string
flag.StringVar(&configurationFileName, "f", "", "the required configuration file")
flag.Parse()
configuration, err := ParseConfiguration(configurationFileName)
if err != nil {
errorLogger.Fatalf("Unable to parse configuration file: %s\n", err)
}
keyStore, err := NewKeyStore(infoLogger, configuration)
if err != nil {
errorLogger.Fatalf("Unable to initialize key store: %s\n", err)
}
infoLogger.Printf("Initialized key store with %d keys: %s\n", keyStore.Len(), keyStore.KeyIDs())
issuer := configuration.Issuer
if len(issuer) == 0 {
issuer = DefaultIssuer
}
router := mux.NewRouter()
RouteBuilder{
Issuer: issuer,
ErrorLogger: errorLogger,
InfoLogger: infoLogger,
KeyStore: keyStore,
}.Build(router)
bindAddress := configuration.BindAddress
if len(bindAddress) == 0 {
bindAddress = DefaultBindAddress
}
server := &http.Server{
Addr: bindAddress,
Handler: router,
ErrorLog: errorLogger,
}
infoLogger.Printf("Listening on %s\n", bindAddress)
log.Fatalln(server.ListenAndServe())
}