2018-03-11 22:38:13 -05:00
|
|
|
package routes
|
|
|
|
|
|
|
|
import (
|
2018-03-12 21:44:43 -05:00
|
|
|
"context"
|
2018-03-11 22:38:13 -05:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
2018-03-20 20:26:02 -05:00
|
|
|
"github.com/auth0-community/go-auth0"
|
2018-03-22 22:11:38 -05:00
|
|
|
"github.com/husobee/vestigo"
|
2018-03-20 20:26:02 -05:00
|
|
|
"gopkg.in/square/go-jose.v2"
|
2018-03-11 22:38:13 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
// AuthConfig contains the Auth0 configuration passed from the "auth" JSON object.
|
|
|
|
type AuthConfig struct {
|
|
|
|
Domain string `json:"domain"`
|
|
|
|
ClientID string `json:"id"`
|
|
|
|
ClientSecret string `json:"secret"`
|
|
|
|
}
|
|
|
|
|
2018-03-12 21:44:43 -05:00
|
|
|
// 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"
|
|
|
|
|
2018-03-22 22:11:38 -05:00
|
|
|
func withAuth(next http.HandlerFunc, cfg *AuthConfig) http.HandlerFunc {
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2018-03-11 22:38:13 -05:00
|
|
|
secret := []byte(cfg.ClientSecret)
|
|
|
|
secretProvider := auth0.NewKeyProvider(secret)
|
2018-03-12 21:44:43 -05:00
|
|
|
audience := []string{fmt.Sprintf("https://%s/userinfo", cfg.Domain)}
|
2018-03-11 22:38:13 -05:00
|
|
|
|
2018-03-12 21:44:43 -05:00
|
|
|
configuration := auth0.NewConfiguration(secretProvider, audience, fmt.Sprintf("https://%s/", cfg.Domain), jose.HS256)
|
2018-03-20 20:26:02 -05:00
|
|
|
validator := auth0.NewValidator(configuration, nil)
|
2018-03-11 22:38:13 -05:00
|
|
|
|
|
|
|
token, err := validator.ValidateRequest(r)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
fmt.Println("Token is not valid:", token)
|
|
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
|
|
w.Write([]byte("Unauthorized"))
|
|
|
|
} else {
|
2018-03-12 21:44:43 -05:00
|
|
|
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"]))
|
2018-03-11 22:38:13 -05:00
|
|
|
// TODO pass the user ID (sub) along; this -> doesn't work | r.Header.Add("user-id", token.Claims("sub"))
|
2018-03-22 22:11:38 -05:00
|
|
|
next(w, r)
|
2018-03-11 22:38:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewRouter returns a configured router to handle all incoming requests.
|
2018-03-22 22:11:38 -05:00
|
|
|
func NewRouter(cfg *AuthConfig) *vestigo.Router {
|
|
|
|
router := vestigo.NewRouter()
|
2018-03-11 22:38:13 -05:00
|
|
|
for _, route := range routes {
|
|
|
|
if route.IsPublic {
|
2018-03-22 22:11:38 -05:00
|
|
|
router.Add(route.Method, route.Pattern, route.Func)
|
2018-03-11 22:38:13 -05:00
|
|
|
} else {
|
2018-03-22 22:11:38 -05:00
|
|
|
router.Add(route.Method, route.Pattern, withAuth(route.Func, cfg))
|
2018-03-11 22:38:13 -05:00
|
|
|
}
|
|
|
|
}
|
2018-03-22 22:11:38 -05:00
|
|
|
router.Get("/*", http.FileServer(http.Dir("/public")).ServeHTTP)
|
2018-03-11 22:38:13 -05:00
|
|
|
return router
|
|
|
|
}
|