Skip to content

Commit 389b393

Browse files
committed
Upgrade to github.com/ory/hydra-client-go/v2. Acceptance test ory/hydra work with updated npm package and go library
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
1 parent c6c2d78 commit 389b393

7 files changed

Lines changed: 202 additions & 499 deletions

File tree

go.mod

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ require (
2222
github.com/fatih/color v1.14.1
2323
github.com/gdamore/tcell v1.3.0
2424
github.com/getsentry/sentry-go v0.20.0
25-
github.com/go-openapi/runtime v0.19.26
26-
github.com/go-openapi/strfmt v0.21.3
2725
github.com/gofrs/uuid v4.0.0+incompatible
2826
github.com/gogo/protobuf v1.3.2
2927
github.com/golang-migrate/migrate v3.5.4+incompatible
@@ -50,7 +48,7 @@ require (
5048
github.com/olekukonko/tablewriter v0.0.5
5149
github.com/olivere/elastic/v7 v7.0.12
5250
github.com/ory/dockertest/v3 v3.8.1
53-
github.com/ory/hydra-client-go v1.9.2
51+
github.com/ory/hydra-client-go/v2 v2.2.0
5452
github.com/ory/kratos-client-go v1.3.8
5553
github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5
5654
github.com/prometheus/client_golang v1.14.0
@@ -80,7 +78,7 @@ require (
8078
golang.org/x/exp v0.0.0-20230307190834-24139beb5833
8179
golang.org/x/mod v0.20.0
8280
golang.org/x/net v0.36.0
83-
golang.org/x/oauth2 v0.6.0
81+
golang.org/x/oauth2 v0.21.0
8482
golang.org/x/sync v0.11.0
8583
golang.org/x/sys v0.30.0
8684
golang.org/x/term v0.29.0
@@ -151,14 +149,9 @@ require (
151149
github.com/go-errors/errors v1.4.2 // indirect
152150
github.com/go-logr/logr v1.2.3 // indirect
153151
github.com/go-logr/stdr v1.2.2 // indirect
154-
github.com/go-openapi/analysis v0.21.4 // indirect
155-
github.com/go-openapi/errors v0.20.3 // indirect
156152
github.com/go-openapi/jsonpointer v0.19.6 // indirect
157153
github.com/go-openapi/jsonreference v0.20.2 // indirect
158-
github.com/go-openapi/loads v0.21.2 // indirect
159-
github.com/go-openapi/spec v0.20.8 // indirect
160154
github.com/go-openapi/swag v0.22.3 // indirect
161-
github.com/go-openapi/validate v0.22.1 // indirect
162155
github.com/goccy/go-json v0.10.2 // indirect
163156
github.com/goccy/go-yaml v1.9.8 // indirect
164157
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
@@ -244,7 +237,6 @@ require (
244237
github.com/spf13/jwalterweatherman v1.1.0 // indirect
245238
github.com/src-d/gcfg v1.4.0 // indirect
246239
github.com/subosito/gotenv v1.2.0 // indirect
247-
github.com/tidwall/pretty v1.2.0 // indirect
248240
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
249241
github.com/xanzy/ssh-agent v0.2.1 // indirect
250242
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
@@ -256,7 +248,6 @@ require (
256248
go.etcd.io/etcd/client/v2 v2.305.8 // indirect
257249
go.etcd.io/etcd/pkg/v3 v3.5.8 // indirect
258250
go.etcd.io/etcd/raft/v3 v3.5.8 // indirect
259-
go.mongodb.org/mongo-driver v1.11.3 // indirect
260251
go.opencensus.io v0.24.0 // indirect
261252
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 // indirect
262253
go.opentelemetry.io/otel v1.14.0 // indirect
@@ -276,7 +267,7 @@ require (
276267
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
277268
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
278269
google.golang.org/appengine v1.6.7 // indirect
279-
google.golang.org/protobuf v1.29.1 // indirect
270+
google.golang.org/protobuf v1.31.0 // indirect
280271
gopkg.in/inf.v0 v0.9.1 // indirect
281272
gopkg.in/ini.v1 v1.67.0 // indirect
282273
gopkg.in/launchdarkly/go-jsonstream.v1 v1.0.1 // indirect

go.sum

Lines changed: 6 additions & 151 deletions
Large diffs are not rendered by default.

go_deps.bzl

Lines changed: 19 additions & 201 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cloud/shared/idprovider/BUILD.bazel

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ go_library(
2424
visibility = ["//src/cloud:__subpackages__"],
2525
deps = [
2626
"//src/shared/services/handler",
27-
"@com_github_go_openapi_runtime//client",
28-
"@com_github_go_openapi_strfmt//:strfmt",
2927
"@com_github_gorilla_sessions//:sessions",
30-
"@com_github_ory_hydra_client_go//client",
31-
"@com_github_ory_hydra_client_go//client/admin",
32-
"@com_github_ory_hydra_client_go//models",
28+
"@com_github_ory_hydra_client_go_v2//:hydra-client-go",
3329
"@com_github_ory_kratos_client_go//:kratos-client-go",
3430
"@com_github_sirupsen_logrus//:logrus",
3531
"@com_github_spf13_pflag//:pflag",
@@ -47,8 +43,7 @@ pl_go_test(
4743
embed = [":idprovider"],
4844
deps = [
4945
"@com_github_gorilla_sessions//:sessions",
50-
"@com_github_ory_hydra_client_go//client/admin",
51-
"@com_github_ory_hydra_client_go//models",
46+
"@com_github_ory_hydra_client_go_v2//:hydra-client-go",
5247
"@com_github_ory_kratos_client_go//:kratos-client-go",
5348
"@com_github_stretchr_testify//assert",
5449
"@com_github_stretchr_testify//require",

src/cloud/shared/idprovider/client.go

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,8 @@ import (
3131
"os"
3232
"strings"
3333

34-
httptransport "github.com/go-openapi/runtime/client"
35-
"github.com/go-openapi/strfmt"
3634
"github.com/gorilla/sessions"
37-
hydra "github.com/ory/hydra-client-go/client"
38-
hydraAdmin "github.com/ory/hydra-client-go/client/admin"
39-
hydraModels "github.com/ory/hydra-client-go/models"
35+
hydra "github.com/ory/hydra-client-go/v2"
4036
kratos "github.com/ory/kratos-client-go"
4137
log "github.com/sirupsen/logrus"
4238
"github.com/spf13/pflag"
@@ -89,10 +85,10 @@ type HydraKratosConfig struct {
8985
const HydraLoginStateKey string = "hydra_login_state"
9086

9187
type hydraAdminClientService interface {
92-
AcceptConsentRequest(params *hydraAdmin.AcceptConsentRequestParams) (*hydraAdmin.AcceptConsentRequestOK, error)
93-
AcceptLoginRequest(params *hydraAdmin.AcceptLoginRequestParams) (*hydraAdmin.AcceptLoginRequestOK, error)
94-
GetConsentRequest(params *hydraAdmin.GetConsentRequestParams) (*hydraAdmin.GetConsentRequestOK, error)
95-
IntrospectOAuth2Token(params *hydraAdmin.IntrospectOAuth2TokenParams) (*hydraAdmin.IntrospectOAuth2TokenOK, error)
88+
AcceptOAuth2ConsentRequest(context.Context) hydra.OAuth2APIAcceptOAuth2ConsentRequestRequest
89+
AcceptOAuth2LoginRequest(context.Context) hydra.OAuth2APIAcceptOAuth2LoginRequestRequest
90+
GetOAuth2ConsentRequest(context.Context) hydra.OAuth2APIGetOAuth2ConsentRequestRequest
91+
IntrospectOAuth2Token(context.Context) hydra.OAuth2APIIntrospectOAuth2TokenRequest
9692
}
9793

9894
type kratosPublicClientService interface {
@@ -142,17 +138,18 @@ func createHTTPClient() (*http.Client, error) {
142138
return client, nil
143139
}
144140

145-
func createRuntime(path string, client *http.Client) (*httptransport.Runtime, error) {
146-
u, err := url.Parse(path)
141+
func createHydraClient(host string, client *http.Client) (*hydra.APIClient, error) {
142+
u, err := url.Parse(host)
147143
if err != nil {
148144
return nil, err
149145
}
150-
return httptransport.NewWithClient(
151-
u.Host,
152-
u.Path,
153-
[]string{u.Scheme},
154-
client,
155-
), nil
146+
147+
conf := hydra.NewConfiguration()
148+
conf.Host = u.Host
149+
conf.Scheme = u.Scheme
150+
conf.Servers = hydra.ServerConfigurations{{URL: host}}
151+
conf.HTTPClient = client
152+
return hydra.NewAPIClient(conf), nil
156153
}
157154

158155
func createKratosClient(host string, client *http.Client) (*kratos.APIClient, error) {
@@ -180,12 +177,10 @@ func NewHydraKratosClientFromConfig(cfg *HydraKratosConfig) (*HydraKratosClient,
180177
}
181178
}
182179

183-
hydraAdminRuntime, err := createRuntime(cfg.HydraAdminHost, httpClient)
180+
hydraAdminClient, err := createHydraClient(cfg.HydraAdminHost, httpClient)
184181
if err != nil {
185182
return nil, err
186183
}
187-
// We specify the Admin client to avoid confusing bugs because the Public client is held behind a different endpoint.
188-
hydraAdminClient := hydra.New(hydraAdminRuntime, strfmt.NewFormats()).Admin
189184

190185
// One can theoretically send public requests to the Admin Host but then kratos will
191186
// 302 the requests to the public host/port.
@@ -205,7 +200,7 @@ func NewHydraKratosClientFromConfig(cfg *HydraKratosConfig) (*HydraKratosClient,
205200
return &HydraKratosClient{
206201
Config: cfg,
207202
httpClient: httpClient,
208-
hydraAdminClient: hydraAdminClient,
203+
hydraAdminClient: hydraAdminClient.OAuth2API,
209204
kratosAdminClient: kratosAdminClient.IdentityAPI,
210205
kratosPublicClient: kratosPublicClient.FrontendAPI,
211206
}, nil
@@ -374,19 +369,14 @@ type RedirectResponse struct {
374369
// AcceptHydraLogin sends a request to accept the login on the hydra endpoint.
375370
func (c *HydraKratosClient) AcceptHydraLogin(ctx context.Context, challenge string, whoamiResp *Whoami) (*RedirectResponse, error) {
376371
subject := whoamiResp.ID()
377-
params := &hydraAdmin.AcceptLoginRequestParams{
378-
Body: &hydraModels.AcceptLoginRequest{
379-
Context: whoamiResp.kratosSession,
380-
Subject: &subject,
381-
},
382-
LoginChallenge: challenge,
383-
Context: ctx,
384-
}
385-
resp, err := c.hydraAdminClient.AcceptLoginRequest(params)
372+
body := hydra.NewAcceptOAuth2LoginRequest(subject)
373+
body.SetContext(whoamiResp.kratosSession)
374+
375+
resp, _, err := c.hydraAdminClient.AcceptOAuth2LoginRequest(ctx).LoginChallenge(challenge).AcceptOAuth2LoginRequest(*body).Execute()
386376
if err != nil {
387377
return nil, err
388378
}
389-
return &RedirectResponse{RedirectTo: resp.GetPayload().RedirectTo}, nil
379+
return &RedirectResponse{RedirectTo: &resp.RedirectTo}, nil
390380
}
391381

392382
// InterceptHydraUserConsent performs the user consent flow bypassing normal user interaction. Hydra uses
@@ -432,43 +422,35 @@ func (c *HydraKratosClient) AcceptConsent(ctx context.Context, challenge string)
432422
if challenge == "" {
433423
return nil, fmt.Errorf("challenge is empty")
434424
}
435-
resp, err := c.hydraAdminClient.GetConsentRequest(&hydraAdmin.GetConsentRequestParams{
436-
ConsentChallenge: challenge,
437-
Context: ctx,
438-
})
425+
resp, _, err := c.hydraAdminClient.GetOAuth2ConsentRequest(ctx).ConsentChallenge(challenge).Execute()
439426
if err != nil {
440427
log.Debug("error on hydra.consentRequest:")
441428
return nil, err
442429
}
443430

444-
if resp.GetPayload() == nil {
431+
if resp == nil {
445432
log.Debug("consent request payload is empty")
446-
return nil, err
433+
return nil, fmt.Errorf("consent request payload is empty")
447434
}
448435

449-
consentRequest := resp.GetPayload()
450-
451436
// We only trust the client that's passed in as a config here. In the future we might want to support other clients
452437
// at which point we will want to actually ask for permission from the user.
453438

454439
// TODO(ddelnano): This needs cannot be hard coded to auth-code-client, but should be set in the config.
455-
// if consentRequest.Client.ClientID != c.Config.HydraClientID {
456-
// return nil, fmt.Errorf("'%s' not an allowed client", consentRequest.Client.ClientID)
440+
// if resp.Client.ClientId != c.Config.HydraClientID {
441+
// return nil, fmt.Errorf("'%s' not an allowed client", resp.Client.ClientId)
457442
// }
458443

459-
acceptResp, err := c.hydraAdminClient.AcceptConsentRequest(&hydraAdmin.AcceptConsentRequestParams{
460-
Body: &hydraModels.AcceptConsentRequest{
461-
GrantScope: consentRequest.RequestedScope,
462-
GrantAccessTokenAudience: consentRequest.RequestedAccessTokenAudience,
463-
},
464-
ConsentChallenge: challenge,
465-
Context: ctx,
466-
})
444+
body := hydra.NewAcceptOAuth2ConsentRequest()
445+
body.SetGrantScope(resp.RequestedScope)
446+
body.SetGrantAccessTokenAudience(resp.RequestedAccessTokenAudience)
447+
448+
acceptResp, _, err := c.hydraAdminClient.AcceptOAuth2ConsentRequest(ctx).ConsentChallenge(challenge).AcceptOAuth2ConsentRequest(*body).Execute()
467449
if err != nil {
468450
log.Debug("error on hydra.AcceptConsentRequest:")
469451
return nil, err
470452
}
471-
return &RedirectResponse{RedirectTo: acceptResp.GetPayload().RedirectTo}, nil
453+
return &RedirectResponse{RedirectTo: &acceptResp.RedirectTo}, nil
472454
}
473455

474456
// HandleLogin handles the login for Hydra and Kratos.
@@ -554,16 +536,15 @@ func (c *HydraKratosClient) SessionKey() string {
554536

555537
// GetUserIDFromToken returns the userID from the subject portion of the access token.
556538
func (c *HydraKratosClient) GetUserIDFromToken(ctx context.Context, token string) (string, error) {
557-
params := &hydraAdmin.IntrospectOAuth2TokenParams{
558-
Context: ctx,
559-
Token: token,
560-
}
561-
res, err := c.hydraAdminClient.IntrospectOAuth2Token(params)
539+
res, _, err := c.hydraAdminClient.IntrospectOAuth2Token(ctx).Token(token).Execute()
562540
if err != nil {
563541
return "", err
564542
}
565543

566-
return res.GetPayload().Sub, nil
544+
if res.Sub == nil {
545+
return "", fmt.Errorf("token introspection returned nil subject")
546+
}
547+
return *res.Sub, nil
567548
}
568549

569550
// KratosUserInfo contains the user information format as stored in Kratos.

src/cloud/shared/idprovider/client_test.go

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ import (
2626
"testing"
2727

2828
"github.com/gorilla/sessions"
29-
hydraAdmin "github.com/ory/hydra-client-go/client/admin"
30-
hydraModels "github.com/ory/hydra-client-go/models"
29+
hydra "github.com/ory/hydra-client-go/v2"
3130
kratos "github.com/ory/kratos-client-go"
3231
"github.com/stretchr/testify/assert"
3332
"github.com/stretchr/testify/require"
@@ -45,7 +44,7 @@ type testClientConfig struct {
4544
idpConsentPath string
4645
hydraBrowserURL string
4746
hydraConsentPath string
48-
introspectOAuth2TokenFn *func(params *hydraAdmin.IntrospectOAuth2TokenParams) (*hydraAdmin.IntrospectOAuth2TokenOK, error)
47+
introspectOAuth2TokenFn func(string) (*hydra.IntrospectOAuth2TokenResponse, error)
4948
}
5049

5150
func fillDefaults(p *testClientConfig) *testClientConfig {
@@ -97,11 +96,9 @@ func makeClientFromConfig(t *testing.T, p *testClientConfig) (*HydraKratosClient
9796
http.Redirect(w, r, consentURL.String(), http.StatusFound)
9897
}))
9998

100-
acceptConsentRequestFn := func(params *hydraAdmin.AcceptConsentRequestParams) (*hydraAdmin.AcceptConsentRequestOK, error) {
101-
return &hydraAdmin.AcceptConsentRequestOK{
102-
Payload: &hydraModels.CompletedRequest{
103-
RedirectTo: &p.postLoginRedirect,
104-
},
99+
acceptConsentRequestFn := func(challenge string, body *hydra.AcceptOAuth2ConsentRequest) (*hydra.OAuth2RedirectTo, error) {
100+
return &hydra.OAuth2RedirectTo{
101+
RedirectTo: &p.postLoginRedirect,
105102
}, nil
106103
}
107104

@@ -116,7 +113,7 @@ func makeClientFromConfig(t *testing.T, p *testClientConfig) (*HydraKratosClient
116113
hydraAdminClient: &fakeHydraAdminClient{
117114
introspectOAuth2TokenFn: p.introspectOAuth2TokenFn,
118115
redirect: p.hydraBrowserURL + p.hydraConsentPath,
119-
acceptConsentRequestFn: &acceptConsentRequestFn,
116+
acceptConsentRequestFn: acceptConsentRequestFn,
120117
},
121118
kratosPublicClient: &kratosFakeAPI{},
122119
kratosAdminClient: &kratosFakeAPI{},
@@ -238,15 +235,18 @@ func TestRedirectToLogin(t *testing.T) {
238235

239236
func TestAcceptHydraLogin(t *testing.T) {
240237
loginChallenge := "abcdefgh"
241-
acceptLoginRequestFn := func(params *hydraAdmin.AcceptLoginRequestParams) (*hydraAdmin.AcceptLoginRequestOK, error) {
238+
acceptLoginRequestFn := func(challenge string, body *hydra.AcceptOAuth2LoginRequest) (*hydra.OAuth2RedirectTo, error) {
242239
// Make sure the loginChallenge is forwarded.
243-
assert.Equal(t, params.LoginChallenge, loginChallenge)
244-
// Call the original login request to handle the rest.
245-
return (&fakeHydraAdminClient{}).AcceptLoginRequest(params)
240+
assert.Equal(t, challenge, loginChallenge)
241+
// Return a redirect response
242+
redirect := "/redirect"
243+
return &hydra.OAuth2RedirectTo{
244+
RedirectTo: &redirect,
245+
}, nil
246246
}
247247
c, cleanup := makeClient(t)
248248
c.hydraAdminClient = &fakeHydraAdminClient{
249-
acceptLoginRequestFn: &acceptLoginRequestFn,
249+
acceptLoginRequestFn: acceptLoginRequestFn,
250250
}
251251
defer cleanup()
252252

@@ -309,35 +309,32 @@ func TestInterceptHydraConsent(t *testing.T) {
309309

310310
func TestAcceptConsent(t *testing.T) {
311311
consentChallenge := "123456789"
312-
getConsentRequestFn := func(params *hydraAdmin.GetConsentRequestParams) (*hydraAdmin.GetConsentRequestOK, error) {
313-
assert.Equal(t, consentChallenge, params.ConsentChallenge)
314-
return &hydraAdmin.GetConsentRequestOK{
315-
Payload: &hydraModels.ConsentRequest{
316-
Client: &hydraModels.OAuth2Client{
317-
ClientID: "hydra_client_id",
318-
},
319-
RequestedScope: []string{"openid", "offline"},
320-
RequestedAccessTokenAudience: []string{"api"},
312+
getConsentRequestFn := func(challenge string) (*hydra.OAuth2ConsentRequest, error) {
313+
assert.Equal(t, consentChallenge, challenge)
314+
clientID := "hydra_client_id"
315+
return &hydra.OAuth2ConsentRequest{
316+
Client: &hydra.OAuth2Client{
317+
ClientId: &clientID,
321318
},
319+
RequestedScope: []string{"openid", "offline"},
320+
RequestedAccessTokenAudience: []string{"api"},
322321
}, nil
323322
}
324323
redirectURL := "/oauth2/auth"
325-
acceptConsentRequestFn := func(params *hydraAdmin.AcceptConsentRequestParams) (*hydraAdmin.AcceptConsentRequestOK, error) {
326-
assert.ElementsMatch(t, []string{"openid", "offline"}, params.Body.GrantScope)
327-
assert.ElementsMatch(t, []string{"api"}, params.Body.GrantAccessTokenAudience)
328-
assert.Equal(t, consentChallenge, params.ConsentChallenge)
329-
return &hydraAdmin.AcceptConsentRequestOK{
330-
Payload: &hydraModels.CompletedRequest{
331-
RedirectTo: &redirectURL,
332-
},
324+
acceptConsentRequestFn := func(challenge string, body *hydra.AcceptOAuth2ConsentRequest) (*hydra.OAuth2RedirectTo, error) {
325+
assert.ElementsMatch(t, []string{"openid", "offline"}, body.GrantScope)
326+
assert.ElementsMatch(t, []string{"api"}, body.GrantAccessTokenAudience)
327+
assert.Equal(t, consentChallenge, challenge)
328+
return &hydra.OAuth2RedirectTo{
329+
RedirectTo: &redirectURL,
333330
}, nil
334331
}
335332
hydraAdminClient := &fakeHydraAdminClient{
336333
redirect: "/",
337334
consentChallenge: consentChallenge,
338335
oauthClientID: "hydra_client_id",
339-
getConsentRequestFn: &getConsentRequestFn,
340-
acceptConsentRequestFn: &acceptConsentRequestFn,
336+
getConsentRequestFn: getConsentRequestFn,
337+
acceptConsentRequestFn: acceptConsentRequestFn,
341338
}
342339
c := HydraKratosClient{
343340
Config: &HydraKratosConfig{

0 commit comments

Comments
 (0)