Skip to content

Commit

Permalink
Add /oauth/token dummy endpoint
Browse files Browse the repository at this point in the history
- The CF CLI requires a token endpoint during log streaming
- This endpoint provides a token with a valid expiration, which allows
  the CLI to proceed. The token is not used for actual authentication so
  it only needs to be in a parsable format.
- Eventually the CLI will be updated to skip this call but for now we
  need it.

[#1294]

Co-authored-by: Matt Royal <mroyal@vmware.com>
Co-authored-by: Julian Hjortshoj <hjortshojj@vmware.com>
  • Loading branch information
3 people committed Jul 14, 2022
1 parent 77c5e7e commit 6e1eca3
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 6 deletions.
1 change: 1 addition & 0 deletions api/handlers/authentication_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func NewAuthenticationMiddleware(authInfoParser AuthInfoParser, identityProvider
"/": struct{}{},
"/v3": struct{}{},
"/api/v1/info": struct{}{},
"/oauth/token": struct{}{},
},
}
}
Expand Down
52 changes: 52 additions & 0 deletions api/handlers/oauth_token_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package handlers

import (
"context"
"time"

"code.cloudfoundry.org/korifi/api/authorization"

"github.com/go-logr/logr"
"github.com/golang-jwt/jwt"
"github.com/gorilla/mux"
"net/http"
"net/url"
ctrl "sigs.k8s.io/controller-runtime"
)

const (
OAuthTokenPath = "/oauth/token"
)

type OAuthTokenHandler struct {
handlerWrapper *AuthAwareHandlerFuncWrapper
apiBaseURL url.URL
}

func NewOAuthToken(apiBaseURL url.URL) *OAuthTokenHandler {
return &OAuthTokenHandler{
handlerWrapper: NewUnauthenticatedHandlerFuncWrapper(ctrl.Log.WithName("OAuthTokenHandler")), //NewAuthAwareHandlerFuncWrapper(ctrl.Log.WithName("OAuthTokenHandler")),
apiBaseURL: apiBaseURL,
}
}

func (h *OAuthTokenHandler) oauthTokenHandler(ctx context.Context, logger logr.Logger, authInfo authorization.Info, r *http.Request) (*HandlerResponse, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"exp": time.Now().Add(time.Hour).Unix(),
})

tokenString, err := token.SignedString([]byte("not-a-real-secret"))
if err != nil {
// we don't expect to hit this ever, given that the string above is hard coded.
panic(err.Error())
}

return NewHandlerResponse(http.StatusOK).WithBody(map[string]string{
"token_type": "bearer",
"access_token": tokenString,
}), nil
}

func (h *OAuthTokenHandler) RegisterRoutes(router *mux.Router) {
router.Path(OAuthTokenPath).Methods("POST").HandlerFunc(h.handlerWrapper.Wrap(h.oauthTokenHandler))
}
58 changes: 58 additions & 0 deletions api/handlers/oauth_token_handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package handlers_test

import (
"encoding/json"
"net/http"
"time"

"code.cloudfoundry.org/korifi/api/authorization"
apis "code.cloudfoundry.org/korifi/api/handlers"

"github.com/SermoDigital/jose/jws"
"github.com/go-http-utils/headers"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("OAuthToken", func() {
const oauthTokenBase = "/oauth/token"

var (
OAuthTokenHandler *apis.OAuthTokenHandler
requestMethod string
requestPath string
)

BeforeEach(func() {
requestPath = oauthTokenBase
requestMethod = http.MethodPost
ctx = authorization.NewContext(ctx, &authorization.Info{Token: "the-token"})
OAuthTokenHandler = apis.NewOAuthToken(*serverURL)
OAuthTokenHandler.RegisterRoutes(router)
})

JustBeforeEach(func() {
req, err := http.NewRequestWithContext(ctx, requestMethod, requestPath, nil)
req.Header.Add(headers.Authorization, authHeader)
Expect(err).NotTo(HaveOccurred())

router.ServeHTTP(rr, req)
})

Describe("POST OAuthToken", func() {
It("returns 201 with appropriate success JSON", func() {
Expect(rr).To(HaveHTTPStatus(http.StatusOK))
Expect(rr).To(HaveHTTPHeaderWithValue("Content-Type", "application/json"))
jsonBody := map[string]string{}
Expect(json.NewDecoder(rr.Body).Decode(&jsonBody)).To(Succeed())
Expect(jsonBody).To(HaveKeyWithValue("token_type", "bearer"))
Expect(jsonBody).To(HaveKeyWithValue("access_token", Not(BeEmpty())))

tokenout, err := jws.ParseJWT([]byte(jsonBody["access_token"]))
Expect(err).NotTo(HaveOccurred())
expiration, ok := tokenout.Claims().Expiration()
Expect(ok).To(BeTrue())
Expect(expiration.Unix()).To(BeNumerically(">", time.Now().Add(time.Minute*59).Unix()))
})
})
})
12 changes: 7 additions & 5 deletions api/handlers/root_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ var _ = Describe("RootHandler", func() {
},
"network_policy_v0": nil,
"network_policy_v1": nil,
"login": nil,
"uaa": nil,
"credhub": nil,
"routing": nil,
"logging": nil,
"login": {
Link: presenter.Link{HRef: defaultServerURL},
},
"uaa": nil,
"credhub": nil,
"routing": nil,
"logging": nil,
"log_cache": {
Link: presenter.Link{HRef: defaultServerURL},
},
Expand Down
4 changes: 4 additions & 0 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ func main() {
taskRepo,
decoderValidator,
),

handlers.NewOAuthToken(
*serverURL,
),
}

router := mux.NewRouter()
Expand Down
2 changes: 1 addition & 1 deletion api/presenter/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func GetRootResponse(serverURL string) RootResponse {
"cloud_controller_v3": {Link: Link{HRef: serverURL + "/v3"}, Meta: APILinkMeta{Version: V3APIVersion}},
"network_policy_v0": nil,
"network_policy_v1": nil,
"login": nil,
"login": {Link: Link{HRef: serverURL}},
"uaa": nil,
"credhub": nil,
"routing": nil,
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5
code.cloudfoundry.org/eirini-controller v0.7.0
code.cloudfoundry.org/go-loggregator/v8 v8.0.5
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2
github.com/buildpacks/lifecycle v0.14.1
github.com/buildpacks/pack v0.27.0
github.com/cloudfoundry/cf-test-helpers v1.0.1-0.20220603211108-d498b915ef74
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/ReneKroon/ttlcache/v2 v2.7.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY=
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2 h1:koK7z0nSsRiRiBWwa+E714Puh+DO+ZRdIyAXiXzL+lg=
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
Expand Down

0 comments on commit 6e1eca3

Please sign in to comment.