Skip to content

Commit

Permalink
feat(jwt): add jwt auth to protected endpoints (#131)
Browse files Browse the repository at this point in the history
Co-authored-by: Leland Garofalo <[email protected]>
  • Loading branch information
lgarofalo and Leland Garofalo authored Aug 15, 2024
1 parent 81645a1 commit 0825b64
Show file tree
Hide file tree
Showing 162 changed files with 18,102 additions and 746 deletions.
11 changes: 6 additions & 5 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
FROM golang:1.22

FROM golang:alpine AS builder
WORKDIR /app
ADD . /app
RUN go build -o /sheltertech-go ./cmd/sheltertech-go

EXPOSE 3001

CMD [ "/app/tmp/sheltertech-go" ]
FROM golang:alpine
COPY --from=builder /sheltertech-go /sheltertech-go
CMD ["/sheltertech-go"]
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ fmt:
@gofmt -l -w $(SRC)

run:
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./tmp/sheltertech-go ./cmd/sheltertech-go && DOCKER_DEFAULT_PLATFORM="linux/amd64" docker-compose -f docker-compose.dev.yml build && docker-compose -f docker-compose.dev.yml up
docker compose -f docker-compose.dev.yml build && docker compose -f docker-compose.dev.yml up

hot-run:
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./tmp/sheltertech-go-hot ./cmd/sheltertech-go && DOCKER_DEFAULT_PLATFORM="linux/amd64" docker-compose -f docker-compose.hot.dev.yml build && docker-compose -f docker-compose.hot.dev.yml up
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./tmp/sheltertech-go-hot ./cmd/sheltertech-go && DOCKER_DEFAULT_PLATFORM="linux/amd64" docker compose -f docker-compose.hot.dev.yml build && docker compose -f docker-compose.hot.dev.yml up

ci-run:
docker-compose -f docker-compose.ci.yml build && docker-compose -f docker-compose.ci.yml up -d
docker compose -f docker-compose.ci.yml build && docker compose -f docker-compose.ci.yml up -d

build:
go build -v ./...
Expand Down
29 changes: 29 additions & 0 deletions cmd/sheltertech-go/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

const categoryUrl = "http://localhost:3001/api/categories"
const serviceUrl = "http://localhost:3001/api/services"
const bookmarkUrl = "http://localhost:3001/api/bookmarks"

func TestGetCategoriesFeatured(t *testing.T) {
startServer()
Expand Down Expand Up @@ -113,6 +114,33 @@ func TestGetServiceByID(t *testing.T) {

assert.Equal(t, serviceResponse.Service.Id, serviceId, "Service Id is a match")
}

func TestUnauthorized(t *testing.T) {
t.Skip("skipping until this is supported in dev")
startServer()

res, err := http.Get(bookmarkUrl)
require.NoError(t, err)
defer res.Body.Close()

require.Equal(t, http.StatusUnauthorized, res.StatusCode)
}

func TestAuthorized(t *testing.T) {
t.Skip("skipping until this is supported in dev")
startServer()

req, err := http.NewRequest(http.MethodGet, bookmarkUrl, nil)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer k")

res, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer res.Body.Close()

require.Equal(t, http.StatusOK, res.StatusCode)
}

func TestPostServicesChangeRequest(t *testing.T) {
startServer()

Expand Down Expand Up @@ -176,6 +204,7 @@ func startServer() {
viper.SetDefault("DB_PORT", "5432")
viper.SetDefault("DB_NAME", "askdarcel_development")
viper.SetDefault("DB_PASS", "")
viper.SetDefault("AUTH0_DOMAIN", "login.sfserviceguide.org")
go main()
time.Sleep(time.Second)
}
71 changes: 39 additions & 32 deletions cmd/sheltertech-go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/sheltertechsf/sheltertech-go/docs"
"github.com/sheltertechsf/sheltertech-go/internal/auth"
"github.com/sheltertechsf/sheltertech-go/internal/bookmarks"
"github.com/sheltertechsf/sheltertech-go/internal/categories"
"github.com/sheltertechsf/sheltertech-go/internal/changerequest"
Expand Down Expand Up @@ -57,7 +58,7 @@ func main() {
dbPass := viper.GetString("DB_PASS")
serveDocs := viper.GetBool("SERVE_DOCS")
auth0Domain := viper.GetString("AUTH0_DOMAIN")

enableJwtVerification := viper.GetBool("ENABLE_JWT_VERIFICATION")
var jwtKeyfunc keyfunc.Keyfunc
if auth0Domain != "" {
jwksUrl := "https://" + auth0Domain + "/.well-known/jwks.json"
Expand Down Expand Up @@ -96,37 +97,43 @@ func main() {
r.Use(middleware.Logger)
r.Use(sentryHandler.Handle)

r.Get("/api/categories", categoriesManager.Get)
r.Get("/api/categories/{id}", categoriesManager.GetByID)
r.Get("/api/categories/subcategories/{id}", categoriesManager.GetSubCategoriesByID)
r.Get("/api/categories/featured", categoriesManager.GetByFeatured)
r.Get("/api/categories/counts", categoriesManager.GetCategoryCounts)

// no user auth in folders yet
r.Get("/api/folders", foldersManager.Get)
r.Post("/api/folders", foldersManager.Post)
r.Get("/api/folders/{id}", foldersManager.GetByID)
r.Put("/api/folders/{id}", foldersManager.Put)
r.Delete("/api/folders/{id}", foldersManager.Delete)

r.Post("/api/services/{id}/change_request", changeRequestManager.Submit)
r.Get("/api/services/{id}", servicesManager.GetByID)
r.Get("/api/resources/{id}", resourcesManager.GetByID)
r.Get("/api/users/current", usersManager.GetCurrent)

r.Get("/metrics", promhttp.Handler().ServeHTTP)

r.Get("/api/bookmarks", bookmarksManager.Get)
r.Get("/api/bookmarks/{id}", bookmarksManager.GetByID)
r.Post("/api/bookmarks", bookmarksManager.Submit)
r.Put("/api/bookmarks/{id}", bookmarksManager.Update)
r.Delete("/api/bookmarks/{id}", bookmarksManager.DeleteByID)

r.Get("/api/saved_searches", savedSearchesManager.Get)
r.Post("/api/saved_searches", savedSearchesManager.Post)
r.Get("/api/saved_searches/{id}", savedSearchesManager.GetByID)
// r.Put("/api/saved_searches/{id}", savedSearchesManager.Put)
r.Delete("/api/saved_searches/{id}", savedSearchesManager.Delete)
r.Group(func(r chi.Router) {
if enableJwtVerification {
r.Use(auth.EnsureValidToken())
}
r.Get("/api/folders", foldersManager.Get)
r.Post("/api/folders", foldersManager.Post)
r.Get("/api/folders/{id}", foldersManager.GetByID)
r.Put("/api/folders/{id}", foldersManager.Put)
r.Delete("/api/folders/{id}", foldersManager.Delete)

r.Get("/api/bookmarks", bookmarksManager.Get)
r.Get("/api/bookmarks/{id}", bookmarksManager.GetByID)
r.Post("/api/bookmarks", bookmarksManager.Submit)
r.Put("/api/bookmarks/{id}", bookmarksManager.Update)
r.Delete("/api/bookmarks/{id}", bookmarksManager.DeleteByID)

r.Get("/api/saved_searches", savedSearchesManager.Get)
r.Post("/api/saved_searches", savedSearchesManager.Post)
r.Get("/api/saved_searches/{id}", savedSearchesManager.GetByID)
// r.Put("/api/saved_searches/{id}", savedSearchesManager.Put)
r.Delete("/api/saved_searches/{id}", savedSearchesManager.Delete)
})

r.Group(func(r chi.Router) {
r.Get("/api/categories", categoriesManager.Get)
r.Get("/api/categories/{id}", categoriesManager.GetByID)
r.Get("/api/categories/subcategories/{id}", categoriesManager.GetSubCategoriesByID)
r.Get("/api/categories/featured", categoriesManager.GetByFeatured)
r.Get("/api/categories/counts", categoriesManager.GetCategoryCounts)

r.Post("/api/services/{id}/change_request", changeRequestManager.Submit)
r.Get("/api/services/{id}", servicesManager.GetByID)
r.Get("/api/resources/{id}", resourcesManager.GetByID)
r.Get("/api/users/current", usersManager.GetCurrent)

r.Get("/metrics", promhttp.Handler().ServeHTTP)
})

docs.SwaggerInfo.Title = "Swagger Example API"
docs.SwaggerInfo.Description = "This is a sample server Petstore server."
Expand Down
14 changes: 9 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ toolchain go1.22.1

require github.com/go-chi/chi/v5 v5.1.0

require github.com/auth0/go-jwt-middleware/v2 v2.2.0

require (
github.com/MicahParks/keyfunc/v3 v3.3.3
github.com/getsentry/sentry-go v0.28.1
Expand Down Expand Up @@ -41,7 +43,7 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.19.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand Down Expand Up @@ -69,14 +71,16 @@ require (
github.com/ugorji/go/codec v1.2.12 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/go-jose/go-jose.v2 v2.6.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
28 changes: 16 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/MicahParks/jwkset v0.5.18 h1:WLdyMngF7rCrnstQxA7mpRoxeaWqGzPM/0z40PJU
github.com/MicahParks/jwkset v0.5.18/go.mod h1:q8ptTGn/Z9c4MwbcfeCDssADeVQb3Pk7PnVxrvi+2QY=
github.com/MicahParks/keyfunc/v3 v3.3.3 h1:c6j9oSu1YUo0k//KwF1miIQlEMtqNlj7XBFLB8jtEmY=
github.com/MicahParks/keyfunc/v3 v3.3.3/go.mod h1:f/UMyXdKfkZzmBeBFUeYk+zu066J1Fcl48f7Wnl5Z48=
github.com/auth0/go-jwt-middleware/v2 v2.2.0 h1:4WTpcHh+VZJOLEnS4E+hh+vP96Jy1tSbJOMnbJ29/KI=
github.com/auth0/go-jwt-middleware/v2 v2.2.0/go.mod h1:BFCz+RF+1szSkrGNJLYn2ng2PtfzBiKR6fynTvS2A/k=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bytedance/sonic v1.11.5 h1:G00FYjjqll5iQ1PYXynbg/hyzqBqavH8Mo9/oTopd9k=
Expand Down Expand Up @@ -54,8 +56,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
Expand Down Expand Up @@ -159,8 +161,8 @@ golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d h1:N0hmiNbwsSNwHBAvR3QB5w25pUwH4tK0Y/RltD1j1h4=
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
Expand All @@ -174,39 +176,41 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/go-jose/go-jose.v2 v2.6.1 h1:qEzJlIDmG9q5VO0M/o8tGS65QMHMS1w01TQJB1VPJ4U=
gopkg.in/go-jose/go-jose.v2 v2.6.1/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
70 changes: 70 additions & 0 deletions internal/auth/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// middleware/jwt.go

package auth

import (
"context"
"log"
"net/http"
"net/url"
"os"
"time"

jwtmiddleware "github.com/auth0/go-jwt-middleware/v2"
"github.com/auth0/go-jwt-middleware/v2/jwks"
"github.com/auth0/go-jwt-middleware/v2/validator"
)

// CustomClaims contains custom data we want from the token.
type CustomClaims struct {
Scope string `json:"scope"`
}

// Validate does nothing for this example, but we need
// it to satisfy validator.CustomClaims interface.
func (c CustomClaims) Validate(ctx context.Context) error {
return nil
}

// EnsureValidToken is a middleware that will check the validity of our JWT.
func EnsureValidToken() func(next http.Handler) http.Handler {
issuerURL, err := url.Parse("https://" + os.Getenv("AUTH0_DOMAIN") + "/")
if err != nil {
log.Fatalf("Failed to parse the issuer url: %v", err)
}

provider := jwks.NewCachingProvider(issuerURL, 5*time.Minute)

jwtValidator, err := validator.New(
provider.KeyFunc,
validator.RS256,
issuerURL.String(),
[]string{os.Getenv("AUTH0_AUDIENCE")},
validator.WithCustomClaims(
func() validator.CustomClaims {
return &CustomClaims{}
},
),
validator.WithAllowedClockSkew(time.Minute),
)
if err != nil {
log.Fatalf("Failed to set up the jwt validator")
}

errorHandler := func(w http.ResponseWriter, r *http.Request, err error) {
log.Printf("Encountered error while validating JWT: %v", err)

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(`{"message":"Failed to validate JWT."}`))
}

middleware := jwtmiddleware.New(
jwtValidator.ValidateToken,
jwtmiddleware.WithErrorHandler(errorHandler),
)

return func(next http.Handler) http.Handler {
return middleware.CheckJWT(next)
}
}
16 changes: 16 additions & 0 deletions vendor/github.com/auth0/go-jwt-middleware/v2/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions vendor/github.com/auth0/go-jwt-middleware/v2/.semgrepignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vendor/github.com/auth0/go-jwt-middleware/v2/.shiprc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0825b64

Please sign in to comment.