From b7406bd82786a1481092cd898a05cc3850753c89 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 12 Mar 2018 21:44:43 -0500 Subject: [PATCH] More work on auth and req ctx --- .gitignore | 2 +- src/api/routes/router.go | 23 +++++++++++++++++++---- src/my-prayer-journal.go | 3 +-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 0583941..fe673e2 100644 --- a/.gitignore +++ b/.gitignore @@ -256,6 +256,6 @@ paket-files/ src/api/build src/api/public/index.html src/api/public/static -src/api/appsettings.json +src/config.json /build src/*.exe diff --git a/src/api/routes/router.go b/src/api/routes/router.go index 7390156..6d1e8fb 100644 --- a/src/api/routes/router.go +++ b/src/api/routes/router.go @@ -1,9 +1,11 @@ package routes import ( + "context" "database/sql" "fmt" "net/http" + "time" auth0 "github.com/auth0-community/go-auth0" "github.com/julienschmidt/httprouter" @@ -17,14 +19,22 @@ type AuthConfig struct { ClientSecret string `json:"secret"` } -// DBHandler extends httprouter's handler with a DB instance +// DBHandler extends httprouter's handler with a DB instance. type DBHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *sql.DB) //type APIHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *sql.DB, string) +// ContextKey is the type of key used in our contexts. +type ContextKey string + +// ContextUserKey is the key for the current user in the context. +const ContextUserKey ContextKey = "user" + func withDB(next DBHandler, db *sql.DB) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - next(w, r, p, db) + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(60*time.Second)) + defer cancel() + next(w, r.WithContext(ctx), p, db) } } @@ -32,9 +42,9 @@ func withAuth(next DBHandler, cfg *AuthConfig) DBHandler { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params, db *sql.DB) { secret := []byte(cfg.ClientSecret) secretProvider := auth0.NewKeyProvider(secret) - audience := []string{"{YOUR-AUTH0-API-AUDIENCE}"} + audience := []string{fmt.Sprintf("https://%s/userinfo", cfg.Domain)} - configuration := auth0.NewConfiguration(secretProvider, audience, fmt.Sprintf("https://%s.auth0.com/", cfg.Domain), jose.HS256) + configuration := auth0.NewConfiguration(secretProvider, audience, fmt.Sprintf("https://%s/", cfg.Domain), jose.HS256) validator := auth0.NewValidator(configuration) token, err := validator.ValidateRequest(r) @@ -45,6 +55,11 @@ func withAuth(next DBHandler, cfg *AuthConfig) DBHandler { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized")) } else { + values := make(map[string]interface{}) + if err := token.Claims(secret, &values); err != nil { + sendError(w, r, err) + } + r = r.WithContext(context.WithValue(r.Context(), ContextUserKey, values["sub"])) // TODO pass the user ID (sub) along; this -> doesn't work | r.Header.Add("user-id", token.Claims("sub")) next(w, r, p, db) } diff --git a/src/my-prayer-journal.go b/src/my-prayer-journal.go index 647587e..8e94488 100644 --- a/src/my-prayer-journal.go +++ b/src/my-prayer-journal.go @@ -30,9 +30,8 @@ func readSettings(f string) *Settings { log.Fatal(err) } defer config.Close() - parser := json.NewDecoder(config) settings := Settings{} - if err = parser.Decode(&settings); err != nil { + if err = json.NewDecoder(config).Decode(&settings); err != nil { log.Fatal(err) } return &settings