From 9c582989d9f46eb4d3b1cbfddf44e2734dd8c196 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 11:58:03 +0200 Subject: [PATCH 001/185] chore(deps): bump actions/setup-go from 4 to 5 (#498) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab22f8d..42f8d4a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... From bca8833c15fa96da2ed04aa3e5830ae0c2d89ac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 11:59:11 +0200 Subject: [PATCH 002/185] chore(deps): bump github.com/google/uuid from 1.4.0 to 1.5.0 (#499) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d78f707..62d42a5 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/go-jose/go-jose/v3 v3.0.1 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/gorilla/securecookie v1.1.2 github.com/jeremija/gosubmit v0.2.7 github.com/muhlemmer/gu v0.3.1 diff --git a/go.sum b/go.sum index 3bf2861..8cff8d2 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= From 7bdaf9c71db5666c15a79f0a7b68865c75d4be2c Mon Sep 17 00:00:00 2001 From: snow <47487241+snowkat@users.noreply.github.com> Date: Sun, 17 Dec 2023 04:06:42 -0800 Subject: [PATCH 003/185] feat(op): User-configurable claims_supported (#495) * User-configurable claims_supported * Use op.SupportedClaims instead of interface --- pkg/op/discovery.go | 30 +++++------------------------- pkg/op/op.go | 28 ++++++++++++++++++++++++++++ pkg/op/op_test.go | 1 + 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index 8251261..6af1674 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -213,32 +213,12 @@ func AuthMethodsRevocationEndpoint(c Configuration) []oidc.AuthMethod { } func SupportedClaims(c Configuration) []string { - return []string{ // TODO: config - "sub", - "aud", - "exp", - "iat", - "iss", - "auth_time", - "nonce", - "acr", - "amr", - "c_hash", - "at_hash", - "act", - "scopes", - "client_id", - "azp", - "preferred_username", - "name", - "family_name", - "given_name", - "locale", - "email", - "email_verified", - "phone_number", - "phone_number_verified", + provider, ok := c.(*Provider) + if ok && provider.config.SupportedClaims != nil { + return provider.config.SupportedClaims } + + return DefaultSupportedClaims } func CodeChallengeMethods(c Configuration) []oidc.CodeChallengeMethod { diff --git a/pkg/op/op.go b/pkg/op/op.go index 939ebf8..fdc073c 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -45,6 +45,33 @@ var ( DeviceAuthorization: NewEndpoint(defaultDeviceAuthzEndpoint), } + DefaultSupportedClaims = []string{ + "sub", + "aud", + "exp", + "iat", + "iss", + "auth_time", + "nonce", + "acr", + "amr", + "c_hash", + "at_hash", + "act", + "scopes", + "client_id", + "azp", + "preferred_username", + "name", + "family_name", + "given_name", + "locale", + "email", + "email_verified", + "phone_number", + "phone_number_verified", + } + defaultCORSOptions = cors.Options{ AllowCredentials: true, AllowedHeaders: []string{ @@ -146,6 +173,7 @@ type Config struct { GrantTypeRefreshToken bool RequestObjectSupported bool SupportedUILocales []language.Tag + SupportedClaims []string DeviceAuthorization DeviceAuthorizationConfig } diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index 062fcfe..f97f666 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -30,6 +30,7 @@ var ( AuthMethodPrivateKeyJWT: true, GrantTypeRefreshToken: true, RequestObjectSupported: true, + SupportedClaims: op.DefaultSupportedClaims, SupportedUILocales: []language.Tag{language.English}, DeviceAuthorization: op.DeviceAuthorizationConfig{ Lifetime: 5 * time.Minute, From b300027cd755317eecef840dd2db2b75c991b008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 18 Dec 2023 09:39:39 +0200 Subject: [PATCH 004/185] feat(op): ID token for device authorization grant (#500) --- pkg/op/device.go | 91 ++++++++++++++++++++++++++++------------ pkg/op/device_test.go | 93 +++++++++++++++++++++++++++++++++++++++++ pkg/op/server_legacy.go | 9 +--- pkg/op/storage.go | 9 ---- pkg/op/token.go | 2 + 5 files changed, 162 insertions(+), 42 deletions(-) diff --git a/pkg/op/device.go b/pkg/op/device.go index 813c3f5..1b86d04 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -14,6 +14,7 @@ import ( httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" + strs "github.com/zitadel/oidc/v3/pkg/strings" ) type DeviceAuthorizationConfig struct { @@ -185,24 +186,6 @@ func NewUserCode(charSet []rune, charAmount, dashInterval int) (string, error) { return buf.String(), nil } -type deviceAccessTokenRequest struct { - subject string - audience []string - scopes []string -} - -func (r *deviceAccessTokenRequest) GetSubject() string { - return r.subject -} - -func (r *deviceAccessTokenRequest) GetAudience() []string { - return r.audience -} - -func (r *deviceAccessTokenRequest) GetScopes() []string { - return r.scopes -} - func DeviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { ctx, span := tracer.Start(r.Context(), "DeviceAccessToken") defer span.End() @@ -229,7 +212,7 @@ func deviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchang if err != nil { return err } - state, err := CheckDeviceAuthorizationState(ctx, clientID, req.DeviceCode, exchanger) + tokenRequest, err := CheckDeviceAuthorizationState(ctx, clientID, req.DeviceCode, exchanger) if err != nil { return err } @@ -243,11 +226,6 @@ func deviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchang WithDescription("confidential client requires authentication") } - tokenRequest := &deviceAccessTokenRequest{ - subject: state.Subject, - audience: []string{clientID}, - scopes: state.Scopes, - } resp, err := CreateDeviceTokenResponse(r.Context(), tokenRequest, exchanger, client) if err != nil { return err @@ -265,6 +243,50 @@ func ParseDeviceAccessTokenRequest(r *http.Request, exchanger Exchanger) (*oidc. return req, nil } +// DeviceAuthorizationState describes the current state of +// the device authorization flow. +// It implements the [IDTokenRequest] interface. +type DeviceAuthorizationState struct { + ClientID string + Audience []string + Scopes []string + Expires time.Time // The time after we consider the authorization request timed-out + Done bool // The user authenticated and approved the authorization request + Denied bool // The user authenticated and denied the authorization request + + // The following fields are populated after Done == true + Subject string + AMR []string + AuthTime time.Time +} + +func (r *DeviceAuthorizationState) GetAMR() []string { + return r.AMR +} + +func (r *DeviceAuthorizationState) GetAudience() []string { + if !strs.Contains(r.Audience, r.ClientID) { + r.Audience = append(r.Audience, r.ClientID) + } + return r.Audience +} + +func (r *DeviceAuthorizationState) GetAuthTime() time.Time { + return r.AuthTime +} + +func (r *DeviceAuthorizationState) GetClientID() string { + return r.ClientID +} + +func (r *DeviceAuthorizationState) GetScopes() []string { + return r.Scopes +} + +func (r *DeviceAuthorizationState) GetSubject() string { + return r.Subject +} + func CheckDeviceAuthorizationState(ctx context.Context, clientID, deviceCode string, exchanger Exchanger) (*DeviceAuthorizationState, error) { storage, err := assertDeviceStorage(exchanger.Storage()) if err != nil { @@ -291,15 +313,32 @@ func CheckDeviceAuthorizationState(ctx context.Context, clientID, deviceCode str } func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator, client Client) (*oidc.AccessTokenResponse, error) { + /* TODO(v4): + Change the TokenRequest argument type to *DeviceAuthorizationState. + Breaking change that can not be done for v3. + */ + ctx, span := tracer.Start(ctx, "CreateDeviceTokenResponse") + defer span.End() + accessToken, refreshToken, validity, err := CreateAccessToken(ctx, tokenRequest, client.AccessTokenType(), creator, client, "") if err != nil { return nil, err } - return &oidc.AccessTokenResponse{ + response := &oidc.AccessTokenResponse{ AccessToken: accessToken, RefreshToken: refreshToken, TokenType: oidc.BearerToken, ExpiresIn: uint64(validity.Seconds()), - }, nil + } + + // TODO(v4): remove type assertion + if idTokenRequest, ok := tokenRequest.(IDTokenRequest); ok && strs.Contains(tokenRequest.GetScopes(), oidc.ScopeOpenID) { + response.IDToken, err = CreateIDToken(ctx, IssuerFromContext(ctx), idTokenRequest, client.IDTokenLifetime(), accessToken, "", creator.Storage(), client) + if err != nil { + return nil, err + } + } + + return response, nil } diff --git a/pkg/op/device_test.go b/pkg/op/device_test.go index f5452f9..570b943 100644 --- a/pkg/op/device_test.go +++ b/pkg/op/device_test.go @@ -453,3 +453,96 @@ func TestCheckDeviceAuthorizationState(t *testing.T) { }) } } + +func TestCreateDeviceTokenResponse(t *testing.T) { + tests := []struct { + name string + tokenRequest op.TokenRequest + wantAccessToken bool + wantRefreshToken bool + wantIDToken bool + wantErr bool + }{ + { + name: "access token", + tokenRequest: &op.DeviceAuthorizationState{ + ClientID: "client1", + Subject: "id1", + AMR: []string{"password"}, + AuthTime: time.Now(), + }, + wantAccessToken: true, + }, + { + name: "access and refresh tokens", + tokenRequest: &op.DeviceAuthorizationState{ + ClientID: "client1", + Subject: "id1", + AMR: []string{"password"}, + AuthTime: time.Now(), + Scopes: []string{oidc.ScopeOfflineAccess}, + }, + wantAccessToken: true, + wantRefreshToken: true, + }, + { + name: "access and id token", + tokenRequest: &op.DeviceAuthorizationState{ + ClientID: "client1", + Subject: "id1", + AMR: []string{"password"}, + AuthTime: time.Now(), + Scopes: []string{oidc.ScopeOpenID}, + }, + wantAccessToken: true, + wantIDToken: true, + }, + { + name: "access, refresh and id token", + tokenRequest: &op.DeviceAuthorizationState{ + ClientID: "client1", + Subject: "id1", + AMR: []string{"password"}, + AuthTime: time.Now(), + Scopes: []string{oidc.ScopeOfflineAccess, oidc.ScopeOpenID}, + }, + wantAccessToken: true, + wantRefreshToken: true, + wantIDToken: true, + }, + { + name: "id token creation error", + tokenRequest: &op.DeviceAuthorizationState{ + ClientID: "client1", + Subject: "foobar", + AMR: []string{"password"}, + AuthTime: time.Now(), + Scopes: []string{oidc.ScopeOfflineAccess, oidc.ScopeOpenID}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client, err := testProvider.Storage().GetClientByClientID(context.Background(), "native") + require.NoError(t, err) + + got, err := op.CreateDeviceTokenResponse(context.Background(), tt.tokenRequest, testProvider, client) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.InDelta(t, 300, got.ExpiresIn, 2) + if tt.wantAccessToken { + assert.NotEmpty(t, got.AccessToken, "access token") + } + if tt.wantRefreshToken { + assert.NotEmpty(t, got.RefreshToken, "refresh token") + } + if tt.wantIDToken { + assert.NotEmpty(t, got.IDToken, "id token") + } + }) + } +} diff --git a/pkg/op/server_legacy.go b/pkg/op/server_legacy.go index a851a2a..114d431 100644 --- a/pkg/op/server_legacy.go +++ b/pkg/op/server_legacy.go @@ -291,7 +291,7 @@ func (s *LegacyServer) ClientCredentialsExchange(ctx context.Context, r *ClientR } func (s *LegacyServer) DeviceToken(ctx context.Context, r *ClientRequest[oidc.DeviceAccessTokenRequest]) (*Response, error) { - if !s.provider.GrantTypeClientCredentialsSupported() { + if !s.provider.GrantTypeDeviceCodeSupported() { return nil, unimplementedGrantError(oidc.GrantTypeDeviceCode) } // use a limited context timeout shorter as the default @@ -299,15 +299,10 @@ func (s *LegacyServer) DeviceToken(ctx context.Context, r *ClientRequest[oidc.De ctx, cancel := context.WithTimeout(ctx, 4*time.Second) defer cancel() - state, err := CheckDeviceAuthorizationState(ctx, r.Client.GetID(), r.Data.DeviceCode, s.provider) + tokenRequest, err := CheckDeviceAuthorizationState(ctx, r.Client.GetID(), r.Data.DeviceCode, s.provider) if err != nil { return nil, err } - tokenRequest := &deviceAccessTokenRequest{ - subject: state.Subject, - audience: []string{r.Client.GetID()}, - scopes: state.Scopes, - } resp, err := CreateDeviceTokenResponse(ctx, tokenRequest, s.provider, r.Client) if err != nil { return nil, err diff --git a/pkg/op/storage.go b/pkg/op/storage.go index d083a31..a1a00ed 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -168,15 +168,6 @@ type EndSessionRequest struct { var ErrDuplicateUserCode = errors.New("user code already exists") -type DeviceAuthorizationState struct { - ClientID string - Scopes []string - Expires time.Time - Done bool - Subject string - Denied bool -} - type DeviceAuthorizationStorage interface { // StoreDeviceAuthorizationRequest stores a new device authorization request in the database. // User code will be used by the user to complete the login flow and must be unique. diff --git a/pkg/op/token.go b/pkg/op/token.go index 63a01a6..83889f0 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -84,6 +84,8 @@ func needsRefreshToken(tokenRequest TokenRequest, client AccessTokenClient) bool return req.GetRequestedTokenType() == oidc.RefreshTokenType case RefreshTokenRequest: return true + case *DeviceAuthorizationState: + return strings.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && ValidateGrantType(client, oidc.GrantTypeRefreshToken) default: return false } From e6d41bdd5d39cacdf444b6d1425e209be36633a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:54:35 +0200 Subject: [PATCH 005/185] chore(deps): bump github/codeql-action from 2 to 3 (#501) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a8106ae..27fa244 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -29,7 +29,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 # Override language selection by uncommenting this and choosing your languages with: languages: go @@ -37,7 +37,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -51,4 +51,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From 2b35eeb83560d69c6b492eb5dcad02ad30c6da55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:15:36 +0200 Subject: [PATCH 006/185] chore(deps): bump golang.org/x/crypto from 0.16.0 to 0.17.0 (#502) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.16.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 62d42a5..57ea200 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect - golang.org/x/crypto v0.16.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/sys v0.15.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 8cff8d2..26e2b66 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= From 6a8e144e8d37feb32ef3a412ad50a3dd08984e9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 18:26:55 +0200 Subject: [PATCH 007/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.0.10 to 5.0.11 (#504) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.10 to 5.0.11. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.0.10...v5.0.11) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 57ea200..29bc0ee 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/zitadel/oidc/v3 go 1.19 require ( - github.com/go-chi/chi/v5 v5.0.10 + github.com/go-chi/chi/v5 v5.0.11 github.com/go-jose/go-jose/v3 v3.0.1 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index 26e2b66..6b643d9 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA= +github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From dce79a73fb3db57e90b60e0ff409ae8bd8fb496e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 22 Dec 2023 11:25:58 +0200 Subject: [PATCH 008/185] fix(oidc): ignore unknown language tag in userinfo unmarshal (#505) * fix(oidc): ignore unknown language tag in userinfo unmarshal Open system reported an issue where a generic OpenID provider might return language tags like "gb". These tags are well-formed but unknown and Go returns an error for it. We already ignored unknown tags is ui_locale arrays lik in AuthRequest. This change ignores singular unknown tags, like used in the userinfo `locale` claim. * do not set nil to Locale field --- pkg/oidc/types.go | 18 ++++++++++++++++- pkg/oidc/types_test.go | 46 +++++++++++++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index d8372b8..0e7152c 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -3,6 +3,7 @@ package oidc import ( "database/sql/driver" "encoding/json" + "errors" "fmt" "reflect" "strings" @@ -76,8 +77,23 @@ func (l *Locale) MarshalJSON() ([]byte, error) { return json.Marshal(tag) } +// UnmarshalJSON implements json.Unmarshaler. +// When [language.ValueError] is encountered, the containing tag will be set +// to an empty value (language "und") and no error will be returned. +// This state can be checked with the `l.Tag().IsRoot()` method. func (l *Locale) UnmarshalJSON(data []byte) error { - return json.Unmarshal(data, &l.tag) + err := json.Unmarshal(data, &l.tag) + if err == nil { + return nil + } + + // catch "well-formed but unknown" errors + var target language.ValueError + if errors.As(err, &target) { + l.tag = language.Tag{} + return nil + } + return err } type Locales []language.Tag diff --git a/pkg/oidc/types_test.go b/pkg/oidc/types_test.go index af4f113..df93a73 100644 --- a/pkg/oidc/types_test.go +++ b/pkg/oidc/types_test.go @@ -208,20 +208,46 @@ func TestLocale_MarshalJSON(t *testing.T) { } func TestLocale_UnmarshalJSON(t *testing.T) { - type a struct { + type dst struct { Locale *Locale `json:"locale,omitempty"` } - want := a{ - Locale: NewLocale(language.Afrikaans), + tests := []struct { + name string + input string + want dst + wantErr bool + }{ + { + name: "afrikaans, ok", + input: `{"locale": "af"}`, + want: dst{ + Locale: NewLocale(language.Afrikaans), + }, + }, + { + name: "gb, ignored", + input: `{"locale": "gb"}`, + want: dst{ + Locale: &Locale{}, + }, + }, + { + name: "bad form, error", + input: `{"locale": "g!!!!!"}`, + wantErr: true, + }, } - const input = `{"locale": "af"}` - var got a - - require.NoError(t, - json.Unmarshal([]byte(input), &got), - ) - assert.Equal(t, want, got) + for _, tt := range tests { + var got dst + err := json.Unmarshal([]byte(tt.input), &got) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tt.want, got) + } } func TestParseLocales(t *testing.T) { From c37ca25220936dec4c7e67cfa9be7bf2f9b3b961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 5 Jan 2024 17:30:17 +0200 Subject: [PATCH 009/185] feat(op): allow double star globs (#507) Related to https://github.com/zitadel/zitadel/issues/5110 --- go.mod | 1 + go.sum | 2 + pkg/op/auth_request.go | 4 +- pkg/op/auth_request_test.go | 54 +++++++ pkg/op/client.go | 1 + pkg/op/mock/generate.go | 1 + pkg/op/mock/glob.go | 24 +++ pkg/op/mock/glob.mock.go | 289 ++++++++++++++++++++++++++++++++++++ 8 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 pkg/op/mock/glob.go create mode 100644 pkg/op/mock/glob.mock.go diff --git a/go.mod b/go.mod index 29bc0ee..4934640 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/zitadel/oidc/v3 go 1.19 require ( + github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.0.11 github.com/go-jose/go-jose/v3 v3.0.1 github.com/golang/mock v1.6.0 diff --git a/go.sum b/go.sum index 6b643d9..6c0eace 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 7ef06a8..02c820e 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -7,10 +7,10 @@ import ( "net" "net/http" "net/url" - "path" "strings" "time" + "github.com/bmatcuk/doublestar/v4" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" str "github.com/zitadel/oidc/v3/pkg/strings" @@ -283,7 +283,7 @@ func checkURIAgainstRedirects(client Client, uri string) error { } if globClient, ok := client.(HasRedirectGlobs); ok { for _, uriGlob := range globClient.RedirectURIGlobs() { - isMatch, err := path.Match(uriGlob, uri) + isMatch, err := doublestar.Match(uriGlob, uri) if err != nil { return oidc.ErrServerError().WithParent(err) } diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index db70fd7..18880f0 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -583,6 +583,60 @@ func TestValidateAuthReqRedirectURI(t *testing.T) { }, false, }, + { + "code flow dev mode has redirect globs regular ok", + args{ + "http://registered.com/callback", + mock.NewHasRedirectGlobsWithConfig(t, []string{"http://registered.com/*"}, op.ApplicationTypeUserAgent, nil, true), + oidc.ResponseTypeCode, + }, + false, + }, + { + "code flow dev mode has redirect globs wildcard ok", + args{ + "http://registered.com/callback", + mock.NewHasRedirectGlobsWithConfig(t, []string{"http://registered.com/*"}, op.ApplicationTypeUserAgent, nil, true), + oidc.ResponseTypeCode, + }, + false, + }, + { + "code flow dev mode has redirect globs double star ok", + args{ + "http://registered.com/callback", + mock.NewHasRedirectGlobsWithConfig(t, []string{"http://**/*"}, op.ApplicationTypeUserAgent, nil, true), + oidc.ResponseTypeCode, + }, + false, + }, + { + "code flow dev mode has redirect globs double star ok", + args{ + "http://registered.com/callback", + mock.NewHasRedirectGlobsWithConfig(t, []string{"http://**/*"}, op.ApplicationTypeUserAgent, nil, true), + oidc.ResponseTypeCode, + }, + false, + }, + { + "code flow dev mode has redirect globs IPv6 ok", + args{ + "http://[::1]:80/callback", + mock.NewHasRedirectGlobsWithConfig(t, []string{"http://\\[::1\\]:80/*"}, op.ApplicationTypeUserAgent, nil, true), + oidc.ResponseTypeCode, + }, + false, + }, + { + "code flow dev mode has redirect globs bad pattern", + args{ + "http://registered.com/callback", + mock.NewHasRedirectGlobsWithConfig(t, []string{"http://**/\\"}, op.ApplicationTypeUserAgent, nil, true), + oidc.ResponseTypeCode, + }, + true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/op/client.go b/pkg/op/client.go index 04ef3c7..0574afa 100644 --- a/pkg/op/client.go +++ b/pkg/op/client.go @@ -63,6 +63,7 @@ type Client interface { // such as DevMode for the client being enabled. // https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest type HasRedirectGlobs interface { + Client RedirectURIGlobs() []string PostLogoutRedirectURIGlobs() []string } diff --git a/pkg/op/mock/generate.go b/pkg/op/mock/generate.go index 590356c..e5cab3e 100644 --- a/pkg/op/mock/generate.go +++ b/pkg/op/mock/generate.go @@ -4,6 +4,7 @@ package mock //go:generate mockgen -package mock -destination ./storage.mock.go github.com/zitadel/oidc/v3/pkg/op Storage //go:generate mockgen -package mock -destination ./authorizer.mock.go github.com/zitadel/oidc/v3/pkg/op Authorizer //go:generate mockgen -package mock -destination ./client.mock.go github.com/zitadel/oidc/v3/pkg/op Client +//go:generate mockgen -package mock -destination ./glob.mock.go github.com/zitadel/oidc/v3/pkg/op HasRedirectGlobs //go:generate mockgen -package mock -destination ./configuration.mock.go github.com/zitadel/oidc/v3/pkg/op Configuration //go:generate mockgen -package mock -destination ./discovery.mock.go github.com/zitadel/oidc/v3/pkg/op DiscoverStorage //go:generate mockgen -package mock -destination ./signer.mock.go github.com/zitadel/oidc/v3/pkg/op SigningKey,Key diff --git a/pkg/op/mock/glob.go b/pkg/op/mock/glob.go new file mode 100644 index 0000000..cade476 --- /dev/null +++ b/pkg/op/mock/glob.go @@ -0,0 +1,24 @@ +package mock + +import ( + "testing" + + gomock "github.com/golang/mock/gomock" + "github.com/zitadel/oidc/v3/pkg/oidc" + op "github.com/zitadel/oidc/v3/pkg/op" +) + +func NewHasRedirectGlobs(t *testing.T) op.HasRedirectGlobs { + return NewMockHasRedirectGlobs(gomock.NewController(t)) +} + +func NewHasRedirectGlobsWithConfig(t *testing.T, uri []string, appType op.ApplicationType, responseTypes []oidc.ResponseType, devMode bool) op.HasRedirectGlobs { + c := NewHasRedirectGlobs(t) + m := c.(*MockHasRedirectGlobs) + m.EXPECT().RedirectURIs().AnyTimes().Return(uri) + m.EXPECT().RedirectURIGlobs().AnyTimes().Return(uri) + m.EXPECT().ApplicationType().AnyTimes().Return(appType) + m.EXPECT().ResponseTypes().AnyTimes().Return(responseTypes) + m.EXPECT().DevMode().AnyTimes().Return(devMode) + return c +} diff --git a/pkg/op/mock/glob.mock.go b/pkg/op/mock/glob.mock.go new file mode 100644 index 0000000..cf9996e --- /dev/null +++ b/pkg/op/mock/glob.mock.go @@ -0,0 +1,289 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: HasRedirectGlobs) + +// Package mock is a generated GoMock package. +package mock + +import ( + reflect "reflect" + time "time" + + gomock "github.com/golang/mock/gomock" + oidc "github.com/zitadel/oidc/v3/pkg/oidc" + op "github.com/zitadel/oidc/v3/pkg/op" +) + +// MockHasRedirectGlobs is a mock of HasRedirectGlobs interface. +type MockHasRedirectGlobs struct { + ctrl *gomock.Controller + recorder *MockHasRedirectGlobsMockRecorder +} + +// MockHasRedirectGlobsMockRecorder is the mock recorder for MockHasRedirectGlobs. +type MockHasRedirectGlobsMockRecorder struct { + mock *MockHasRedirectGlobs +} + +// NewMockHasRedirectGlobs creates a new mock instance. +func NewMockHasRedirectGlobs(ctrl *gomock.Controller) *MockHasRedirectGlobs { + mock := &MockHasRedirectGlobs{ctrl: ctrl} + mock.recorder = &MockHasRedirectGlobsMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHasRedirectGlobs) EXPECT() *MockHasRedirectGlobsMockRecorder { + return m.recorder +} + +// AccessTokenType mocks base method. +func (m *MockHasRedirectGlobs) AccessTokenType() op.AccessTokenType { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AccessTokenType") + ret0, _ := ret[0].(op.AccessTokenType) + return ret0 +} + +// AccessTokenType indicates an expected call of AccessTokenType. +func (mr *MockHasRedirectGlobsMockRecorder) AccessTokenType() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccessTokenType", reflect.TypeOf((*MockHasRedirectGlobs)(nil).AccessTokenType)) +} + +// ApplicationType mocks base method. +func (m *MockHasRedirectGlobs) ApplicationType() op.ApplicationType { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ApplicationType") + ret0, _ := ret[0].(op.ApplicationType) + return ret0 +} + +// ApplicationType indicates an expected call of ApplicationType. +func (mr *MockHasRedirectGlobsMockRecorder) ApplicationType() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplicationType", reflect.TypeOf((*MockHasRedirectGlobs)(nil).ApplicationType)) +} + +// AuthMethod mocks base method. +func (m *MockHasRedirectGlobs) AuthMethod() oidc.AuthMethod { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AuthMethod") + ret0, _ := ret[0].(oidc.AuthMethod) + return ret0 +} + +// AuthMethod indicates an expected call of AuthMethod. +func (mr *MockHasRedirectGlobsMockRecorder) AuthMethod() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthMethod", reflect.TypeOf((*MockHasRedirectGlobs)(nil).AuthMethod)) +} + +// ClockSkew mocks base method. +func (m *MockHasRedirectGlobs) ClockSkew() time.Duration { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClockSkew") + ret0, _ := ret[0].(time.Duration) + return ret0 +} + +// ClockSkew indicates an expected call of ClockSkew. +func (mr *MockHasRedirectGlobsMockRecorder) ClockSkew() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClockSkew", reflect.TypeOf((*MockHasRedirectGlobs)(nil).ClockSkew)) +} + +// DevMode mocks base method. +func (m *MockHasRedirectGlobs) DevMode() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DevMode") + ret0, _ := ret[0].(bool) + return ret0 +} + +// DevMode indicates an expected call of DevMode. +func (mr *MockHasRedirectGlobsMockRecorder) DevMode() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevMode", reflect.TypeOf((*MockHasRedirectGlobs)(nil).DevMode)) +} + +// GetID mocks base method. +func (m *MockHasRedirectGlobs) GetID() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetID") + ret0, _ := ret[0].(string) + return ret0 +} + +// GetID indicates an expected call of GetID. +func (mr *MockHasRedirectGlobsMockRecorder) GetID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetID", reflect.TypeOf((*MockHasRedirectGlobs)(nil).GetID)) +} + +// GrantTypes mocks base method. +func (m *MockHasRedirectGlobs) GrantTypes() []oidc.GrantType { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GrantTypes") + ret0, _ := ret[0].([]oidc.GrantType) + return ret0 +} + +// GrantTypes indicates an expected call of GrantTypes. +func (mr *MockHasRedirectGlobsMockRecorder) GrantTypes() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GrantTypes", reflect.TypeOf((*MockHasRedirectGlobs)(nil).GrantTypes)) +} + +// IDTokenLifetime mocks base method. +func (m *MockHasRedirectGlobs) IDTokenLifetime() time.Duration { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IDTokenLifetime") + ret0, _ := ret[0].(time.Duration) + return ret0 +} + +// IDTokenLifetime indicates an expected call of IDTokenLifetime. +func (mr *MockHasRedirectGlobsMockRecorder) IDTokenLifetime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDTokenLifetime", reflect.TypeOf((*MockHasRedirectGlobs)(nil).IDTokenLifetime)) +} + +// IDTokenUserinfoClaimsAssertion mocks base method. +func (m *MockHasRedirectGlobs) IDTokenUserinfoClaimsAssertion() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IDTokenUserinfoClaimsAssertion") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IDTokenUserinfoClaimsAssertion indicates an expected call of IDTokenUserinfoClaimsAssertion. +func (mr *MockHasRedirectGlobsMockRecorder) IDTokenUserinfoClaimsAssertion() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDTokenUserinfoClaimsAssertion", reflect.TypeOf((*MockHasRedirectGlobs)(nil).IDTokenUserinfoClaimsAssertion)) +} + +// IsScopeAllowed mocks base method. +func (m *MockHasRedirectGlobs) IsScopeAllowed(arg0 string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsScopeAllowed", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsScopeAllowed indicates an expected call of IsScopeAllowed. +func (mr *MockHasRedirectGlobsMockRecorder) IsScopeAllowed(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsScopeAllowed", reflect.TypeOf((*MockHasRedirectGlobs)(nil).IsScopeAllowed), arg0) +} + +// LoginURL mocks base method. +func (m *MockHasRedirectGlobs) LoginURL(arg0 string) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LoginURL", arg0) + ret0, _ := ret[0].(string) + return ret0 +} + +// LoginURL indicates an expected call of LoginURL. +func (mr *MockHasRedirectGlobsMockRecorder) LoginURL(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoginURL", reflect.TypeOf((*MockHasRedirectGlobs)(nil).LoginURL), arg0) +} + +// PostLogoutRedirectURIGlobs mocks base method. +func (m *MockHasRedirectGlobs) PostLogoutRedirectURIGlobs() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PostLogoutRedirectURIGlobs") + ret0, _ := ret[0].([]string) + return ret0 +} + +// PostLogoutRedirectURIGlobs indicates an expected call of PostLogoutRedirectURIGlobs. +func (mr *MockHasRedirectGlobsMockRecorder) PostLogoutRedirectURIGlobs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostLogoutRedirectURIGlobs", reflect.TypeOf((*MockHasRedirectGlobs)(nil).PostLogoutRedirectURIGlobs)) +} + +// PostLogoutRedirectURIs mocks base method. +func (m *MockHasRedirectGlobs) PostLogoutRedirectURIs() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PostLogoutRedirectURIs") + ret0, _ := ret[0].([]string) + return ret0 +} + +// PostLogoutRedirectURIs indicates an expected call of PostLogoutRedirectURIs. +func (mr *MockHasRedirectGlobsMockRecorder) PostLogoutRedirectURIs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostLogoutRedirectURIs", reflect.TypeOf((*MockHasRedirectGlobs)(nil).PostLogoutRedirectURIs)) +} + +// RedirectURIGlobs mocks base method. +func (m *MockHasRedirectGlobs) RedirectURIGlobs() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RedirectURIGlobs") + ret0, _ := ret[0].([]string) + return ret0 +} + +// RedirectURIGlobs indicates an expected call of RedirectURIGlobs. +func (mr *MockHasRedirectGlobsMockRecorder) RedirectURIGlobs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RedirectURIGlobs", reflect.TypeOf((*MockHasRedirectGlobs)(nil).RedirectURIGlobs)) +} + +// RedirectURIs mocks base method. +func (m *MockHasRedirectGlobs) RedirectURIs() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RedirectURIs") + ret0, _ := ret[0].([]string) + return ret0 +} + +// RedirectURIs indicates an expected call of RedirectURIs. +func (mr *MockHasRedirectGlobsMockRecorder) RedirectURIs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RedirectURIs", reflect.TypeOf((*MockHasRedirectGlobs)(nil).RedirectURIs)) +} + +// ResponseTypes mocks base method. +func (m *MockHasRedirectGlobs) ResponseTypes() []oidc.ResponseType { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResponseTypes") + ret0, _ := ret[0].([]oidc.ResponseType) + return ret0 +} + +// ResponseTypes indicates an expected call of ResponseTypes. +func (mr *MockHasRedirectGlobsMockRecorder) ResponseTypes() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResponseTypes", reflect.TypeOf((*MockHasRedirectGlobs)(nil).ResponseTypes)) +} + +// RestrictAdditionalAccessTokenScopes mocks base method. +func (m *MockHasRedirectGlobs) RestrictAdditionalAccessTokenScopes() func([]string) []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RestrictAdditionalAccessTokenScopes") + ret0, _ := ret[0].(func([]string) []string) + return ret0 +} + +// RestrictAdditionalAccessTokenScopes indicates an expected call of RestrictAdditionalAccessTokenScopes. +func (mr *MockHasRedirectGlobsMockRecorder) RestrictAdditionalAccessTokenScopes() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestrictAdditionalAccessTokenScopes", reflect.TypeOf((*MockHasRedirectGlobs)(nil).RestrictAdditionalAccessTokenScopes)) +} + +// RestrictAdditionalIdTokenScopes mocks base method. +func (m *MockHasRedirectGlobs) RestrictAdditionalIdTokenScopes() func([]string) []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RestrictAdditionalIdTokenScopes") + ret0, _ := ret[0].(func([]string) []string) + return ret0 +} + +// RestrictAdditionalIdTokenScopes indicates an expected call of RestrictAdditionalIdTokenScopes. +func (mr *MockHasRedirectGlobsMockRecorder) RestrictAdditionalIdTokenScopes() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestrictAdditionalIdTokenScopes", reflect.TypeOf((*MockHasRedirectGlobs)(nil).RestrictAdditionalIdTokenScopes)) +} From e23b1d475435b695c3e33baac204d5a47ecf55f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 8 Jan 2024 09:01:34 +0100 Subject: [PATCH 010/185] fix: Implement dedicated error for RevokeToken (#508) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan-Otto Kröpke --- pkg/client/rp/errors.go | 5 +++++ pkg/client/rp/relying_party.go | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 pkg/client/rp/errors.go diff --git a/pkg/client/rp/errors.go b/pkg/client/rp/errors.go new file mode 100644 index 0000000..b95420b --- /dev/null +++ b/pkg/client/rp/errors.go @@ -0,0 +1,5 @@ +package rp + +import "errors" + +var ErrRelyingPartyNotSupportRevokeCaller = errors.New("RelyingParty does not support RevokeCaller") diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 5899af0..e31b025 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -4,12 +4,11 @@ import ( "context" "encoding/base64" "errors" - "fmt" "net/http" "net/url" "time" - jose "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v3" "github.com/google/uuid" "github.com/zitadel/logging" "golang.org/x/exp/slog" @@ -726,5 +725,5 @@ func RevokeToken(ctx context.Context, rp RelyingParty, token string, tokenTypeHi if rc, ok := rp.(client.RevokeCaller); ok && rc.GetRevokeEndpoint() != "" { return client.CallRevokeEndpoint(ctx, request, nil, rc) } - return fmt.Errorf("RelyingParty does not support RevokeCaller") + return ErrRelyingPartyNotSupportRevokeCaller } From 8923b821427f0a7537778791c79568a119b82fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 8 Jan 2024 11:18:33 +0200 Subject: [PATCH 011/185] chore(deps): enable dependabot for the v2 branch (#512) --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 79ff704..1efdcf8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,16 @@ updates: commit-message: prefix: chore include: scope +- package-ecosystem: gomod + target-branch: "2.12.x" + directory: "/" + schedule: + interval: daily + time: '04:00' + open-pull-requests-limit: 10 + commit-message: + prefix: chore + include: scope - package-ecosystem: "github-actions" directory: "/" schedule: From 4d85375702dca1a96d6b835d39424f8a3112525e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 8 Jan 2024 11:21:28 +0200 Subject: [PATCH 012/185] chore(example): add device package level documentation (#510) --- example/client/device/device.go | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/example/client/device/device.go b/example/client/device/device.go index bea6134..78ed2c8 100644 --- a/example/client/device/device.go +++ b/example/client/device/device.go @@ -1,3 +1,37 @@ +// Command device is an example Oauth2 Device Authorization Grant app. +// It creates a new Device Authorization request on the Issuer and then polls for tokens. +// The user is then prompted to visit a URL and enter the user code. +// Or, the complete URL can be used instead to omit manual entry. +// In practice then can be a "magic link" in the form or a QR. +// +// The following environment variables are used for configuration: +// +// ISSUER: URL to the OP, required. +// CLIENT_ID: ID of the application, required. +// CLIENT_SECRET: Secret to authenticate the app using basic auth. Only required if the OP expects this type of authentication. +// KEY_PATH: Path to a private key file, used to for JWT authentication of the App. Only required if the OP expects this type of authentication. +// SCOPES: Scopes of the Authentication Request. Optional. +// +// Basic usage: +// +// cd example/client/device +// export ISSUER="http://localhost:9000" CLIENT_ID="246048465824634593@demo" +// +// Get an Access Token: +// +// SCOPES="email profile" go run . +// +// Get an Access Token and ID Token: +// +// SCOPES="email profile openid" go run . +// +// Get an Access Token and Refresh Token +// +// SCOPES="email profile offline_access" go run . +// +// Get Access, Refresh and ID Tokens: +// +// SCOPES="email profile offline_access openid" go run . package main import ( @@ -57,5 +91,5 @@ func main() { if err != nil { logrus.Fatal(err) } - logrus.Infof("successfully obtained token: %v", token) + logrus.Infof("successfully obtained token: %#v", token) } From 5dcf6de055a5da59d8a688d57e8384428640194d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:17:04 +0200 Subject: [PATCH 013/185] chore(deps): bump golang.org/x/oauth2 from 0.15.0 to 0.16.0 (#513) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.15.0 to 0.16.0. - [Commits](https://github.com/golang/oauth2/compare/v0.15.0...v0.16.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 4934640..737fa45 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel/trace v1.21.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 - golang.org/x/oauth2 v0.15.0 + golang.org/x/oauth2 v0.16.0 golang.org/x/text v0.14.0 ) @@ -33,9 +33,9 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.16.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 6c0eace..20e9734 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -77,11 +77,11 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -90,8 +90,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= From 984e31a9e22e8b43a7ac6bfaeab29db56b28f69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Tue, 9 Jan 2024 16:24:05 +0100 Subject: [PATCH 014/185] feat(rp): Add UnauthorizedHandler (#503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * RP: Add UnauthorizedHandler Signed-off-by: Jan-Otto Kröpke * remove race condition Signed-off-by: Jan-Otto Kröpke * Use optional interface Signed-off-by: Jan-Otto Kröpke --------- Signed-off-by: Jan-Otto Kröpke --- pkg/client/rp/relying_party.go | 62 +++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index e31b025..04be4ef 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -66,19 +66,28 @@ type RelyingParty interface { // IDTokenVerifier returns the verifier used for oidc id_token verification IDTokenVerifier() *IDTokenVerifier - // ErrorHandler returns the handler used for callback errors + // ErrorHandler returns the handler used for callback errors ErrorHandler() func(http.ResponseWriter, *http.Request, string, string, string) // Logger from the context, or a fallback if set. Logger(context.Context) (logger *slog.Logger, ok bool) } +type HasUnauthorizedHandler interface { + // UnauthorizedHandler returns the handler used for unauthorized errors + UnauthorizedHandler() func(w http.ResponseWriter, r *http.Request, desc string, state string) +} + type ErrorHandler func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) +type UnauthorizedHandler func(w http.ResponseWriter, r *http.Request, desc string, state string) var DefaultErrorHandler ErrorHandler = func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) { http.Error(w, errorType+": "+errorDesc, http.StatusInternalServerError) } +var DefaultUnauthorizedHandler UnauthorizedHandler = func(w http.ResponseWriter, r *http.Request, desc string, state string) { + http.Error(w, desc, http.StatusUnauthorized) +} type relyingParty struct { issuer string @@ -91,11 +100,12 @@ type relyingParty struct { httpClient *http.Client cookieHandler *httphelper.CookieHandler - errorHandler func(http.ResponseWriter, *http.Request, string, string, string) - idTokenVerifier *IDTokenVerifier - verifierOpts []VerifierOption - signer jose.Signer - logger *slog.Logger + errorHandler func(http.ResponseWriter, *http.Request, string, string, string) + unauthorizedHandler func(http.ResponseWriter, *http.Request, string, string) + idTokenVerifier *IDTokenVerifier + verifierOpts []VerifierOption + signer jose.Signer + logger *slog.Logger } func (rp *relyingParty) OAuthConfig() *oauth2.Config { @@ -156,6 +166,10 @@ func (rp *relyingParty) ErrorHandler() func(http.ResponseWriter, *http.Request, return rp.errorHandler } +func (rp *relyingParty) UnauthorizedHandler() func(http.ResponseWriter, *http.Request, string, string) { + return rp.unauthorizedHandler +} + func (rp *relyingParty) Logger(ctx context.Context) (logger *slog.Logger, ok bool) { logger, ok = logging.FromContext(ctx) if ok { @@ -169,9 +183,10 @@ func (rp *relyingParty) Logger(ctx context.Context) (logger *slog.Logger, ok boo // it will use the AuthURL and TokenURL set in config func NewRelyingPartyOAuth(config *oauth2.Config, options ...Option) (RelyingParty, error) { rp := &relyingParty{ - oauthConfig: config, - httpClient: httphelper.DefaultHTTPClient, - oauth2Only: true, + oauthConfig: config, + httpClient: httphelper.DefaultHTTPClient, + oauth2Only: true, + unauthorizedHandler: DefaultUnauthorizedHandler, } for _, optFunc := range options { @@ -268,6 +283,13 @@ func WithErrorHandler(errorHandler ErrorHandler) Option { } } +func WithUnauthorizedHandler(unauthorizedHandler UnauthorizedHandler) Option { + return func(rp *relyingParty) error { + rp.unauthorizedHandler = unauthorizedHandler + return nil + } +} + func WithVerifierOpts(opts ...VerifierOption) Option { return func(rp *relyingParty) error { rp.verifierOpts = opts @@ -355,13 +377,13 @@ func AuthURLHandler(stateFn func() string, rp RelyingParty, urlParam ...URLParam state := stateFn() if err := trySetStateCookie(w, state, rp); err != nil { - http.Error(w, "failed to create state cookie: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "failed to create state cookie: "+err.Error(), state, rp) return } if rp.IsPKCE() { codeChallenge, err := GenerateAndStoreCodeChallenge(w, rp) if err != nil { - http.Error(w, "failed to create code challenge: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "failed to create code challenge: "+err.Error(), state, rp) return } opts = append(opts, WithCodeChallenge(codeChallenge)) @@ -448,7 +470,7 @@ func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp R return func(w http.ResponseWriter, r *http.Request) { state, err := tryReadStateCookie(w, r, rp) if err != nil { - http.Error(w, "failed to get state: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "failed to get state: "+err.Error(), state, rp) return } params := r.URL.Query() @@ -464,7 +486,7 @@ func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp R if rp.IsPKCE() { codeVerifier, err := rp.CookieHandler().CheckCookie(r, pkceCode) if err != nil { - http.Error(w, "failed to get code verifier: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "failed to get code verifier: "+err.Error(), state, rp) return } codeOpts = append(codeOpts, WithCodeVerifier(codeVerifier)) @@ -473,14 +495,14 @@ func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp R if rp.Signer() != nil { assertion, err := client.SignedJWTProfileAssertion(rp.OAuthConfig().ClientID, []string{rp.Issuer()}, time.Hour, rp.Signer()) if err != nil { - http.Error(w, "failed to build assertion: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "failed to build assertion: "+err.Error(), state, rp) return } codeOpts = append(codeOpts, WithClientAssertionJWT(assertion)) } tokens, err := CodeExchange[C](r.Context(), params.Get("code"), rp, codeOpts...) if err != nil { - http.Error(w, "failed to exchange token: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "failed to exchange token: "+err.Error(), state, rp) return } callback(w, r, tokens, state, rp) @@ -500,7 +522,7 @@ func UserinfoCallback[C oidc.IDClaims, U SubjectGetter](f CodeExchangeUserinfoCa return func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[C], state string, rp RelyingParty) { info, err := Userinfo[U](r.Context(), tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.GetSubject(), rp) if err != nil { - http.Error(w, "userinfo failed: "+err.Error(), http.StatusUnauthorized) + unauthorizedError(w, r, "userinfo failed: "+err.Error(), state, rp) return } f(w, r, tokens, state, rp, info) @@ -727,3 +749,11 @@ func RevokeToken(ctx context.Context, rp RelyingParty, token string, tokenTypeHi } return ErrRelyingPartyNotSupportRevokeCaller } + +func unauthorizedError(w http.ResponseWriter, r *http.Request, desc string, state string, rp RelyingParty) { + if rp, ok := rp.(HasUnauthorizedHandler); ok { + rp.UnauthorizedHandler()(w, r, desc, state) + return + } + http.Error(w, desc, http.StatusUnauthorized) +} From 844e2337bb96a513c559494decafe5d7901d5d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 16 Jan 2024 08:18:41 +0200 Subject: [PATCH 015/185] fix(op): check redirect URI in code exchange (#516) This changes fixes a missing redirect check in the Legacy Server's Code Exchange handler. --- pkg/op/server_legacy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/op/server_legacy.go b/pkg/op/server_legacy.go index 114d431..089be6f 100644 --- a/pkg/op/server_legacy.go +++ b/pkg/op/server_legacy.go @@ -210,6 +210,9 @@ func (s *LegacyServer) CodeExchange(ctx context.Context, r *ClientRequest[oidc.A return nil, err } } + if r.Data.RedirectURI != authReq.GetRedirectURI() { + return nil, oidc.ErrInvalidGrant().WithDescription("redirect_uri does not correspond") + } resp, err := CreateTokenResponse(ctx, authReq, r.Client, s.provider, true, r.Data.Code, "") if err != nil { return nil, err From 57d04e74651766c47097c8253bf08417a366d553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 17 Jan 2024 17:06:45 +0200 Subject: [PATCH 016/185] fix: don't force server errors in legacy server (#517) * fix: don't force server errors in legacy server * fix tests and be more consistent with the returned status code --- pkg/op/auth_request.go | 10 +++++----- pkg/op/error.go | 32 ++++++++++++++++++++++++-------- pkg/op/error_test.go | 6 +++++- pkg/op/server_http_test.go | 6 +++--- pkg/op/server_legacy.go | 10 +++++----- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 02c820e..ed368eb 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -138,20 +138,20 @@ func ParseRequestObject(ctx context.Context, authReq *oidc.AuthRequest, storage } if requestObject.ClientID != "" && requestObject.ClientID != authReq.ClientID { - return oidc.ErrInvalidRequest() + return oidc.ErrInvalidRequest().WithDescription("missing or wrong client id in request") } if requestObject.ResponseType != "" && requestObject.ResponseType != authReq.ResponseType { - return oidc.ErrInvalidRequest() + return oidc.ErrInvalidRequest().WithDescription("missing or wrong response type in request") } if requestObject.Issuer != requestObject.ClientID { - return oidc.ErrInvalidRequest() + return oidc.ErrInvalidRequest().WithDescription("missing or wrong issuer in request") } if !str.Contains(requestObject.Audience, issuer) { - return oidc.ErrInvalidRequest() + return oidc.ErrInvalidRequest().WithDescription("issuer missing in audience") } keySet := &jwtProfileKeySet{storage: storage, clientID: requestObject.Issuer} if err = oidc.CheckSignature(ctx, authReq.RequestParam, payload, requestObject, nil, keySet); err != nil { - return err + return oidc.ErrInvalidRequest().WithParent(err).WithDescription(err.Error()) } CopyRequestObjectToAuthRequest(authReq, requestObject) return nil diff --git a/pkg/op/error.go b/pkg/op/error.go index 0cac14b..e4580f6 100644 --- a/pkg/op/error.go +++ b/pkg/op/error.go @@ -157,13 +157,29 @@ func (e StatusError) Is(err error) bool { e.statusCode == target.statusCode } -// WriteError asserts for a StatusError containing an [oidc.Error]. -// If no StatusError is found, the status code will default to [http.StatusBadRequest]. -// If no [oidc.Error] was found in the parent, the error type defaults to [oidc.ServerError]. +// WriteError asserts for a [StatusError] containing an [oidc.Error]. +// If no `StatusError` is found, the status code will default to [http.StatusBadRequest]. +// If no `oidc.Error` was found in the parent, the error type defaults to [oidc.ServerError]. +// When there was no `StatusError` and the `oidc.Error` is of type `oidc.ServerError`, +// the status code will be set to [http.StatusInternalServerError] func WriteError(w http.ResponseWriter, r *http.Request, err error, logger *slog.Logger) { - statusError := AsStatusError(err, http.StatusBadRequest) - e := oidc.DefaultToServerError(statusError.parent, statusError.parent.Error()) - - logger.Log(r.Context(), e.LogLevel(), "request error", "oidc_error", e) - httphelper.MarshalJSONWithStatus(w, e, statusError.statusCode) + var statusError StatusError + if errors.As(err, &statusError) { + writeError(w, r, + oidc.DefaultToServerError(statusError.parent, statusError.parent.Error()), + statusError.statusCode, logger, + ) + return + } + statusCode := http.StatusBadRequest + e := oidc.DefaultToServerError(err, err.Error()) + if e.ErrorType == oidc.ServerError { + statusCode = http.StatusInternalServerError + } + writeError(w, r, e, statusCode, logger) +} + +func writeError(w http.ResponseWriter, r *http.Request, err *oidc.Error, statusCode int, logger *slog.Logger) { + logger.Log(r.Context(), err.LogLevel(), "request error", "oidc_error", err, "status_code", statusCode) + httphelper.MarshalJSONWithStatus(w, err, statusCode) } diff --git a/pkg/op/error_test.go b/pkg/op/error_test.go index 689ee5a..50a9cbf 100644 --- a/pkg/op/error_test.go +++ b/pkg/op/error_test.go @@ -579,7 +579,7 @@ func TestWriteError(t *testing.T) { { name: "not a status or oidc error", err: io.ErrClosedPipe, - wantStatus: http.StatusBadRequest, + wantStatus: http.StatusInternalServerError, wantBody: `{ "error":"server_error", "error_description":"io: read/write on closed pipe" @@ -592,6 +592,7 @@ func TestWriteError(t *testing.T) { "parent":"io: read/write on closed pipe", "type":"server_error" }, + "status_code":500, "time":"not" }`, }, @@ -611,6 +612,7 @@ func TestWriteError(t *testing.T) { "parent":"io: read/write on closed pipe", "type":"server_error" }, + "status_code":500, "time":"not" }`, }, @@ -629,6 +631,7 @@ func TestWriteError(t *testing.T) { "description":"oops", "type":"invalid_request" }, + "status_code":400, "time":"not" }`, }, @@ -650,6 +653,7 @@ func TestWriteError(t *testing.T) { "description":"oops", "type":"unauthorized_client" }, + "status_code":401, "time":"not" }`, }, diff --git a/pkg/op/server_http_test.go b/pkg/op/server_http_test.go index 4eac4a0..6cb268f 100644 --- a/pkg/op/server_http_test.go +++ b/pkg/op/server_http_test.go @@ -365,14 +365,14 @@ func Test_webServer_authorizeHandler(t *testing.T) { }, }, { - name: "authorize error", + name: "server error", fields: fields{ server: &requestVerifier{}, decoder: testDecoder, }, r: httptest.NewRequest(http.MethodPost, "/authorize", strings.NewReader("foo=bar")), want: webServerResult{ - wantStatus: http.StatusBadRequest, + wantStatus: http.StatusInternalServerError, wantBody: `{"error":"server_error"}`, }, }, @@ -1237,7 +1237,7 @@ func Test_webServer_simpleHandler(t *testing.T) { }, r: httptest.NewRequest(http.MethodGet, "/", bytes.NewReader(make([]byte, 11<<20))), want: webServerResult{ - wantStatus: http.StatusBadRequest, + wantStatus: http.StatusInternalServerError, wantBody: `{"error":"server_error", "error_description":"io: read/write on closed pipe"}`, }, }, diff --git a/pkg/op/server_legacy.go b/pkg/op/server_legacy.go index 089be6f..f99d15d 100644 --- a/pkg/op/server_legacy.go +++ b/pkg/op/server_legacy.go @@ -91,7 +91,7 @@ func (s *LegacyServer) Ready(ctx context.Context, r *Request[struct{}]) (*Respon for _, probe := range s.provider.Probes() { // shouldn't we run probes in Go routines? if err := probe(ctx); err != nil { - return nil, NewStatusError(err, http.StatusInternalServerError) + return nil, AsStatusError(err, http.StatusInternalServerError) } } return NewResponse(Status{Status: "ok"}), nil @@ -106,7 +106,7 @@ func (s *LegacyServer) Discovery(ctx context.Context, r *Request[struct{}]) (*Re func (s *LegacyServer) Keys(ctx context.Context, r *Request[struct{}]) (*Response, error) { keys, err := s.provider.Storage().KeySet(ctx) if err != nil { - return nil, NewStatusError(err, http.StatusInternalServerError) + return nil, AsStatusError(err, http.StatusInternalServerError) } return NewResponse(jsonWebKeySet(keys)), nil } @@ -127,7 +127,7 @@ func (s *LegacyServer) VerifyAuthRequest(ctx context.Context, r *Request[oidc.Au } } if r.Data.ClientID == "" { - return nil, ErrAuthReqMissingClientID + return nil, oidc.ErrInvalidRequest().WithParent(ErrAuthReqMissingClientID).WithDescription(ErrAuthReqMissingClientID.Error()) } client, err := s.provider.Storage().GetClientByClientID(ctx, r.Data.ClientID) if err != nil { @@ -155,7 +155,7 @@ func (s *LegacyServer) Authorize(ctx context.Context, r *ClientRequest[oidc.Auth func (s *LegacyServer) DeviceAuthorization(ctx context.Context, r *ClientRequest[oidc.DeviceAuthorizationRequest]) (*Response, error) { response, err := createDeviceAuthorization(ctx, r.Data, r.Client.GetID(), s.provider) if err != nil { - return nil, NewStatusError(err, http.StatusInternalServerError) + return nil, AsStatusError(err, http.StatusInternalServerError) } return NewResponse(response), nil } @@ -248,7 +248,7 @@ func (s *LegacyServer) JWTProfile(ctx context.Context, r *Request[oidc.JWTProfil } tokenRequest, err := VerifyJWTAssertion(ctx, r.Data.Assertion, exchanger.JWTProfileVerifier(ctx)) if err != nil { - return nil, err + return nil, oidc.ErrInvalidRequest().WithParent(err).WithDescription("assertion invalid") } tokenRequest.Scopes, err = exchanger.Storage().ValidateJWTProfileScopes(ctx, tokenRequest.Issuer, r.Data.Scope) From 3f26eb10ad45a059900b7c2c0c66f4955fa69101 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:26:18 +0200 Subject: [PATCH 017/185] chore(deps): bump go.opentelemetry.io/otel/trace from 1.21.0 to 1.22.0 (#520) Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.21.0 to 1.22.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.21.0...v1.22.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/trace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 737fa45..45c80e5 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/stretchr/testify v1.8.4 github.com/zitadel/logging v0.5.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.21.0 - go.opentelemetry.io/otel/trace v1.21.0 + go.opentelemetry.io/otel v1.22.0 + go.opentelemetry.io/otel/trace v1.22.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/oauth2 v0.16.0 golang.org/x/text v0.14.0 @@ -27,12 +27,12 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect diff --git a/go.sum b/go.sum index 20e9734..8080fa9 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNIT github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= @@ -57,12 +57,12 @@ github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= From b8e520afd0b8ba0f742145e82d3fb8e1de7ac713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 19 Jan 2024 12:30:51 +0200 Subject: [PATCH 018/185] fix: allow expired ID token hint to end sessions (#522) * fix: allow expired ID token hint to end sessions This change adds a specific error for expired ID Token hints, including too old "issued at" and "max auth age". The error is returned VerifyIDTokenHint so that the end session handler can choose to ignore this error. This fixes the behavior to be in line with [OpenID Connect RP-Initiated Logout 1.0, section 4](https://openid.net/specs/openid-connect-rpinitiated-1_0.html#ValidationAndErrorHandling). * Tes IDTokenHintExpiredError --- pkg/oidc/verifier.go | 2 +- pkg/op/session.go | 3 +- pkg/op/verifier_id_token_hint.go | 36 ++++++++---- pkg/op/verifier_id_token_hint_test.go | 79 +++++++++++++++------------ 4 files changed, 74 insertions(+), 46 deletions(-) diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index 42fbb20..fe28857 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -57,7 +57,7 @@ var ( ErrNonceInvalid = errors.New("nonce does not match") ErrAcrInvalid = errors.New("acr is invalid") ErrAuthTimeNotPresent = errors.New("claim `auth_time` of token is missing") - ErrAuthTimeToOld = errors.New("auth time of token is to old") + ErrAuthTimeToOld = errors.New("auth time of token is too old") ErrAtHash = errors.New("at_hash does not correspond to access token") ) diff --git a/pkg/op/session.go b/pkg/op/session.go index c33627f..c933659 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -2,6 +2,7 @@ package op import ( "context" + "errors" "net/http" "net/url" "path" @@ -68,7 +69,7 @@ func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, } if req.IdTokenHint != "" { claims, err := VerifyIDTokenHint[*oidc.IDTokenClaims](ctx, req.IdTokenHint, ender.IDTokenHintVerifier(ctx)) - if err != nil { + if err != nil && !errors.As(err, &IDTokenHintExpiredError{}) { return nil, oidc.ErrInvalidRequest().WithDescription("id_token_hint invalid").WithParent(err) } session.UserID = claims.GetSubject() diff --git a/pkg/op/verifier_id_token_hint.go b/pkg/op/verifier_id_token_hint.go index 6143252..b5ec72e 100644 --- a/pkg/op/verifier_id_token_hint.go +++ b/pkg/op/verifier_id_token_hint.go @@ -2,6 +2,7 @@ package op import ( "context" + "errors" "github.com/zitadel/oidc/v3/pkg/oidc" ) @@ -27,8 +28,23 @@ func NewIDTokenHintVerifier(issuer string, keySet oidc.KeySet, opts ...IDTokenHi return verifier } +type IDTokenHintExpiredError struct { + error +} + +func (e IDTokenHintExpiredError) Unwrap() error { + return e.error +} + +func (e IDTokenHintExpiredError) Is(err error) bool { + return errors.Is(err, e.error) +} + // VerifyIDTokenHint validates the id token according to -// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation +// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. +// In case of an expired token both the Claims and first encountered expiry related error +// is returned of type [IDTokenHintExpiredError]. In that case the caller can choose to still +// trust the token for cases like logout, as signature and other verifications succeeded. func VerifyIDTokenHint[C oidc.Claims](ctx context.Context, token string, v *IDTokenHintVerifier) (claims C, err error) { var nilClaims C @@ -49,20 +65,20 @@ func VerifyIDTokenHint[C oidc.Claims](ctx context.Context, token string, v *IDTo return nilClaims, err } - if err = oidc.CheckExpiration(claims, v.Offset); err != nil { - return nilClaims, err - } - - if err = oidc.CheckIssuedAt(claims, v.MaxAgeIAT, v.Offset); err != nil { - return nilClaims, err - } - if err = oidc.CheckAuthorizationContextClassReference(claims, v.ACR); err != nil { return nilClaims, err } + if err = oidc.CheckExpiration(claims, v.Offset); err != nil { + return claims, IDTokenHintExpiredError{err} + } + + if err = oidc.CheckIssuedAt(claims, v.MaxAgeIAT, v.Offset); err != nil { + return claims, IDTokenHintExpiredError{err} + } + if err = oidc.CheckAuthTime(claims, v.MaxAge); err != nil { - return nilClaims, err + return claims, IDTokenHintExpiredError{err} } return claims, nil } diff --git a/pkg/op/verifier_id_token_hint_test.go b/pkg/op/verifier_id_token_hint_test.go index e514a76..597e291 100644 --- a/pkg/op/verifier_id_token_hint_test.go +++ b/pkg/op/verifier_id_token_hint_test.go @@ -2,6 +2,7 @@ package op import ( "context" + "errors" "testing" "time" @@ -57,6 +58,13 @@ func TestNewIDTokenHintVerifier(t *testing.T) { } } +func Test_IDTokenHintExpiredError(t *testing.T) { + var err error = IDTokenHintExpiredError{oidc.ErrExpired} + assert.True(t, errors.Unwrap(err) == oidc.ErrExpired) + assert.ErrorIs(t, err, oidc.ErrExpired) + assert.ErrorAs(t, err, &IDTokenHintExpiredError{}) +} + func TestVerifyIDTokenHint(t *testing.T) { verifier := &IDTokenHintVerifier{ Issuer: tu.ValidIssuer, @@ -71,21 +79,23 @@ func TestVerifyIDTokenHint(t *testing.T) { tests := []struct { name string tokenClaims func() (string, *oidc.IDTokenClaims) - wantErr bool + wantClaims bool + wantErr error }{ { name: "success", tokenClaims: tu.ValidIDToken, + wantClaims: true, }, { name: "parse err", tokenClaims: func() (string, *oidc.IDTokenClaims) { return "~~~~", nil }, - wantErr: true, + wantErr: oidc.ErrParse, }, { name: "invalid signature", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.InvalidSignatureToken, nil }, - wantErr: true, + wantErr: oidc.ErrSignatureUnsupportedAlg, }, { name: "wrong issuer", @@ -96,29 +106,7 @@ func TestVerifyIDTokenHint(t *testing.T) { tu.ValidACR, tu.ValidAMR, tu.ValidClientID, tu.ValidSkew, "", ) }, - wantErr: true, - }, - { - name: "expired", - tokenClaims: func() (string, *oidc.IDTokenClaims) { - return tu.NewIDToken( - tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, - tu.ValidExpiration.Add(-time.Hour), tu.ValidAuthTime, tu.ValidNonce, - tu.ValidACR, tu.ValidAMR, tu.ValidClientID, tu.ValidSkew, "", - ) - }, - wantErr: true, - }, - { - name: "wrong IAT", - tokenClaims: func() (string, *oidc.IDTokenClaims) { - return tu.NewIDToken( - tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, - tu.ValidExpiration, tu.ValidAuthTime, tu.ValidNonce, - tu.ValidACR, tu.ValidAMR, tu.ValidClientID, -time.Hour, "", - ) - }, - wantErr: true, + wantErr: oidc.ErrIssuerInvalid, }, { name: "wrong acr", @@ -129,7 +117,31 @@ func TestVerifyIDTokenHint(t *testing.T) { "else", tu.ValidAMR, tu.ValidClientID, tu.ValidSkew, "", ) }, - wantErr: true, + wantErr: oidc.ErrAcrInvalid, + }, + { + name: "expired", + tokenClaims: func() (string, *oidc.IDTokenClaims) { + return tu.NewIDToken( + tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, + tu.ValidExpiration.Add(-time.Hour), tu.ValidAuthTime, tu.ValidNonce, + tu.ValidACR, tu.ValidAMR, tu.ValidClientID, tu.ValidSkew, "", + ) + }, + wantClaims: true, + wantErr: IDTokenHintExpiredError{oidc.ErrExpired}, + }, + { + name: "IAT too old", + tokenClaims: func() (string, *oidc.IDTokenClaims) { + return tu.NewIDToken( + tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, + tu.ValidExpiration, tu.ValidAuthTime, tu.ValidNonce, + tu.ValidACR, tu.ValidAMR, tu.ValidClientID, time.Hour, "", + ) + }, + wantClaims: true, + wantErr: IDTokenHintExpiredError{oidc.ErrIatToOld}, }, { name: "expired auth", @@ -140,7 +152,8 @@ func TestVerifyIDTokenHint(t *testing.T) { tu.ValidACR, tu.ValidAMR, tu.ValidClientID, tu.ValidSkew, "", ) }, - wantErr: true, + wantClaims: true, + wantErr: IDTokenHintExpiredError{oidc.ErrAuthTimeToOld}, }, } for _, tt := range tests { @@ -148,14 +161,12 @@ func TestVerifyIDTokenHint(t *testing.T) { token, want := tt.tokenClaims() got, err := VerifyIDTokenHint[*oidc.IDTokenClaims](context.Background(), token, verifier) - if tt.wantErr { - assert.Error(t, err) - assert.Nil(t, got) + require.ErrorIs(t, err, tt.wantErr) + if tt.wantClaims { + assert.Equal(t, got, want, "claims") return } - require.NoError(t, err) - require.NotNil(t, got) - assert.Equal(t, got, want) + assert.Nil(t, got, "claims") }) } } From 437a0497ab3454b8ce6cdd5310bae2d9c906d906 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 13:54:30 +0200 Subject: [PATCH 019/185] chore(deps): bump github.com/google/uuid from 1.5.0 to 1.6.0 (#523) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 45c80e5..eb53ce5 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-jose/go-jose/v3 v3.0.1 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/gorilla/securecookie v1.1.2 github.com/jeremija/gosubmit v0.2.7 github.com/muhlemmer/gu v0.3.1 diff --git a/go.sum b/go.sum index 8080fa9..f75fab7 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= From e9bd7d7bac49692a814e4f89e01f572eb3a263a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 26 Jan 2024 17:44:50 +0200 Subject: [PATCH 020/185] feat(op): split the access and ID token hint verifiers (#525) * feat(op): split the access and ID token hint verifiers In zitadel we require different behaviors wrt public key expiry between access tokens and ID token hints. This change splits the two verifiers in the OP. The default is still based on Storage and passed to both verifier fields. * add new options to tests --- pkg/op/op.go | 59 ++++++++++++++++++++++++++--------------------- pkg/op/op_test.go | 8 +++++-- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/pkg/op/op.go b/pkg/op/op.go index fdc073c..14c5356 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -257,13 +257,16 @@ func NewForwardedOpenIDProvider(path string, config *Config, storage Storage, op // op.AuthCallbackURL(provider) which is probably /callback. On the redirect back // to the AuthCallbackURL, the request id should be passed as the "id" parameter. func NewProvider(config *Config, storage Storage, issuer func(insecure bool) (IssuerFromRequest, error), opOpts ...Option) (_ *Provider, err error) { + keySet := &OpenIDKeySet{storage} o := &Provider{ - config: config, - storage: storage, - endpoints: DefaultEndpoints, - timer: make(<-chan time.Time), - corsOpts: &defaultCORSOptions, - logger: slog.Default(), + config: config, + storage: storage, + accessTokenKeySet: keySet, + idTokenHinKeySet: keySet, + endpoints: DefaultEndpoints, + timer: make(<-chan time.Time), + corsOpts: &defaultCORSOptions, + logger: slog.Default(), } for _, optFunc := range opOpts { @@ -276,19 +279,11 @@ func NewProvider(config *Config, storage Storage, issuer func(insecure bool) (Is if err != nil { return nil, err } - o.Handler = CreateRouter(o, o.interceptors...) - o.decoder = schema.NewDecoder() o.decoder.IgnoreUnknownKeys(true) - o.encoder = oidc.NewEncoder() - o.crypto = NewAESCrypto(config.CryptoKey) - - // Avoid potential race conditions by calling these early - _ = o.openIDKeySet() // sets keySet - return o, nil } @@ -299,7 +294,8 @@ type Provider struct { insecure bool endpoints *Endpoints storage Storage - keySet *openIDKeySet + accessTokenKeySet oidc.KeySet + idTokenHinKeySet oidc.KeySet crypto Crypto decoder *schema.Decoder encoder *schema.Encoder @@ -435,7 +431,7 @@ func (o *Provider) Encoder() httphelper.Encoder { } func (o *Provider) IDTokenHintVerifier(ctx context.Context) *IDTokenHintVerifier { - return NewIDTokenHintVerifier(IssuerFromContext(ctx), o.openIDKeySet(), o.idTokenHintVerifierOpts...) + return NewIDTokenHintVerifier(IssuerFromContext(ctx), o.idTokenHinKeySet, o.idTokenHintVerifierOpts...) } func (o *Provider) JWTProfileVerifier(ctx context.Context) *JWTProfileVerifier { @@ -443,14 +439,7 @@ func (o *Provider) JWTProfileVerifier(ctx context.Context) *JWTProfileVerifier { } func (o *Provider) AccessTokenVerifier(ctx context.Context) *AccessTokenVerifier { - return NewAccessTokenVerifier(IssuerFromContext(ctx), o.openIDKeySet(), o.accessTokenVerifierOpts...) -} - -func (o *Provider) openIDKeySet() oidc.KeySet { - if o.keySet == nil { - o.keySet = &openIDKeySet{o.Storage()} - } - return o.keySet + return NewAccessTokenVerifier(IssuerFromContext(ctx), o.accessTokenKeySet, o.accessTokenVerifierOpts...) } func (o *Provider) Crypto() Crypto { @@ -480,13 +469,13 @@ func (o *Provider) HttpHandler() http.Handler { return o } -type openIDKeySet struct { +type OpenIDKeySet struct { Storage } // VerifySignature implements the oidc.KeySet interface // providing an implementation for the keys stored in the OP Storage interface -func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { +func (o *OpenIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { keySet, err := o.Storage.KeySet(ctx) if err != nil { return nil, fmt.Errorf("error fetching keys: %w", err) @@ -617,6 +606,15 @@ func WithHttpInterceptors(interceptors ...HttpInterceptor) Option { } } +// WithAccessTokenKeySet allows passing a KeySet with public keys for Access Token verification. +// The default KeySet uses the [Storage] interface +func WithAccessTokenKeySet(keySet oidc.KeySet) Option { + return func(o *Provider) error { + o.accessTokenKeySet = keySet + return nil + } +} + func WithAccessTokenVerifierOpts(opts ...AccessTokenVerifierOpt) Option { return func(o *Provider) error { o.accessTokenVerifierOpts = opts @@ -624,6 +622,15 @@ func WithAccessTokenVerifierOpts(opts ...AccessTokenVerifierOpt) Option { } } +// WithIDTokenHintKeySet allows passing a KeySet with public keys for ID Token Hint verification. +// The default KeySet uses the [Storage] interface. +func WithIDTokenHintKeySet(keySet oidc.KeySet) Option { + return func(o *Provider) error { + o.idTokenHinKeySet = keySet + return nil + } +} + func WithIDTokenHintVerifierOpts(opts ...IDTokenHintVerifierOpt) Option { return func(o *Provider) error { o.idTokenHintVerifierOpts = opts diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index f97f666..b2a758c 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -58,8 +58,12 @@ func init() { } func newTestProvider(config *op.Config) op.OpenIDProvider { - provider, err := op.NewOpenIDProvider(testIssuer, config, - storage.NewStorage(storage.NewUserStore(testIssuer)), op.WithAllowInsecure(), + storage := storage.NewStorage(storage.NewUserStore(testIssuer)) + keySet := &op.OpenIDKeySet{storage} + provider, err := op.NewOpenIDProvider(testIssuer, config, storage, + op.WithAllowInsecure(), + op.WithAccessTokenKeySet(keySet), + op.WithIDTokenHintKeySet(keySet), ) if err != nil { panic(err) From 35d9540fd74496d8dc059fbf2bd701f74872d884 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:56:16 +0200 Subject: [PATCH 021/185] chore(deps): bump codecov/codecov-action from 3.1.4 to 3.1.5 (#526) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.4 to 3.1.5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.4...v3.1.5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 42f8d4a..93ffe69 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v3.1.4 + - uses: codecov/codecov-action@v3.1.5 with: file: ./profile.cov name: codecov-go From 045b59e5a55be97ba180fdaae96fb66302a03353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 1 Feb 2024 14:49:22 +0200 Subject: [PATCH 022/185] fix(op): allow expired id token hints in authorize (#527) Like https://github.com/zitadel/oidc/pull/522 for end session, this change allows passing an expired ID token hint to the authorize endpoint. --- pkg/op/auth_request.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index ed368eb..7058ebc 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -391,9 +391,9 @@ func ValidateAuthReqIDTokenHint(ctx context.Context, idTokenHint string, verifie return "", nil } claims, err := VerifyIDTokenHint[*oidc.TokenClaims](ctx, idTokenHint, verifier) - if err != nil { + if err != nil && !errors.As(err, &IDTokenHintExpiredError{}) { return "", oidc.ErrLoginRequired().WithDescription("The id_token_hint is invalid. " + - "If you have any questions, you may contact the administrator of the application.") + "If you have any questions, you may contact the administrator of the application.").WithParent(err) } return claims.GetSubject(), nil } From 2aa8a327f667db92b616460a378d93a906f10274 Mon Sep 17 00:00:00 2001 From: Fabi Date: Fri, 2 Feb 2024 11:57:41 +0100 Subject: [PATCH 023/185] chore: update pm board action (#528) * chore: update pm board action automatically ad prs of non engineers to board and label community prs * Update issue.yml --- .github/workflows/issue.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 362443d..69cb2ae 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -4,15 +4,40 @@ on: issues: types: - opened + pull_request_target: + types: + - opened jobs: add-to-project: - name: Add issue to project + name: Add issue and community pr to project runs-on: ubuntu-latest steps: - - uses: actions/add-to-project@v0.5.0 + - name: add issue + uses: actions/add-to-project@v0.5.0 + if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization # to the issue project-url: https://github.com/orgs/zitadel/projects/2 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} + - uses: tspascoal/get-user-teams-membership@v3 + id: checkUserMember + with: + username: ${{ github.actor }} + GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} + - name: add pr + uses: actions/add-to-project@v0.5.0 + if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} + with: + # You can target a repository in a different organization + # to the issue + project-url: https://github.com/orgs/zitadel/projects/2 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} + - uses: actions-ecosystem/action-add-labels@v1.1.0 + if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'staff')}} + with: + github_token: ${{ secrets.ADD_TO_PROJECT_PAT }} + labels: | + os-contribution + auth From 984346f9ef6563b65cf10dfa658b22cca5dc0839 Mon Sep 17 00:00:00 2001 From: Fabi Date: Fri, 2 Feb 2024 14:33:52 +0100 Subject: [PATCH 024/185] chore: remove dependabot prs (#529) --- .github/workflows/issue.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 69cb2ae..4184654 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -28,16 +28,15 @@ jobs: GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr uses: actions/add-to-project@v0.5.0 - if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} + if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'engineers') && github.actor != 'app/dependabot'}} with: # You can target a repository in a different organization # to the issue project-url: https://github.com/orgs/zitadel/projects/2 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - uses: actions-ecosystem/action-add-labels@v1.1.0 - if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'staff')}} + if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'staff') && github.actor != 'app/dependabot'}} with: github_token: ${{ secrets.ADD_TO_PROJECT_PAT }} labels: | os-contribution - auth From 25e103b24306fe80560b6281bfe0aecf2d513fb1 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Wed, 7 Feb 2024 07:30:04 +0100 Subject: [PATCH 025/185] chore: ignore dependabot for board PRs --- .github/workflows/issue.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 4184654..83d8ea3 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -23,19 +23,20 @@ jobs: github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - uses: tspascoal/get-user-teams-membership@v3 id: checkUserMember + if: github.actor == 'dependabot[bot]' with: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr uses: actions/add-to-project@v0.5.0 - if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'engineers') && github.actor != 'app/dependabot'}} + if: ${{ github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization # to the issue project-url: https://github.com/orgs/zitadel/projects/2 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - uses: actions-ecosystem/action-add-labels@v1.1.0 - if: ${{ github.event_name == 'pull_request_target' && !contains(steps.checkUserMember.outputs.teams, 'staff') && github.actor != 'app/dependabot'}} + if: ${{ github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'staff')}} with: github_token: ${{ secrets.ADD_TO_PROJECT_PAT }} labels: | From 7a45a8645226a786191b4ee73e47713bdb09a441 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:26:46 +0200 Subject: [PATCH 026/185] chore(deps): bump codecov/codecov-action from 3.1.5 to 4.0.1 (#531) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.5 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.5...v4.0.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 93ffe69..6f92575 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v3.1.5 + - uses: codecov/codecov-action@v4.0.1 with: file: ./profile.cov name: codecov-go From 34f44325b8191c0997a9995521c653ccee4a30f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:29:38 +0200 Subject: [PATCH 027/185] chore(deps): bump go.opentelemetry.io/otel/trace from 1.22.0 to 1.23.0 (#534) Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.22.0...v1.23.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/trace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index eb53ce5..32a8951 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/stretchr/testify v1.8.4 github.com/zitadel/logging v0.5.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.22.0 - go.opentelemetry.io/otel/trace v1.22.0 + go.opentelemetry.io/otel v1.23.0 + go.opentelemetry.io/otel/trace v1.23.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/oauth2 v0.16.0 golang.org/x/text v0.14.0 @@ -32,7 +32,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.23.0 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect diff --git a/go.sum b/go.sum index f75fab7..f3d8daf 100644 --- a/go.sum +++ b/go.sum @@ -57,12 +57,12 @@ github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= -go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= -go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E= +go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0= +go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo= +go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo= +go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI= +go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= From 3ea61738604d6e0f4a1565401500054f3fd64bca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:30:44 +0200 Subject: [PATCH 028/185] chore(deps): bump actions-ecosystem/action-add-labels (#530) Bumps [actions-ecosystem/action-add-labels](https://github.com/actions-ecosystem/action-add-labels) from 1.1.0 to 1.1.3. - [Release notes](https://github.com/actions-ecosystem/action-add-labels/releases) - [Commits](https://github.com/actions-ecosystem/action-add-labels/compare/v1.1.0...v1.1.3) --- updated-dependencies: - dependency-name: actions-ecosystem/action-add-labels dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 83d8ea3..1409ff1 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -35,7 +35,7 @@ jobs: # to the issue project-url: https://github.com/orgs/zitadel/projects/2 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - - uses: actions-ecosystem/action-add-labels@v1.1.0 + - uses: actions-ecosystem/action-add-labels@v1.1.3 if: ${{ github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'staff')}} with: github_token: ${{ secrets.ADD_TO_PROJECT_PAT }} From ee8152f19eecd5d490299c0ddd993e4324cb2432 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Fri, 9 Feb 2024 16:11:59 +0100 Subject: [PATCH 029/185] chore: ignore dependabot for board PRs --- .github/workflows/issue.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 1409ff1..62fd01d 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -23,20 +23,20 @@ jobs: github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - uses: tspascoal/get-user-teams-membership@v3 id: checkUserMember - if: github.actor == 'dependabot[bot]' + if: github.actor != 'dependabot[bot]' with: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr uses: actions/add-to-project@v0.5.0 - if: ${{ github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} + if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization # to the issue project-url: https://github.com/orgs/zitadel/projects/2 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} - uses: actions-ecosystem/action-add-labels@v1.1.3 - if: ${{ github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'staff')}} + if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'staff')}} with: github_token: ${{ secrets.ADD_TO_PROJECT_PAT }} labels: | From 625a4e480d2d06819c345ed94c7b506727b0532a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:14:24 +0100 Subject: [PATCH 030/185] chore(deps): bump go.opentelemetry.io/otel/trace from 1.23.0 to 1.23.1 (#539) Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.23.0 to 1.23.1. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.0...v1.23.1) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/trace dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 32a8951..30e5abe 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/stretchr/testify v1.8.4 github.com/zitadel/logging v0.5.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.23.0 - go.opentelemetry.io/otel/trace v1.23.0 + go.opentelemetry.io/otel v1.23.1 + go.opentelemetry.io/otel/trace v1.23.1 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/oauth2 v0.16.0 golang.org/x/text v0.14.0 @@ -32,7 +32,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.23.0 // indirect + go.opentelemetry.io/otel/metric v1.23.1 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect diff --git a/go.sum b/go.sum index f3d8daf..5639d44 100644 --- a/go.sum +++ b/go.sum @@ -57,12 +57,12 @@ github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E= -go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0= -go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo= -go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo= -go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI= -go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk= +go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY= +go.opentelemetry.io/otel v1.23.1/go.mod h1:Td0134eafDLcTS4y+zQ26GE8u3dEuRBiBCTUIRHaikA= +go.opentelemetry.io/otel/metric v1.23.1 h1:PQJmqJ9u2QaJLBOELl1cxIdPcpbwzbkjfEyelTl2rlo= +go.opentelemetry.io/otel/metric v1.23.1/go.mod h1:mpG2QPlAfnK8yNhNJAxDZruU9Y1/HubbC+KyH8FaCWI= +go.opentelemetry.io/otel/trace v1.23.1 h1:4LrmmEd8AU2rFvU1zegmvqW7+kWarxtNOPyeL6HmYY8= +go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1KcVmuW7dwFSVrI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= From 1eebaf8d6f0c47241ddc1ea69e17729bdf947f1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:14:46 +0100 Subject: [PATCH 031/185] chore(deps): bump go.opentelemetry.io/otel from 1.23.0 to 1.23.1 (#540) Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.23.0 to 1.23.1. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.0...v1.23.1) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From da8b73f3425ae9e0e3836db5cadc101541952e5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:16:10 +0000 Subject: [PATCH 032/185] chore(deps): bump golang.org/x/oauth2 from 0.16.0 to 0.17.0 (#542) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.16.0 to 0.17.0. - [Commits](https://github.com/golang/oauth2/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 30e5abe..534c5e6 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( go.opentelemetry.io/otel v1.23.1 go.opentelemetry.io/otel/trace v1.23.1 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 - golang.org/x/oauth2 v0.16.0 + golang.org/x/oauth2 v0.17.0 golang.org/x/text v0.14.0 ) @@ -33,9 +33,9 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.23.1 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 5639d44..aee4334 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1Kc golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -77,11 +77,11 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -90,8 +90,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= From 3e593474e989be842afcaefb4111418cee6d3939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 12:14:41 +0200 Subject: [PATCH 033/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.0.11 to 5.0.12 (#548) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.11 to 5.0.12. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.0.11...v5.0.12) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 534c5e6..8b3865b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 - github.com/go-chi/chi/v5 v5.0.11 + github.com/go-chi/chi/v5 v5.0.12 github.com/go-jose/go-jose/v3 v3.0.1 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index aee4334..3ffd38c 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTS github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA= -github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= +github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From b45072a4c0c978366c63ca53c048bb9e1a35e375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Wed, 21 Feb 2024 11:17:00 +0100 Subject: [PATCH 034/185] fix: Set unauthorizedHandler, if not defined (#547) --- pkg/client/rp/relying_party.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 04be4ef..6105b2f 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -167,6 +167,9 @@ func (rp *relyingParty) ErrorHandler() func(http.ResponseWriter, *http.Request, } func (rp *relyingParty) UnauthorizedHandler() func(http.ResponseWriter, *http.Request, string, string) { + if rp.unauthorizedHandler == nil { + rp.unauthorizedHandler = DefaultUnauthorizedHandler + } return rp.unauthorizedHandler } @@ -196,8 +199,9 @@ func NewRelyingPartyOAuth(config *oauth2.Config, options ...Option) (RelyingPart } // avoid races by calling these early - _ = rp.IDTokenVerifier() // sets idTokenVerifier - _ = rp.ErrorHandler() // sets errorHandler + _ = rp.IDTokenVerifier() // sets idTokenVerifier + _ = rp.ErrorHandler() // sets errorHandler + _ = rp.UnauthorizedHandler() // sets unauthorizedHandler return rp, nil } @@ -233,8 +237,9 @@ func NewRelyingPartyOIDC(ctx context.Context, issuer, clientID, clientSecret, re rp.endpoints = endpoints // avoid races by calling these early - _ = rp.IDTokenVerifier() // sets idTokenVerifier - _ = rp.ErrorHandler() // sets errorHandler + _ = rp.IDTokenVerifier() // sets idTokenVerifier + _ = rp.ErrorHandler() // sets errorHandler + _ = rp.UnauthorizedHandler() // sets unauthorizedHandler return rp, nil } From f4bbffb51b60be934f1b79082de71d8aba4f6eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Fri, 23 Feb 2024 11:18:06 +0100 Subject: [PATCH 035/185] feat: Add rp.WithAuthStyle as Option (#546) * feat: Add rp.WithAuthStyle as Option * Update integration_test.go * Update integration_test.go * Update integration_test.go --- pkg/client/integration_test.go | 2 ++ pkg/client/rp/relying_party.go | 25 ++++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkg/client/integration_test.go b/pkg/client/integration_test.go index 7d4cd9e..ce77f5e 100644 --- a/pkg/client/integration_test.go +++ b/pkg/client/integration_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/exp/slog" + "golang.org/x/oauth2" "github.com/zitadel/oidc/v3/example/server/exampleop" "github.com/zitadel/oidc/v3/example/server/storage" @@ -217,6 +218,7 @@ func RunAuthorizationCodeFlow(t *testing.T, opServer *httptest.Server, clientID, targetURL, []string{"openid", "email", "profile", "offline_access"}, rp.WithPKCE(cookieHandler), + rp.WithAuthStyle(oauth2.AuthStyleInHeader), rp.WithVerifierOpts( rp.WithIssuedAtOffset(5*time.Second), rp.WithSupportedSigningAlgorithms("RS256", "RS384", "RS512", "ES256", "ES384", "ES512"), diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 6105b2f..d4bc13c 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -100,6 +100,8 @@ type relyingParty struct { httpClient *http.Client cookieHandler *httphelper.CookieHandler + oauthAuthStyle oauth2.AuthStyle + errorHandler func(http.ResponseWriter, *http.Request, string, string, string) unauthorizedHandler func(http.ResponseWriter, *http.Request, string, string) idTokenVerifier *IDTokenVerifier @@ -190,6 +192,7 @@ func NewRelyingPartyOAuth(config *oauth2.Config, options ...Option) (RelyingPart httpClient: httphelper.DefaultHTTPClient, oauth2Only: true, unauthorizedHandler: DefaultUnauthorizedHandler, + oauthAuthStyle: oauth2.AuthStyleAutoDetect, } for _, optFunc := range options { @@ -198,6 +201,8 @@ func NewRelyingPartyOAuth(config *oauth2.Config, options ...Option) (RelyingPart } } + rp.oauthConfig.Endpoint.AuthStyle = rp.oauthAuthStyle + // avoid races by calling these early _ = rp.IDTokenVerifier() // sets idTokenVerifier _ = rp.ErrorHandler() // sets errorHandler @@ -218,8 +223,9 @@ func NewRelyingPartyOIDC(ctx context.Context, issuer, clientID, clientSecret, re RedirectURL: redirectURI, Scopes: scopes, }, - httpClient: httphelper.DefaultHTTPClient, - oauth2Only: false, + httpClient: httphelper.DefaultHTTPClient, + oauth2Only: false, + oauthAuthStyle: oauth2.AuthStyleAutoDetect, } for _, optFunc := range options { @@ -236,6 +242,9 @@ func NewRelyingPartyOIDC(ctx context.Context, issuer, clientID, clientSecret, re rp.oauthConfig.Endpoint = endpoints.Endpoint rp.endpoints = endpoints + rp.oauthConfig.Endpoint.AuthStyle = rp.oauthAuthStyle + rp.endpoints.Endpoint.AuthStyle = rp.oauthAuthStyle + // avoid races by calling these early _ = rp.IDTokenVerifier() // sets idTokenVerifier _ = rp.ErrorHandler() // sets errorHandler @@ -295,6 +304,13 @@ func WithUnauthorizedHandler(unauthorizedHandler UnauthorizedHandler) Option { } } +func WithAuthStyle(oauthAuthStyle oauth2.AuthStyle) Option { + return func(rp *relyingParty) error { + rp.oauthAuthStyle = oauthAuthStyle + return nil + } +} + func WithVerifierOpts(opts ...VerifierOption) Option { return func(rp *relyingParty) error { rp.verifierOpts = opts @@ -594,9 +610,8 @@ type Endpoints struct { func GetEndpoints(discoveryConfig *oidc.DiscoveryConfiguration) Endpoints { return Endpoints{ Endpoint: oauth2.Endpoint{ - AuthURL: discoveryConfig.AuthorizationEndpoint, - AuthStyle: oauth2.AuthStyleAutoDetect, - TokenURL: discoveryConfig.TokenEndpoint, + AuthURL: discoveryConfig.AuthorizationEndpoint, + TokenURL: discoveryConfig.TokenEndpoint, }, IntrospectURL: discoveryConfig.IntrospectionEndpoint, UserinfoURL: discoveryConfig.UserinfoEndpoint, From a6a206b021a4c00a73f7a0a92a6abd8ebba78fa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:45:58 +0200 Subject: [PATCH 036/185] chore(deps): bump go.opentelemetry.io/otel/trace from 1.23.1 to 1.24.0 (#556) Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.23.1 to 1.24.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.23.1...v1.24.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/trace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 8b3865b..10ed4c1 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/stretchr/testify v1.8.4 github.com/zitadel/logging v0.5.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.23.1 - go.opentelemetry.io/otel/trace v1.23.1 + go.opentelemetry.io/otel v1.24.0 + go.opentelemetry.io/otel/trace v1.24.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/oauth2 v0.17.0 golang.org/x/text v0.14.0 @@ -32,7 +32,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.23.1 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect golang.org/x/crypto v0.19.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect diff --git a/go.sum b/go.sum index 3ffd38c..d38a7f2 100644 --- a/go.sum +++ b/go.sum @@ -57,12 +57,12 @@ github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY= -go.opentelemetry.io/otel v1.23.1/go.mod h1:Td0134eafDLcTS4y+zQ26GE8u3dEuRBiBCTUIRHaikA= -go.opentelemetry.io/otel/metric v1.23.1 h1:PQJmqJ9u2QaJLBOELl1cxIdPcpbwzbkjfEyelTl2rlo= -go.opentelemetry.io/otel/metric v1.23.1/go.mod h1:mpG2QPlAfnK8yNhNJAxDZruU9Y1/HubbC+KyH8FaCWI= -go.opentelemetry.io/otel/trace v1.23.1 h1:4LrmmEd8AU2rFvU1zegmvqW7+kWarxtNOPyeL6HmYY8= -go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1KcVmuW7dwFSVrI= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= From b93f625088b6311a2e7f4db26d3094f0a0bf5c7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:47:11 +0200 Subject: [PATCH 037/185] chore(deps): bump github.com/go-jose/go-jose/v3 from 3.0.1 to 3.0.2 (#554) Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v3.0.1...v3.0.2) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 32 +++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 10ed4c1..d1c5f2b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.0.12 - github.com/go-jose/go-jose/v3 v3.0.1 + github.com/go-jose/go-jose/v3 v3.0.2 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index d38a7f2..f84f80e 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= -github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.2 h1:2Edjn8Nrb44UvTdp84KU0bBPs1cO7noRCybtS3eJEUQ= +github.com/go-jose/go-jose/v3 v3.0.2/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -19,9 +19,9 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= @@ -48,11 +48,11 @@ github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA= github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= @@ -64,19 +64,25 @@ go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8p go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -84,23 +90,39 @@ golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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-20220715151400-c0bba94af5f8/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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.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/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 385060930dd4438ac4589f211034caecf48fa497 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:05:38 +0200 Subject: [PATCH 038/185] chore(deps): bump actions/add-to-project from 0.5.0 to 0.6.0 (#558) Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 0.5.0 to 0.6.0. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v0.5.0...v0.6.0) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 62fd01d..a2b56eb 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: add issue - uses: actions/add-to-project@v0.5.0 + uses: actions/add-to-project@v0.6.0 if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization @@ -28,7 +28,7 @@ jobs: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr - uses: actions/add-to-project@v0.5.0 + uses: actions/add-to-project@v0.6.0 if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization From 38c025f7f8948484cd044dcf8d466fb210a2e022 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:09:14 +0200 Subject: [PATCH 039/185] chore(deps): bump codecov/codecov-action from 4.0.1 to 4.1.0 (#559) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.0.1 to 4.1.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.0.1...v4.1.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f92575..12b9007 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.0.1 + - uses: codecov/codecov-action@v4.1.0 with: file: ./profile.cov name: codecov-go From 972b8981e5e10fde590d9dd426702ab525f33de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 28 Feb 2024 11:44:14 +0200 Subject: [PATCH 040/185] feat: go 1.22 and slog migration (#557) This change adds Go 1.22 as a build target and drops support for Go 1.20 and older. The golang.org/x/exp/slog import is migrated to log/slog. Slog has been part of the Go standard library since Go 1.21. Therefore we are dropping support for older Go versions. This is in line of our support policy of "the latest two Go versions". --- .github/workflows/release.yml | 2 +- README.md | 5 +- example/client/app/app.go | 2 +- example/server/exampleop/op.go | 2 +- example/server/main.go | 2 +- example/server/storage/oidc.go | 2 +- go.mod | 5 +- go.sum | 12 +++-- pkg/client/integration_test.go | 2 +- pkg/client/rp/log.go | 2 +- pkg/client/rp/relying_party.go | 2 +- pkg/oidc/authorization.go | 2 +- pkg/oidc/authorization_test.go | 2 +- pkg/oidc/error.go | 3 +- pkg/oidc/error_go120_test.go | 83 ---------------------------------- pkg/oidc/error_test.go | 74 +++++++++++++++++++++++++++++- pkg/op/auth_request.go | 2 +- pkg/op/auth_request_test.go | 2 +- pkg/op/error.go | 2 +- pkg/op/error_test.go | 2 +- pkg/op/mock/authorizer.mock.go | 2 +- pkg/op/op.go | 6 +-- pkg/op/server_http.go | 2 +- pkg/op/server_http_test.go | 2 +- pkg/op/session.go | 2 +- pkg/op/token_request.go | 2 +- 26 files changed, 106 insertions(+), 120 deletions(-) delete mode 100644 pkg/oidc/error_go120_test.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12b9007..a4a8f87 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - go: ['1.19', '1.20', '1.21'] + go: ['1.21', '1.22'] name: Go ${{ matrix.go }} test steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 7f1a610..72ae8d4 100644 --- a/README.md +++ b/README.md @@ -115,10 +115,9 @@ Versions that also build are marked with :warning:. | Version | Supported | | ------- | ------------------ | -| <1.19 | :x: | -| 1.19 | :warning: | -| 1.20 | :white_check_mark: | +| <1.21 | :x: | | 1.21 | :white_check_mark: | +| 1.22 | :white_check_mark: | ## Why another library diff --git a/example/client/app/app.go b/example/client/app/app.go index 0e339f4..a779169 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "log/slog" "net/http" "os" "strings" @@ -12,7 +13,6 @@ import ( "github.com/google/uuid" "github.com/sirupsen/logrus" - "golang.org/x/exp/slog" "github.com/zitadel/logging" "github.com/zitadel/oidc/v3/pkg/client/rp" diff --git a/example/server/exampleop/op.go b/example/server/exampleop/op.go index baa2662..893628e 100644 --- a/example/server/exampleop/op.go +++ b/example/server/exampleop/op.go @@ -3,13 +3,13 @@ package exampleop import ( "crypto/sha256" "log" + "log/slog" "net/http" "sync/atomic" "time" "github.com/go-chi/chi/v5" "github.com/zitadel/logging" - "golang.org/x/exp/slog" "golang.org/x/text/language" "github.com/zitadel/oidc/v3/example/server/storage" diff --git a/example/server/main.go b/example/server/main.go index 38057fb..a2ad190 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -2,12 +2,12 @@ package main import ( "fmt" + "log/slog" "net/http" "os" "github.com/zitadel/oidc/v3/example/server/exampleop" "github.com/zitadel/oidc/v3/example/server/storage" - "golang.org/x/exp/slog" ) func main() { diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index 63afcf9..2509f77 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -1,9 +1,9 @@ package storage import ( + "log/slog" "time" - "golang.org/x/exp/slog" "golang.org/x/text/language" "github.com/zitadel/oidc/v3/pkg/oidc" diff --git a/go.mod b/go.mod index d1c5f2b..2ae42cb 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/zitadel/oidc/v3 -go 1.19 +go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 @@ -16,11 +16,10 @@ require ( github.com/rs/cors v1.10.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 - github.com/zitadel/logging v0.5.0 + github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.24.0 go.opentelemetry.io/otel/trace v1.24.0 - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/oauth2 v0.17.0 golang.org/x/text v0.14.0 ) diff --git a/go.sum b/go.sum index f84f80e..42363b9 100644 --- a/go.sum +++ b/go.sum @@ -23,12 +23,14 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= @@ -36,7 +38,9 @@ github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pw github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/vWUetyzY= @@ -53,8 +57,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zitadel/logging v0.5.0 h1:Kunouvqse/efXy4UDvFw5s3vP+Z4AlHo3y8wF7stXHA= -github.com/zitadel/logging v0.5.0/go.mod h1:IzP5fzwFhzzyxHkSmfF8dsyqFsQRJLLcQmwhIBzlGsE= +github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank= +github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= @@ -68,8 +72,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -136,7 +138,9 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/client/integration_test.go b/pkg/client/integration_test.go index ce77f5e..9145c1e 100644 --- a/pkg/client/integration_test.go +++ b/pkg/client/integration_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io" + "log/slog" "math/rand" "net/http" "net/http/cookiejar" @@ -20,7 +21,6 @@ import ( "github.com/jeremija/gosubmit" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "golang.org/x/exp/slog" "golang.org/x/oauth2" "github.com/zitadel/oidc/v3/example/server/exampleop" diff --git a/pkg/client/rp/log.go b/pkg/client/rp/log.go index 6056fa2..556220c 100644 --- a/pkg/client/rp/log.go +++ b/pkg/client/rp/log.go @@ -2,9 +2,9 @@ package rp import ( "context" + "log/slog" "github.com/zitadel/logging" - "golang.org/x/exp/slog" ) func logCtxWithRPData(ctx context.Context, rp RelyingParty, attrs ...any) context.Context { diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index d4bc13c..72270fe 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -4,6 +4,7 @@ import ( "context" "encoding/base64" "errors" + "log/slog" "net/http" "net/url" "time" @@ -11,7 +12,6 @@ import ( "github.com/go-jose/go-jose/v3" "github.com/google/uuid" "github.com/zitadel/logging" - "golang.org/x/exp/slog" "golang.org/x/oauth2" "golang.org/x/oauth2/clientcredentials" diff --git a/pkg/oidc/authorization.go b/pkg/oidc/authorization.go index 511e396..89139ba 100644 --- a/pkg/oidc/authorization.go +++ b/pkg/oidc/authorization.go @@ -1,7 +1,7 @@ package oidc import ( - "golang.org/x/exp/slog" + "log/slog" ) const ( diff --git a/pkg/oidc/authorization_test.go b/pkg/oidc/authorization_test.go index 573d65c..1446efa 100644 --- a/pkg/oidc/authorization_test.go +++ b/pkg/oidc/authorization_test.go @@ -3,10 +3,10 @@ package oidc import ( + "log/slog" "testing" "github.com/stretchr/testify/assert" - "golang.org/x/exp/slog" ) func TestAuthRequest_LogValue(t *testing.T) { diff --git a/pkg/oidc/error.go b/pkg/oidc/error.go index b690a23..86f8724 100644 --- a/pkg/oidc/error.go +++ b/pkg/oidc/error.go @@ -3,8 +3,7 @@ package oidc import ( "errors" "fmt" - - "golang.org/x/exp/slog" + "log/slog" ) type errorType string diff --git a/pkg/oidc/error_go120_test.go b/pkg/oidc/error_go120_test.go deleted file mode 100644 index 399d7f7..0000000 --- a/pkg/oidc/error_go120_test.go +++ /dev/null @@ -1,83 +0,0 @@ -//go:build go1.20 - -package oidc - -import ( - "io" - "testing" - - "github.com/stretchr/testify/assert" - "golang.org/x/exp/slog" -) - -func TestError_LogValue(t *testing.T) { - type fields struct { - Parent error - ErrorType errorType - Description string - State string - redirectDisabled bool - } - tests := []struct { - name string - fields fields - want slog.Value - }{ - { - name: "parent", - fields: fields{ - Parent: io.EOF, - }, - want: slog.GroupValue(slog.Any("parent", io.EOF)), - }, - { - name: "description", - fields: fields{ - Description: "oops", - }, - want: slog.GroupValue(slog.String("description", "oops")), - }, - { - name: "errorType", - fields: fields{ - ErrorType: ExpiredToken, - }, - want: slog.GroupValue(slog.String("type", string(ExpiredToken))), - }, - { - name: "state", - fields: fields{ - State: "123", - }, - want: slog.GroupValue(slog.String("state", "123")), - }, - { - name: "all fields", - fields: fields{ - Parent: io.EOF, - Description: "oops", - ErrorType: ExpiredToken, - State: "123", - }, - want: slog.GroupValue( - slog.Any("parent", io.EOF), - slog.String("description", "oops"), - slog.String("type", string(ExpiredToken)), - slog.String("state", "123"), - ), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - e := &Error{ - Parent: tt.fields.Parent, - ErrorType: tt.fields.ErrorType, - Description: tt.fields.Description, - State: tt.fields.State, - redirectDisabled: tt.fields.redirectDisabled, - } - got := e.LogValue() - assert.Equal(t, tt.want, got) - }) - } -} diff --git a/pkg/oidc/error_test.go b/pkg/oidc/error_test.go index 0554c8f..2eeb4e6 100644 --- a/pkg/oidc/error_test.go +++ b/pkg/oidc/error_test.go @@ -2,10 +2,10 @@ package oidc import ( "io" + "log/slog" "testing" "github.com/stretchr/testify/assert" - "golang.org/x/exp/slog" ) func TestDefaultToServerError(t *testing.T) { @@ -79,3 +79,75 @@ func TestError_LogLevel(t *testing.T) { }) } } + +func TestError_LogValue(t *testing.T) { + type fields struct { + Parent error + ErrorType errorType + Description string + State string + redirectDisabled bool + } + tests := []struct { + name string + fields fields + want slog.Value + }{ + { + name: "parent", + fields: fields{ + Parent: io.EOF, + }, + want: slog.GroupValue(slog.Any("parent", io.EOF)), + }, + { + name: "description", + fields: fields{ + Description: "oops", + }, + want: slog.GroupValue(slog.String("description", "oops")), + }, + { + name: "errorType", + fields: fields{ + ErrorType: ExpiredToken, + }, + want: slog.GroupValue(slog.String("type", string(ExpiredToken))), + }, + { + name: "state", + fields: fields{ + State: "123", + }, + want: slog.GroupValue(slog.String("state", "123")), + }, + { + name: "all fields", + fields: fields{ + Parent: io.EOF, + Description: "oops", + ErrorType: ExpiredToken, + State: "123", + }, + want: slog.GroupValue( + slog.Any("parent", io.EOF), + slog.String("description", "oops"), + slog.String("type", string(ExpiredToken)), + slog.String("state", "123"), + ), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &Error{ + Parent: tt.fields.Parent, + ErrorType: tt.fields.ErrorType, + Description: tt.fields.Description, + State: tt.fields.State, + redirectDisabled: tt.fields.redirectDisabled, + } + got := e.LogValue() + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 7058ebc..d570e25 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "log/slog" "net" "net/http" "net/url" @@ -14,7 +15,6 @@ import ( httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" str "github.com/zitadel/oidc/v3/pkg/strings" - "golang.org/x/exp/slog" ) type AuthRequest interface { diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 18880f0..2e7c75c 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "io" + "log/slog" "net/http" "net/http/httptest" "net/url" @@ -20,7 +21,6 @@ import ( "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/oidc/v3/pkg/op/mock" "github.com/zitadel/schema" - "golang.org/x/exp/slog" ) func TestAuthorize(t *testing.T) { diff --git a/pkg/op/error.go b/pkg/op/error.go index e4580f6..44b1798 100644 --- a/pkg/op/error.go +++ b/pkg/op/error.go @@ -4,11 +4,11 @@ import ( "context" "errors" "fmt" + "log/slog" "net/http" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - "golang.org/x/exp/slog" ) type ErrAuthRequest interface { diff --git a/pkg/op/error_test.go b/pkg/op/error_test.go index 50a9cbf..170039c 100644 --- a/pkg/op/error_test.go +++ b/pkg/op/error_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "log/slog" "net/http" "net/http/httptest" "net/url" @@ -14,7 +15,6 @@ import ( "github.com/stretchr/testify/require" "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/schema" - "golang.org/x/exp/slog" ) func TestAuthRequestError(t *testing.T) { diff --git a/pkg/op/mock/authorizer.mock.go b/pkg/op/mock/authorizer.mock.go index e4297cb..c7703f1 100644 --- a/pkg/op/mock/authorizer.mock.go +++ b/pkg/op/mock/authorizer.mock.go @@ -6,12 +6,12 @@ package mock import ( context "context" + slog "log/slog" reflect "reflect" gomock "github.com/golang/mock/gomock" http "github.com/zitadel/oidc/v3/pkg/http" op "github.com/zitadel/oidc/v3/pkg/op" - slog "golang.org/x/exp/slog" ) // MockAuthorizer is a mock of Authorizer interface. diff --git a/pkg/op/op.go b/pkg/op/op.go index 14c5356..326737a 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -3,6 +3,7 @@ package op import ( "context" "fmt" + "log/slog" "net/http" "time" @@ -12,7 +13,6 @@ import ( "github.com/zitadel/schema" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" - "golang.org/x/exp/slog" "golang.org/x/text/language" httphelper "github.com/zitadel/oidc/v3/pkg/http" @@ -114,8 +114,6 @@ type OpenIDProvider interface { Crypto() Crypto DefaultLogoutRedirectURI() string Probes() []ProbesFn - - // EXPERIMENTAL: Will change to log/slog import after we drop support for Go 1.20 Logger() *slog.Logger // Deprecated: Provider now implements http.Handler directly. @@ -646,8 +644,6 @@ func WithCORSOptions(opts *cors.Options) Option { } // WithLogger lets a logger other than slog.Default(). -// -// EXPERIMENTAL: Will change to log/slog import after we drop support for Go 1.20 func WithLogger(logger *slog.Logger) Option { return func(o *Provider) error { o.logger = logger diff --git a/pkg/op/server_http.go b/pkg/op/server_http.go index 2220e44..0a5e469 100644 --- a/pkg/op/server_http.go +++ b/pkg/op/server_http.go @@ -2,6 +2,7 @@ package op import ( "context" + "log/slog" "net/http" "net/url" @@ -11,7 +12,6 @@ import ( httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/schema" - "golang.org/x/exp/slog" ) // RegisterServer registers an implementation of Server. diff --git a/pkg/op/server_http_test.go b/pkg/op/server_http_test.go index 6cb268f..9ff07bc 100644 --- a/pkg/op/server_http_test.go +++ b/pkg/op/server_http_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io" + "log/slog" "net/http" "net/http/httptest" "net/url" @@ -19,7 +20,6 @@ import ( httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/schema" - "golang.org/x/exp/slog" ) func TestRegisterServer(t *testing.T) { diff --git a/pkg/op/session.go b/pkg/op/session.go index c933659..6af7d7c 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -3,13 +3,13 @@ package op import ( "context" "errors" + "log/slog" "net/http" "net/url" "path" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - "golang.org/x/exp/slog" ) type SessionEnder interface { diff --git a/pkg/op/token_request.go b/pkg/op/token_request.go index f00b294..2006725 100644 --- a/pkg/op/token_request.go +++ b/pkg/op/token_request.go @@ -2,12 +2,12 @@ package op import ( "context" + "log/slog" "net/http" "net/url" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - "golang.org/x/exp/slog" ) type Exchanger interface { From 7bac3c6f40883d5cfe64fd35c383d0f039313e34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 08:10:55 +0100 Subject: [PATCH 041/185] chore(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0 (#560) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2ae42cb..f84e9a5 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/muhlemmer/httpforwarded v0.1.0 github.com/rs/cors v1.10.1 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.24.0 diff --git a/go.sum b/go.sum index 42363b9..6634e85 100644 --- a/go.sum +++ b/go.sum @@ -53,8 +53,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank= From fc743a69c7725b467ef0ca29182fd3255b8b9ca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:07:48 +0100 Subject: [PATCH 042/185] chore(deps): bump golang.org/x/oauth2 from 0.17.0 to 0.18.0 (#562) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.17.0 to 0.18.0. - [Commits](https://github.com/golang/oauth2/compare/v0.17.0...v0.18.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 14 ++++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index f84e9a5..9cb99e6 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.24.0 go.opentelemetry.io/otel/trace v1.24.0 - golang.org/x/oauth2 v0.17.0 + golang.org/x/oauth2 v0.18.0 golang.org/x/text v0.14.0 ) @@ -32,9 +32,9 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 6634e85..9b2c86f 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,9 @@ go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -85,11 +86,11 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -105,8 +106,9 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.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= From 5ef597b1dbfb0ddd797b5ccda78edccd2f58d172 Mon Sep 17 00:00:00 2001 From: Ayato Date: Tue, 5 Mar 2024 22:04:43 +0900 Subject: [PATCH 043/185] feat(op): Add response_mode: form_post (#551) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(op): Add response_mode: form_post * Fix to parse the template ahead of time * Fix to render the template in a buffer * Remove unnecessary import * Fix test * Fix example client setting * Make sure the client not to reuse the content of the response * Fix error handling * Add the response_mode param * Allow implicit flow in the example app * feat(rp): allow form_post in code exchange callback handler --------- Co-authored-by: Tim Möhlmann --- example/client/app/app.go | 15 +++++++- example/server/storage/client.go | 4 +-- example/server/storage/oidc.go | 4 ++- pkg/client/rp/relying_party.go | 7 ++-- pkg/oidc/authorization.go | 1 + pkg/op/auth_request.go | 62 ++++++++++++++++++++++++++++++++ pkg/op/auth_request_test.go | 35 ++++++++++++++++-- pkg/op/form_post.html.tmpl | 14 ++++++++ 8 files changed, 131 insertions(+), 11 deletions(-) create mode 100644 pkg/op/form_post.html.tmpl diff --git a/example/client/app/app.go b/example/client/app/app.go index a779169..9b43b8d 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -32,6 +32,7 @@ func main() { issuer := os.Getenv("ISSUER") port := os.Getenv("PORT") scopes := strings.Split(os.Getenv("SCOPES"), " ") + responseMode := os.Getenv("RESPONSE_MODE") redirectURI := fmt.Sprintf("http://localhost:%v%v", port, callbackPath) cookieHandler := httphelper.NewCookieHandler(key, key, httphelper.WithUnsecure()) @@ -77,12 +78,24 @@ func main() { return uuid.New().String() } + urlOptions := []rp.URLParamOpt{ + rp.WithPromptURLParam("Welcome back!"), + } + + if responseMode != "" { + urlOptions = append(urlOptions, rp.WithResponseModeURLParam(oidc.ResponseMode(responseMode))) + } + // register the AuthURLHandler at your preferred path. // the AuthURLHandler creates the auth request and redirects the user to the auth server. // including state handling with secure cookie and the possibility to use PKCE. // Prompts can optionally be set to inform the server of // any messages that need to be prompted back to the user. - http.Handle("/login", rp.AuthURLHandler(state, provider, rp.WithPromptURLParam("Welcome back!"))) + http.Handle("/login", rp.AuthURLHandler( + state, + provider, + urlOptions..., + )) // for demonstration purposes the returned userinfo response is written as JSON object onto response marshalUserinfo := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[*oidc.IDTokenClaims], state string, rp rp.RelyingParty, info *oidc.UserInfo) { diff --git a/example/server/storage/client.go b/example/server/storage/client.go index 2e57cc5..010b9ce 100644 --- a/example/server/storage/client.go +++ b/example/server/storage/client.go @@ -184,10 +184,10 @@ func WebClient(id, secret string, redirectURIs ...string) *Client { applicationType: op.ApplicationTypeWeb, authMethod: oidc.AuthMethodBasic, loginURL: defaultLoginURL, - responseTypes: []oidc.ResponseType{oidc.ResponseTypeCode}, + responseTypes: []oidc.ResponseType{oidc.ResponseTypeCode, oidc.ResponseTypeIDTokenOnly, oidc.ResponseTypeIDToken}, grantTypes: []oidc.GrantType{oidc.GrantTypeCode, oidc.GrantTypeRefreshToken, oidc.GrantTypeTokenExchange}, accessTokenType: op.AccessTokenTypeBearer, - devMode: false, + devMode: true, idTokenUserinfoClaimsAssertion: false, clockSkew: 0, } diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index 2509f77..9cd08d9 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -35,6 +35,7 @@ type AuthRequest struct { UserID string Scopes []string ResponseType oidc.ResponseType + ResponseMode oidc.ResponseMode Nonce string CodeChallenge *OIDCCodeChallenge @@ -100,7 +101,7 @@ func (a *AuthRequest) GetResponseType() oidc.ResponseType { } func (a *AuthRequest) GetResponseMode() oidc.ResponseMode { - return "" // we won't handle response mode in this example + return a.ResponseMode } func (a *AuthRequest) GetScopes() []string { @@ -154,6 +155,7 @@ func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthReques UserID: userID, Scopes: authReq.Scopes, ResponseType: authReq.ResponseType, + ResponseMode: authReq.ResponseMode, Nonce: authReq.Nonce, CodeChallenge: &OIDCCodeChallenge{ Challenge: authReq.CodeChallenge, diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 72270fe..74da71e 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -494,9 +494,8 @@ func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp R unauthorizedError(w, r, "failed to get state: "+err.Error(), state, rp) return } - params := r.URL.Query() - if params.Get("error") != "" { - rp.ErrorHandler()(w, r, params.Get("error"), params.Get("error_description"), state) + if errValue := r.FormValue("error"); errValue != "" { + rp.ErrorHandler()(w, r, errValue, r.FormValue("error_description"), state) return } codeOpts := make([]CodeExchangeOpt, len(urlParam)) @@ -521,7 +520,7 @@ func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp R } codeOpts = append(codeOpts, WithClientAssertionJWT(assertion)) } - tokens, err := CodeExchange[C](r.Context(), params.Get("code"), rp, codeOpts...) + tokens, err := CodeExchange[C](r.Context(), r.FormValue("code"), rp, codeOpts...) if err != nil { unauthorizedError(w, r, "failed to exchange token: "+err.Error(), state, rp) return diff --git a/pkg/oidc/authorization.go b/pkg/oidc/authorization.go index 89139ba..fa37dbf 100644 --- a/pkg/oidc/authorization.go +++ b/pkg/oidc/authorization.go @@ -48,6 +48,7 @@ const ( ResponseModeQuery ResponseMode = "query" ResponseModeFragment ResponseMode = "fragment" + ResponseModeFormPost ResponseMode = "form_post" // PromptNone (`none`) disallows the Authorization Server to display any authentication or consent user interface pages. // An error (login_required, interaction_required, ...) will be returned if the user is not already authenticated or consent is needed diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index d570e25..18d8826 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -1,9 +1,12 @@ package op import ( + "bytes" "context" + _ "embed" "errors" "fmt" + "html/template" "log/slog" "net" "net/http" @@ -464,6 +467,17 @@ func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthReques Code: code, State: authReq.GetState(), } + + if authReq.GetResponseMode() == oidc.ResponseModeFormPost { + err := AuthResponseFormPost(w, authReq.GetRedirectURI(), &codeResponse, authorizer.Encoder()) + if err != nil { + AuthRequestError(w, r, authReq, err, authorizer) + return + } + + return + } + callback, err := AuthResponseURL(authReq.GetRedirectURI(), authReq.GetResponseType(), authReq.GetResponseMode(), &codeResponse, authorizer.Encoder()) if err != nil { AuthRequestError(w, r, authReq, err, authorizer) @@ -484,6 +498,17 @@ func AuthResponseToken(w http.ResponseWriter, r *http.Request, authReq AuthReque AuthRequestError(w, r, authReq, err, authorizer) return } + + if authReq.GetResponseMode() == oidc.ResponseModeFormPost { + err := AuthResponseFormPost(w, authReq.GetRedirectURI(), resp, authorizer.Encoder()) + if err != nil { + AuthRequestError(w, r, authReq, err, authorizer) + return + } + + return + } + callback, err := AuthResponseURL(authReq.GetRedirectURI(), authReq.GetResponseType(), authReq.GetResponseMode(), resp, authorizer.Encoder()) if err != nil { AuthRequestError(w, r, authReq, err, authorizer) @@ -535,6 +560,43 @@ func AuthResponseURL(redirectURI string, responseType oidc.ResponseType, respons return mergeQueryParams(uri, params), nil } +//go:embed form_post.html.tmpl +var formPostHtmlTemplate string + +var formPostTmpl = template.Must(template.New("form_post").Parse(formPostHtmlTemplate)) + +// AuthResponseFormPost responds a html page that automatically submits the form which contains the auth response parameters +func AuthResponseFormPost(res http.ResponseWriter, redirectURI string, response any, encoder httphelper.Encoder) error { + values := make(map[string][]string) + err := encoder.Encode(response, values) + if err != nil { + return oidc.ErrServerError().WithParent(err) + } + + params := &struct { + RedirectURI string + Params any + }{ + RedirectURI: redirectURI, + Params: values, + } + + var buf bytes.Buffer + err = formPostTmpl.Execute(&buf, params) + if err != nil { + return oidc.ErrServerError().WithParent(err) + } + + res.Header().Set("Cache-Control", "no-store") + res.WriteHeader(http.StatusOK) + _, err = buf.WriteTo(res) + if err != nil { + return oidc.ErrServerError().WithParent(err) + } + + return nil +} + func setFragment(uri *url.URL, params url.Values) string { uri.Fragment = params.Encode() return uri.String() diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 2e7c75c..76cb00d 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -1027,9 +1027,10 @@ func TestAuthResponseCode(t *testing.T) { authorizer func(*testing.T) op.Authorizer } type res struct { - wantCode int - wantLocationHeader string - wantBody string + wantCode int + wantLocationHeader string + wantCacheControlHeader string + wantBody string } tests := []struct { name string @@ -1111,6 +1112,33 @@ func TestAuthResponseCode(t *testing.T) { wantBody: "", }, }, + { + name: "success form_post", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "https://example.com/callback", + TransferState: "state1", + ResponseMode: "form_post", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(context.Background(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantCode: http.StatusOK, + wantCacheControlHeader: "no-store", + wantBody: "\n\n\n\n
\n\n\n\n\n\n\n
\n\n", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1121,6 +1149,7 @@ func TestAuthResponseCode(t *testing.T) { defer resp.Body.Close() assert.Equal(t, tt.res.wantCode, resp.StatusCode) assert.Equal(t, tt.res.wantLocationHeader, resp.Header.Get("Location")) + assert.Equal(t, tt.res.wantCacheControlHeader, resp.Header.Get("Cache-Control")) body, err := io.ReadAll(resp.Body) require.NoError(t, err) assert.Equal(t, tt.res.wantBody, string(body)) diff --git a/pkg/op/form_post.html.tmpl b/pkg/op/form_post.html.tmpl new file mode 100644 index 0000000..7bc9ab3 --- /dev/null +++ b/pkg/op/form_post.html.tmpl @@ -0,0 +1,14 @@ + + + + +
+{{with .Params.state}}{{end}} +{{with .Params.code}}{{end}} +{{with .Params.id_token}}{{end}} +{{with .Params.access_token}}{{end}} +{{with .Params.token_type}}{{end}} +{{with .Params.expires_in}}{{end}} +
+ + \ No newline at end of file From e3e48882dfd387a1d2e552ec74890c5946263191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 5 Mar 2024 15:09:14 +0200 Subject: [PATCH 044/185] chore: upgrade to v3 guide (#463) * chore: upgrade to v3 guide first version with sed scripts. * tidy up introduction info * process feedback from @muir * logging chapter * server interface chapter * update readme with v3 badges and link to update guide * resolve comments --- README.md | 9 +- UPGRADING.md | 370 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 377 insertions(+), 2 deletions(-) create mode 100644 UPGRADING.md diff --git a/README.md b/README.md index 72ae8d4..01d7d47 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) [![Release](https://github.com/zitadel/oidc/workflows/Release/badge.svg)](https://github.com/zitadel/oidc/actions) -[![GoDoc](https://godoc.org/github.com/zitadel/oidc?status.png)](https://pkg.go.dev/github.com/zitadel/oidc) +[![Go Reference](https://pkg.go.dev/badge/github.com/zitadel/oidc/v3.svg)](https://pkg.go.dev/github.com/zitadel/oidc/v3) [![license](https://badgen.net/github/license/zitadel/oidc/)](https://github.com/zitadel/oidc/blob/master/LICENSE) [![release](https://badgen.net/github/release/zitadel/oidc/stable)](https://github.com/zitadel/oidc/releases) -[![Go Report Card](https://goreportcard.com/badge/github.com/zitadel/oidc)](https://goreportcard.com/report/github.com/zitadel/oidc) +[![Go Report Card](https://goreportcard.com/badge/github.com/zitadel/oidc/v3)](https://goreportcard.com/report/github.com/zitadel/oidc/v3) [![codecov](https://codecov.io/gh/zitadel/oidc/branch/main/graph/badge.svg)](https://codecov.io/gh/zitadel/oidc) [![openid_certified](https://cloud.githubusercontent.com/assets/1454075/7611268/4d19de32-f97b-11e4-895b-31b2455a7ca6.png)](https://openid.net/certification/) @@ -37,6 +37,11 @@ The most important packages of the library: /server examples of an OpenID Provider implementations (including dynamic) with some very basic login UI + +### Semver + +This package uses [semver](https://semver.org/) for [releases](https://github.com/zitadel/oidc/releases). Major releases ship breaking changes. Starting with the `v2` to `v3` increment we provide an [upgrade guide](UPGRADING.md) to ease migration to a newer version. + ## How To Use It Check the `/example` folder where example code for different scenarios is located. diff --git a/UPGRADING.md b/UPGRADING.md new file mode 100644 index 0000000..6b5a41d --- /dev/null +++ b/UPGRADING.md @@ -0,0 +1,370 @@ +# Upgrading + +All commands are executed from the root of the project that imports oidc packages. +`sed` commands are created with **GNU sed** in mind and might need alternate syntax +on non-GNU systems, such as MacOS. +Alternatively, GNU sed can be installed on such systems. (`coreutils` package?). + +## V2 to V3 + +**TL;DR** at the [bottom](#full-script) of this chapter is a full `sed` script +containing all automatic steps at once. + + +As first steps we will: +1. Download the latest v3 module; +2. Replace imports in all Go files; +3. Tidy the module file; + +```bash +go get -u github.com/zitadel/oidc/v3 +find . -type f -name '*.go' | xargs sed -i \ + -e 's/github\.com\/zitadel\/oidc\/v2/github.com\/zitadel\/oidc\/v3/g' +go mod tidy +``` + +### global + +#### go-jose package + +`gopkg.in/square/go-jose.v2` import has been changed to `github.com/go-jose/go-jose/v3`. +That means that the imported types are also changed and imports need to be adapted. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/gopkg.in\/square\/go-jose\.v2/github.com\/go-jose\/go-jose\/v3/g' +go mod tidy +``` + +### op + +```go +import "github.com/zitadel/oidc/v3/pkg/op" +``` + +#### Logger + +This version of OIDC adds logging to the framework. For this we use the new Go standard library `log/slog`. (Until v3.12.0 we used `x/exp/slog`). +Mostly OIDC will use error level logs where it's returning an error through a HTTP handler. OIDC errors that are user facing don't carry much context, also for security reasons. With logging we are now able to print the error context, so that developers can more easily find the source of their issues. Previously we just discarded such context. + +Most users of the OP package with the storage interface will not experience breaking changes. However if you use `RequestError()` directly in your code, you now need to give it a `Logger` as final argument. + +The `OpenIDProvider` and sub-interfaces like `Authorizer` and `Exchanger` got a `Logger()` method to return the configured logger. This logger is in turn used by `AuthRequestError()`. You configure the logger with the `WithLogger()` for the `Provider`. By default the `slog.Default()` is used. + +We also provide a new optional interface: [`LogAuthRequest`](https://pkg.go.dev/github.com/zitadel/oidc/v3/pkg/op#LogAuthRequest). If an `AuthRequest` implements this interface, it is completely passed into the logger after an error. Its `LogValue()` will be used by `slog` to print desired fields. This allows omitting sensitive fields you wish not no print. If the interface is not implemented, no `AuthRequest` details will ever be printed. + +#### Server interface + +We've added a new [`Server`](https://pkg.go.dev/github.com/zitadel/oidc/v3/pkg/op#Server) interface. This interface is experimental and subject to change. See [issue 440](https://github.com/zitadel/oidc/issues/440) for the motivation and discussion around this new interface. +Usage of the new interface is not required, but may be used for advanced scenarios when working with the `Storage` interface isn't the optimal solution for your app (like we experienced in [Zitadel](https://github.com/zitadel/zitadel)). + +#### AuthRequestError + +`AuthRequestError` now takes the complete `Authorizer` as final argument, instead of only the encoder. +This is to facilitate the use of the `Logger` as described above. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/\bAuthRequestError(w, r, authReq, err, authorizer.Encoder())/AuthRequestError(w, r, authReq, err, authorizer)/g' +``` + +Note: the sed regex might not find all uses if the local variables of the passed arguments use different names. + +#### AccessTokenVerifier + +`AccessTokenVerifier` interface has become a struct type. `NewAccessTokenVerifier` now returns a pointer to `AccessTokenVerifier`. +Variable and struct fields declarations need to be changed from `op.AccessTokenVerifier` to `*op.AccessTokenVerifier`. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/\bop\.AccessTokenVerifier\b/*op.AccessTokenVerifier/g' +``` + +#### JWTProfileVerifier + +`JWTProfileVerifier` interface has become a struct type. `NewJWTProfileVerifier` now returns a pointer to `JWTProfileVerifier`. +Variable and struct fields declarations need to be changed from `op.JWTProfileVerifier` to `*op.JWTProfileVerifier`. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/\bop\.JWTProfileVerifier\b/*op.JWTProfileVerifier/g' +``` + +#### IDTokenHintVerifier + +`IDTokenHintVerifier` interface has become a struct type. `NewIDTokenHintVerifier` now returns a pointer to `IDTokenHintVerifier`. +Variable and struct fields declarations need to be changed from `op.IDTokenHintVerifier` to `*op.IDTokenHintVerifier`. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/\bop\.IDTokenHintVerifier\b/*op.IDTokenHintVerifier/g' +``` + +#### ParseRequestObject + +`ParseRequestObject` no longer returns `*oidc.AuthRequest` as it already operates on the pointer for the passed `authReq` argument. As such the argument and the return value were the same pointer. Callers can just use the original `*oidc.AuthRequest` now. + +#### Endpoint Configuration + +`Endpoint`s returned from `Configuration` interface methods are now pointers. Usually, `op.Provider` is the main implementation of the `Configuration` interface. However, if a custom implementation is used, you should be able to update it using the following: + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/AuthorizationEndpoint() Endpoint/AuthorizationEndpoint() *Endpoint/g' \ + -e 's/TokenEndpoint() Endpoint/TokenEndpoint() *Endpoint/g' \ + -e 's/IntrospectionEndpoint() Endpoint/IntrospectionEndpoint() *Endpoint/g' \ + -e 's/UserinfoEndpoint() Endpoint/UserinfoEndpoint() *Endpoint/g' \ + -e 's/RevocationEndpoint() Endpoint/RevocationEndpoint() *Endpoint/g' \ + -e 's/EndSessionEndpoint() Endpoint/EndSessionEndpoint() *Endpoint/g' \ + -e 's/KeysEndpoint() Endpoint/KeysEndpoint() *Endpoint/g' \ + -e 's/DeviceAuthorizationEndpoint() Endpoint/DeviceAuthorizationEndpoint() *Endpoint/g' +``` + +#### CreateDiscoveryConfig + +`CreateDiscoveryConfig` now takes a context as first argument. The following adds `context.TODO()` to the function: + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/op\.CreateDiscoveryConfig(/op.CreateDiscoveryConfig(context.TODO(), /g' +``` + +It now takes the issuer out of the context using the [`IssuerFromContext`](https://pkg.go.dev/github.com/zitadel/oidc/v3/pkg/op#IssuerFromContext) functionality, +instead of the `config.IssuerFromRequest()` method. + +#### CreateRouter + +`CreateRouter` now returns a `chi.Router` instead of `*mux.Router`. +Usually this function is called when the Provider is constructed and not by package consumers. +However if your project does call this function directly, manual update of the code is required. + +#### DeviceAuthorizationStorage + +`DeviceAuthorizationStorage` dropped the following methods: + +- `GetDeviceAuthorizationByUserCode` +- `CompleteDeviceAuthorization` +- `DenyDeviceAuthorization` + +These methods proved not to be required from a library point of view. +Implementations of a device authorization flow may take care of these calls in a way they see fit. + +#### AuthorizeCodeChallenge + +The `AuthorizeCodeChallenge` function now only takes the `CodeVerifier` argument, instead of the complete `*oidc.AccessTokenRequest`. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/op\.AuthorizeCodeChallenge(tokenReq/op.AuthorizeCodeChallenge(tokenReq.CodeVerifier/g' +``` + +### client + +```go +import "github.com/zitadel/oidc/v3/pkg/client" +``` + +#### Context + +All client calls now take a context as first argument. The following adds `context.TODO()` to all the affected functions: + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/client\.Discover(/client.Discover(context.TODO(), /g' \ + -e 's/client\.CallTokenEndpoint(/client.CallTokenEndpoint(context.TODO(), /g' \ + -e 's/client\.CallEndSessionEndpoint(/client.CallEndSessionEndpoint(context.TODO(), /g' \ + -e 's/client\.CallRevokeEndpoint(/client.CallRevokeEndpoint(context.TODO(), /g' \ + -e 's/client\.CallTokenExchangeEndpoint(/client.CallTokenExchangeEndpoint(context.TODO(), /g' \ + -e 's/client\.CallDeviceAuthorizationEndpoint(/client.CallDeviceAuthorizationEndpoint(context.TODO(), /g' \ + -e 's/client\.JWTProfileExchange(/client.JWTProfileExchange(context.TODO(), /g' +``` + +#### keyFile type + +The `keyFile` struct type is now exported a `KeyFile` and returned by the `ConfigFromKeyFile` and `ConfigFromKeyFileData`. No changes are needed on the caller's side. + +### client/profile + +The package now defines a new interface `TokenSource` which compliments the `oauth2.TokenSource` with a `TokenCtx` method, so that a context can be explicitly added on each call. Users can migrate to the new method when they whish. + +`NewJWTProfileTokenSource` now takes a context as first argument, so do the related `NewJWTProfileTokenSourceFromKeyFile` and `NewJWTProfileTokenSourceFromKeyFileData`. The context is used for the Discovery request. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/profile\.NewJWTProfileTokenSource(/profile.NewJWTProfileTokenSource(context.TODO(), /g' \ + -e 's/profile\.NewJWTProfileTokenSourceFromKeyFileData(/profile.NewJWTProfileTokenSourceFromKeyFileData(context.TODO(), /g' \ + -e 's/profile\.NewJWTProfileTokenSourceFromKeyFile(/profile.NewJWTProfileTokenSourceFromKeyFile(context.TODO(), /g' +``` + + +### client/rp + +```go +import "github.com/zitadel/oidc/v3/pkg/client/rs" +``` + +#### Discover + +The `Discover` function has been removed. Use `client.Discover` instead. + +#### Context + +Most `rp` functions now require a context as first argument. The following adds `context.TODO()` to the function that have no additional changes. Functions with more complex changes are documented below. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/rp\.NewRelyingPartyOIDC(/rp.NewRelyingPartyOIDC(context.TODO(), /g' \ + -e 's/rp\.EndSession(/rp.EndSession(context.TODO(), /g' \ + -e 's/rp\.RevokeToken(/rp.RevokeToken(context.TODO(), /g' \ + -e 's/rp\.DeviceAuthorization(/rp.DeviceAuthorization(context.TODO(), /g' +``` + +Remember to replace `context.TODO()` with a context that is applicable for your app, where possible. + +#### RefreshAccessToken + +1. Renamed to `RefreshTokens`; +2. A context must be passed; +3. An `*oidc.Tokens` object is now returned, which included an ID Token if it was returned by the server; +4. The function is now generic and requires a type argument for the `IDTokenClaims` implementation inside the returned `oidc.Tokens` object; + +For most use cases `*oidc.IDTokenClaims` can be used as type argument. A custom implementation of `oidc.IDClaims` can be used if type-safe access to custom claims is required. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/rp\.RefreshAccessToken(/rp.RefreshTokens[*oidc.IDTokenClaims](context.TODO(), /g' +``` + +Users that called `tokens.Extra("id_token").(string)` and a subsequent `VerifyTokens` to get the claims, no longer need to do this. The ID token is verified (when present) by `RefreshTokens` already. + + +#### Userinfo + +1. A context must be passed as first argument; +2. The function is now generic and requires a type argument for the returned user info object; + +For most use cases `*oidc.UserInfo` can be used a type argument. A [custom implementation](https://pkg.go.dev/github.com/zitadel/oidc/v3/pkg/client/rp#example-Userinfo-Custom) of `rp.SubjectGetter` can be used if type-safe access to custom claims is required. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/rp\.Userinfo(/rp.Userinfo[*oidc.UserInfo](context.TODO(), /g' +``` + +#### UserinfoCallback + +`UserinfoCallback` has an additional type argument fot the `UserInfo` object. Typically the type argument can be inferred by the compiler, by the function that is passed. The actual code update cannot be done by a simple `sed` script and depends on how the caller implemented the function. + + +#### IDTokenVerifier + +`IDTokenVerifier` interface has become a struct type. `NewIDTokenVerifier` now returns a pointer to `IDTokenVerifier`. +Variable and struct fields declarations need to be changed from `rp.IDTokenVerifier` to `*rp.AccessTokenVerifier`. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/\brp\.IDTokenVerifier\b/*rp.IDTokenVerifier/g' +``` + +### client/rs + +```go +import "github.com/zitadel/oidc/v3/pkg/client/rs" +``` + +#### NewResourceServer + +The `NewResourceServerClientCredentials` and `NewResourceServerJWTProfile` constructor functions now take a context as first argument. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/rs\.NewResourceServerClientCredentials(/rs.NewResourceServerClientCredentials(context.TODO(), /g' \ + -e 's/rs\.NewResourceServerJWTProfile(/rs.NewResourceServerJWTProfile(context.TODO(), /g' +``` + +#### Introspect + +`Introspect` is now generic and requires a type argument for the returned introspection response. For most use cases `*oidc.IntrospectionResponse` can be used as type argument. Any other response type if type-safe access to [custom claims](https://pkg.go.dev/github.com/zitadel/oidc/v3/pkg/client/rs#example-Introspect-Custom) is required. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/rs\.Introspect(/rs.Introspect[*oidc.IntrospectionResponse](/g' +``` + +### client/tokenexchange + +The `TokenExchanger` constructor functions `NewTokenExchanger` and `NewTokenExchangerClientCredentials` now take a context as first argument. +As well as the `ExchangeToken` function. + +```bash +find . -type f -name '*.go' | xargs sed -i \ + -e 's/tokenexchange\.NewTokenExchanger(/tokenexchange.NewTokenExchanger(context.TODO(), /g' \ + -e 's/tokenexchange\.NewTokenExchangerClientCredentials(/tokenexchange.NewTokenExchangerClientCredentials(context.TODO(), /g' \ + -e 's/tokenexchange\.ExchangeToken(/tokenexchange.ExchangeToken(context.TODO(), /g' +``` + +### oidc + +#### SpaceDelimitedArray + +The `SpaceDelimitedArray` type's `Encode()` function has been renamed to `String()` so it implements the `fmt.Stringer` interface. If the `Encode` method was called by a package consumer, it should be changed manually. + +#### Verifier + +The `Verifier` interface as been changed into a struct type. The struct type is aliased in the `op` and `rp` packages for the specific token use cases. See the relevant section above. + +### Full script + +For the courageous this is the full `sed` script which combines all the steps described above. +It should migrate most of the code in a repository to a more-or-less compilable state, +using defaults such as `context.TODO()` where possible. + +Warnings: +- Again, this is written for **GNU sed** not the posix variant. +- Assumes imports that use the package names, not aliases. +- Do this on a project with version control (eg Git), that allows you to rollback if things went wrong. +- The script has been tested on the [ZITADEL](https://github.com/zitadel/zitadel) project, but we do not use all affected symbols. Parts of the script are mere guesswork. + +```bash +go get -u github.com/zitadel/oidc/v3 +find . -type f -name '*.go' | xargs sed -i \ + -e 's/github\.com\/zitadel\/oidc\/v2/github.com\/zitadel\/oidc\/v3/g' \ + -e 's/gopkg.in\/square\/go-jose\.v2/github.com\/go-jose\/go-jose\/v3/g' \ + -e 's/\bAuthRequestError(w, r, authReq, err, authorizer.Encoder())/AuthRequestError(w, r, authReq, err, authorizer)/g' \ + -e 's/\bop\.AccessTokenVerifier\b/*op.AccessTokenVerifier/g' \ + -e 's/\bop\.JWTProfileVerifier\b/*op.JWTProfileVerifier/g' \ + -e 's/\bop\.IDTokenHintVerifier\b/*op.IDTokenHintVerifier/g' \ + -e 's/AuthorizationEndpoint() Endpoint/AuthorizationEndpoint() *Endpoint/g' \ + -e 's/TokenEndpoint() Endpoint/TokenEndpoint() *Endpoint/g' \ + -e 's/IntrospectionEndpoint() Endpoint/IntrospectionEndpoint() *Endpoint/g' \ + -e 's/UserinfoEndpoint() Endpoint/UserinfoEndpoint() *Endpoint/g' \ + -e 's/RevocationEndpoint() Endpoint/RevocationEndpoint() *Endpoint/g' \ + -e 's/EndSessionEndpoint() Endpoint/EndSessionEndpoint() *Endpoint/g' \ + -e 's/KeysEndpoint() Endpoint/KeysEndpoint() *Endpoint/g' \ + -e 's/DeviceAuthorizationEndpoint() Endpoint/DeviceAuthorizationEndpoint() *Endpoint/g' \ + -e 's/op\.CreateDiscoveryConfig(/op.CreateDiscoveryConfig(context.TODO(), /g' \ + -e 's/op\.AuthorizeCodeChallenge(tokenReq/op.AuthorizeCodeChallenge(tokenReq.CodeVerifier/g' \ + -e 's/client\.Discover(/client.Discover(context.TODO(), /g' \ + -e 's/client\.CallTokenEndpoint(/client.CallTokenEndpoint(context.TODO(), /g' \ + -e 's/client\.CallEndSessionEndpoint(/client.CallEndSessionEndpoint(context.TODO(), /g' \ + -e 's/client\.CallRevokeEndpoint(/client.CallRevokeEndpoint(context.TODO(), /g' \ + -e 's/client\.CallTokenExchangeEndpoint(/client.CallTokenExchangeEndpoint(context.TODO(), /g' \ + -e 's/client\.CallDeviceAuthorizationEndpoint(/client.CallDeviceAuthorizationEndpoint(context.TODO(), /g' \ + -e 's/client\.JWTProfileExchange(/client.JWTProfileExchange(context.TODO(), /g' \ + -e 's/profile\.NewJWTProfileTokenSource(/profile.NewJWTProfileTokenSource(context.TODO(), /g' \ + -e 's/profile\.NewJWTProfileTokenSourceFromKeyFileData(/profile.NewJWTProfileTokenSourceFromKeyFileData(context.TODO(), /g' \ + -e 's/profile\.NewJWTProfileTokenSourceFromKeyFile(/profile.NewJWTProfileTokenSourceFromKeyFile(context.TODO(), /g' \ + -e 's/rp\.NewRelyingPartyOIDC(/rp.NewRelyingPartyOIDC(context.TODO(), /g' \ + -e 's/rp\.EndSession(/rp.EndSession(context.TODO(), /g' \ + -e 's/rp\.RevokeToken(/rp.RevokeToken(context.TODO(), /g' \ + -e 's/rp\.DeviceAuthorization(/rp.DeviceAuthorization(context.TODO(), /g' \ + -e 's/rp\.RefreshAccessToken(/rp.RefreshTokens[*oidc.IDTokenClaims](context.TODO(), /g' \ + -e 's/rp\.Userinfo(/rp.Userinfo[*oidc.UserInfo](context.TODO(), /g' \ + -e 's/\brp\.IDTokenVerifier\b/*rp.IDTokenVerifier/g' \ + -e 's/rs\.NewResourceServerClientCredentials(/rs.NewResourceServerClientCredentials(context.TODO(), /g' \ + -e 's/rs\.NewResourceServerJWTProfile(/rs.NewResourceServerJWTProfile(context.TODO(), /g' \ + -e 's/rs\.Introspect(/rs.Introspect[*oidc.IntrospectionResponse](/g' \ + -e 's/tokenexchange\.NewTokenExchanger(/tokenexchange.NewTokenExchanger(context.TODO(), /g' \ + -e 's/tokenexchange\.NewTokenExchangerClientCredentials(/tokenexchange.NewTokenExchangerClientCredentials(context.TODO(), /g' \ + -e 's/tokenexchange\.ExchangeToken(/tokenexchange.ExchangeToken(context.TODO(), /g' +go mod tidy +``` \ No newline at end of file From d18aba8cb336c27a7ddc5146ab97f1afe730ede5 Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Wed, 6 Mar 2024 18:38:37 +0100 Subject: [PATCH 045/185] feat(rp): extend tracing --- pkg/op/auth_request.go | 32 ++++++++++++++++--- pkg/op/client.go | 13 +++++++- pkg/op/device.go | 14 +++++++++ pkg/op/discovery.go | 3 ++ pkg/op/keys.go | 4 +++ pkg/op/server_http.go | 12 ++++++- pkg/op/server_legacy.go | 54 ++++++++++++++++++++++++++++++++ pkg/op/session.go | 7 +++++ pkg/op/token.go | 3 ++ pkg/op/token_exchange.go | 14 +++++++++ pkg/op/token_intospection.go | 4 +++ pkg/op/token_refresh.go | 3 ++ pkg/op/token_request.go | 7 +++++ pkg/op/token_revocation.go | 11 +++++++ pkg/op/userinfo.go | 15 +++++++++ pkg/op/verifier_access_token.go | 3 ++ pkg/op/verifier_id_token_hint.go | 3 ++ pkg/op/verifier_jwt_profile.go | 3 ++ 18 files changed, 198 insertions(+), 7 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 18d8826..435e3f4 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -70,12 +70,16 @@ func authorizeCallbackHandler(authorizer Authorizer) func(http.ResponseWriter, * // Authorize handles the authorization request, including // parsing, validating, storing and finally redirecting to the login handler func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { + ctx, span := tracer.Start(r.Context(), "Authorize") + r = r.WithContext(ctx) + defer span.End() + authReq, err := ParseAuthorizeRequest(r, authorizer.Decoder()) if err != nil { AuthRequestError(w, r, nil, err, authorizer) return } - ctx := r.Context() + ctx = r.Context() if authReq.RequestParam != "" && authorizer.RequestObjectSupported() { err = ParseRequestObject(ctx, authReq, authorizer.Storage(), IssuerFromContext(ctx)) if err != nil { @@ -210,6 +214,9 @@ func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oi // ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error) { + ctx, span := tracer.Start(ctx, "ValidateAuthRequest") + defer span.End() + authReq.MaxAge, err = ValidateAuthReqPrompt(authReq.Prompt, authReq.MaxAge) if err != nil { return "", err @@ -310,7 +317,7 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res return checkURIAgainstRedirects(client, uri) } if client.ApplicationType() == ApplicationTypeNative { - return validateAuthReqRedirectURINative(client, uri, responseType) + return validateAuthReqRedirectURINative(client, uri) } if err := checkURIAgainstRedirects(client, uri); err != nil { return err @@ -330,7 +337,7 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res } // ValidateAuthReqRedirectURINative validates the passed redirect_uri and response_type to the registered uris and client type -func validateAuthReqRedirectURINative(client Client, uri string, responseType oidc.ResponseType) error { +func validateAuthReqRedirectURINative(client Client, uri string) error { parsedURL, isLoopback := HTTPLoopbackOrLocalhost(uri) isCustomSchema := !strings.HasPrefix(uri, "http://") if err := checkURIAgainstRedirects(client, uri); err == nil { @@ -362,8 +369,8 @@ func equalURI(url1, url2 *url.URL) bool { return url1.Path == url2.Path && url1.RawQuery == url2.RawQuery } -func HTTPLoopbackOrLocalhost(rawurl string) (*url.URL, bool) { - parsedURL, err := url.Parse(rawurl) +func HTTPLoopbackOrLocalhost(rawURL string) (*url.URL, bool) { + parsedURL, err := url.Parse(rawURL) if err != nil { return nil, false } @@ -409,6 +416,10 @@ func RedirectToLogin(authReqID string, client Client, w http.ResponseWriter, r * // AuthorizeCallback handles the callback after authentication in the Login UI func AuthorizeCallback(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { + ctx, span := tracer.Start(r.Context(), "AuthorizeCallback") + r = r.WithContext(ctx) + defer span.End() + id, err := ParseAuthorizeCallbackRequest(r) if err != nil { AuthRequestError(w, r, nil, err, authorizer) @@ -441,6 +452,10 @@ func ParseAuthorizeCallbackRequest(r *http.Request) (id string, err error) { // AuthResponse creates the successful authentication response (either code or tokens) func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWriter, r *http.Request) { + ctx, span := tracer.Start(r.Context(), "ValidateAuthRequest") + r = r.WithContext(ctx) + defer span.End() + client, err := authorizer.Storage().GetClientByClientID(r.Context(), authReq.GetClientID()) if err != nil { AuthRequestError(w, r, authReq, err, authorizer) @@ -455,6 +470,10 @@ func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWri // AuthResponseCode creates the successful code authentication response func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer) { + ctx, span := tracer.Start(r.Context(), "AuthResponseCode") + r = r.WithContext(ctx) + defer span.End() + code, err := CreateAuthRequestCode(r.Context(), authReq, authorizer.Storage(), authorizer.Crypto()) if err != nil { AuthRequestError(w, r, authReq, err, authorizer) @@ -519,6 +538,9 @@ func AuthResponseToken(w http.ResponseWriter, r *http.Request, authReq AuthReque // CreateAuthRequestCode creates and stores a code for the auth code response func CreateAuthRequestCode(ctx context.Context, authReq AuthRequest, storage Storage, crypto Crypto) (string, error) { + ctx, span := tracer.Start(ctx, "CreateAuthRequestCode") + defer span.End() + code, err := BuildAuthRequestCode(authReq, crypto) if err != nil { return "", err diff --git a/pkg/op/client.go b/pkg/op/client.go index 0574afa..e0a0443 100644 --- a/pkg/op/client.go +++ b/pkg/op/client.go @@ -92,6 +92,9 @@ type ClientJWTProfile interface { } func ClientJWTAuth(ctx context.Context, ca oidc.ClientAssertionParams, verifier ClientJWTProfile) (clientID string, err error) { + ctx, span := tracer.Start(ctx, "ClientJWTAuth") + defer span.End() + if ca.ClientAssertion == "" { return "", oidc.ErrInvalidClient().WithParent(ErrNoClientCredentials) } @@ -104,6 +107,10 @@ func ClientJWTAuth(ctx context.Context, ca oidc.ClientAssertionParams, verifier } func ClientBasicAuth(r *http.Request, storage Storage) (clientID string, err error) { + ctx, span := tracer.Start(r.Context(), "ClientBasicAuth") + r = r.WithContext(ctx) + defer span.End() + clientID, clientSecret, ok := r.BasicAuth() if !ok { return "", oidc.ErrInvalidClient().WithParent(ErrNoClientCredentials) @@ -146,6 +153,10 @@ type clientData struct { // If no client id can be obtained by any method, oidc.ErrInvalidClient // is returned with ErrMissingClientID wrapped in it. func ClientIDFromRequest(r *http.Request, p ClientProvider) (clientID string, authenticated bool, err error) { + ctx, span := tracer.Start(r.Context(), "ClientIDFromRequest") + r = r.WithContext(ctx) + defer span.End() + err = r.ParseForm() if err != nil { return "", false, oidc.ErrInvalidRequest().WithDescription("cannot parse form").WithParent(err) @@ -171,7 +182,7 @@ func ClientIDFromRequest(r *http.Request, p ClientProvider) (clientID string, au } // if the client did not send a Basic Auth Header, ignore the `ErrNoClientCredentials` // but return other errors immediately - if err != nil && !errors.Is(err, ErrNoClientCredentials) { + if !errors.Is(err, ErrNoClientCredentials) { return "", false, err } diff --git a/pkg/op/device.go b/pkg/op/device.go index 1b86d04..d08b4fd 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -64,6 +64,10 @@ func DeviceAuthorizationHandler(o OpenIDProvider) func(http.ResponseWriter, *htt } func DeviceAuthorization(w http.ResponseWriter, r *http.Request, o OpenIDProvider) error { + ctx, span := tracer.Start(r.Context(), "DeviceAuthorization") + r = r.WithContext(ctx) + defer span.End() + req, err := ParseDeviceCodeRequest(r, o) if err != nil { return err @@ -78,6 +82,9 @@ func DeviceAuthorization(w http.ResponseWriter, r *http.Request, o OpenIDProvide } func createDeviceAuthorization(ctx context.Context, req *oidc.DeviceAuthorizationRequest, clientID string, o OpenIDProvider) (*oidc.DeviceAuthorizationResponse, error) { + ctx, span := tracer.Start(ctx, "createDeviceAuthorization") + defer span.End() + storage, err := assertDeviceStorage(o.Storage()) if err != nil { return nil, err @@ -127,6 +134,10 @@ func createDeviceAuthorization(ctx context.Context, req *oidc.DeviceAuthorizatio } func ParseDeviceCodeRequest(r *http.Request, o OpenIDProvider) (*oidc.DeviceAuthorizationRequest, error) { + ctx, span := tracer.Start(r.Context(), "ParseDeviceCodeRequest") + r = r.WithContext(ctx) + defer span.End() + clientID, _, err := ClientIDFromRequest(r, o) if err != nil { return nil, err @@ -288,6 +299,9 @@ func (r *DeviceAuthorizationState) GetSubject() string { } func CheckDeviceAuthorizationState(ctx context.Context, clientID, deviceCode string, exchanger Exchanger) (*DeviceAuthorizationState, error) { + ctx, span := tracer.Start(ctx, "CheckDeviceAuthorization") + defer span.End() + storage, err := assertDeviceStorage(exchanger.Storage()) if err != nil { return nil, err diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index 6af1674..7b5ecbe 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -135,6 +135,9 @@ func SubjectTypes(c Configuration) []string { } func SigAlgorithms(ctx context.Context, storage DiscoverStorage) []string { + ctx, span := tracer.Start(ctx, "SigAlgorithms") + defer span.End() + algorithms, err := storage.SignatureAlgorithms(ctx) if err != nil { return nil diff --git a/pkg/op/keys.go b/pkg/op/keys.go index fe111f0..d55c8d1 100644 --- a/pkg/op/keys.go +++ b/pkg/op/keys.go @@ -20,6 +20,10 @@ func keysHandler(k KeyProvider) func(http.ResponseWriter, *http.Request) { } func Keys(w http.ResponseWriter, r *http.Request, k KeyProvider) { + ctx, span := tracer.Start(r.Context(), "Keys") + r = r.WithContext(ctx) + defer span.End() + keySet, err := k.KeySet(r.Context()) if err != nil { httphelper.MarshalJSONWithStatus(w, err, http.StatusInternalServerError) diff --git a/pkg/op/server_http.go b/pkg/op/server_http.go index 0a5e469..725dd64 100644 --- a/pkg/op/server_http.go +++ b/pkg/op/server_http.go @@ -124,7 +124,13 @@ func (s *webServer) createRouter() { func (s *webServer) endpointRoute(e *Endpoint, hf http.HandlerFunc) { if e != nil { - s.router.HandleFunc(e.Relative(), hf) + traceHandler := func(w http.ResponseWriter, r *http.Request) { + ctx, span := tracer.Start(r.Context(), e.Relative()) + r = r.WithContext(ctx) + hf(w, r) + defer span.End() + } + s.router.HandleFunc(e.Relative(), traceHandler) s.logger.Info("registered route", "endpoint", e.Relative()) } } @@ -133,6 +139,10 @@ type clientHandler func(w http.ResponseWriter, r *http.Request, client Client) func (s *webServer) withClient(handler clientHandler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + ctx, span := tracer.Start(r.Context(), r.URL.Path) + defer span.End() + r = r.WithContext(ctx) + client, err := s.verifyRequestClient(r) if err != nil { WriteError(w, r, err, s.getLogger(r.Context())) diff --git a/pkg/op/server_legacy.go b/pkg/op/server_legacy.go index f99d15d..6b6d4b3 100644 --- a/pkg/op/server_legacy.go +++ b/pkg/op/server_legacy.go @@ -79,6 +79,9 @@ func (s *LegacyServer) Endpoints() Endpoints { // AuthCallbackURL builds the url for the redirect (with the requestID) after a successful login func (s *LegacyServer) AuthCallbackURL() func(context.Context, string) string { return func(ctx context.Context, requestID string) string { + ctx, span := tracer.Start(ctx, "LegacyServer.AuthCallbackURL") + defer span.End() + return s.endpoints.Authorization.Absolute(IssuerFromContext(ctx)) + authCallbackPathSuffix + "?id=" + requestID } } @@ -98,12 +101,18 @@ func (s *LegacyServer) Ready(ctx context.Context, r *Request[struct{}]) (*Respon } func (s *LegacyServer) Discovery(ctx context.Context, r *Request[struct{}]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.Discovery") + defer span.End() + return NewResponse( createDiscoveryConfigV2(ctx, s.provider, s.provider.Storage(), &s.endpoints), ), nil } func (s *LegacyServer) Keys(ctx context.Context, r *Request[struct{}]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.Keys") + defer span.End() + keys, err := s.provider.Storage().KeySet(ctx) if err != nil { return nil, AsStatusError(err, http.StatusInternalServerError) @@ -117,6 +126,9 @@ var ( ) func (s *LegacyServer) VerifyAuthRequest(ctx context.Context, r *Request[oidc.AuthRequest]) (*ClientRequest[oidc.AuthRequest], error) { + ctx, span := tracer.Start(ctx, "LegacyServer.VerifyAuthRequest") + defer span.End() + if r.Data.RequestParam != "" { if !s.provider.RequestObjectSupported() { return nil, oidc.ErrRequestNotSupported() @@ -141,6 +153,9 @@ func (s *LegacyServer) VerifyAuthRequest(ctx context.Context, r *Request[oidc.Au } func (s *LegacyServer) Authorize(ctx context.Context, r *ClientRequest[oidc.AuthRequest]) (_ *Redirect, err error) { + ctx, span := tracer.Start(ctx, "LegacyServer.Authorize") + defer span.End() + userID, err := ValidateAuthReqIDTokenHint(ctx, r.Data.IDTokenHint, s.provider.IDTokenHintVerifier(ctx)) if err != nil { return nil, err @@ -153,6 +168,9 @@ func (s *LegacyServer) Authorize(ctx context.Context, r *ClientRequest[oidc.Auth } func (s *LegacyServer) DeviceAuthorization(ctx context.Context, r *ClientRequest[oidc.DeviceAuthorizationRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.DeviceAuthorization") + defer span.End() + response, err := createDeviceAuthorization(ctx, r.Data, r.Client.GetID(), s.provider) if err != nil { return nil, AsStatusError(err, http.StatusInternalServerError) @@ -161,6 +179,9 @@ func (s *LegacyServer) DeviceAuthorization(ctx context.Context, r *ClientRequest } func (s *LegacyServer) VerifyClient(ctx context.Context, r *Request[ClientCredentials]) (Client, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.VerifyClient") + defer span.End() + if oidc.GrantType(r.Form.Get("grant_type")) == oidc.GrantTypeClientCredentials { storage, ok := s.provider.Storage().(ClientCredentialsStorage) if !ok { @@ -201,6 +222,9 @@ func (s *LegacyServer) VerifyClient(ctx context.Context, r *Request[ClientCreden } func (s *LegacyServer) CodeExchange(ctx context.Context, r *ClientRequest[oidc.AccessTokenRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.CodeExchange") + defer span.End() + authReq, err := AuthRequestByCode(ctx, s.provider.Storage(), r.Data.Code) if err != nil { return nil, err @@ -221,6 +245,9 @@ func (s *LegacyServer) CodeExchange(ctx context.Context, r *ClientRequest[oidc.A } func (s *LegacyServer) RefreshToken(ctx context.Context, r *ClientRequest[oidc.RefreshTokenRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.RefreshToken") + defer span.End() + if !s.provider.GrantTypeRefreshTokenSupported() { return nil, unimplementedGrantError(oidc.GrantTypeRefreshToken) } @@ -242,6 +269,9 @@ func (s *LegacyServer) RefreshToken(ctx context.Context, r *ClientRequest[oidc.R } func (s *LegacyServer) JWTProfile(ctx context.Context, r *Request[oidc.JWTProfileGrantRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.JWTProfile") + defer span.End() + exchanger, ok := s.provider.(JWTAuthorizationGrantExchanger) if !ok { return nil, unimplementedGrantError(oidc.GrantTypeBearer) @@ -263,6 +293,9 @@ func (s *LegacyServer) JWTProfile(ctx context.Context, r *Request[oidc.JWTProfil } func (s *LegacyServer) TokenExchange(ctx context.Context, r *ClientRequest[oidc.TokenExchangeRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.TokenExchange") + defer span.End() + if !s.provider.GrantTypeTokenExchangeSupported() { return nil, unimplementedGrantError(oidc.GrantTypeTokenExchange) } @@ -278,6 +311,9 @@ func (s *LegacyServer) TokenExchange(ctx context.Context, r *ClientRequest[oidc. } func (s *LegacyServer) ClientCredentialsExchange(ctx context.Context, r *ClientRequest[oidc.ClientCredentialsRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.ClientCredentialsExchange") + defer span.End() + storage, ok := s.provider.Storage().(ClientCredentialsStorage) if !ok { return nil, unimplementedGrantError(oidc.GrantTypeClientCredentials) @@ -294,6 +330,9 @@ func (s *LegacyServer) ClientCredentialsExchange(ctx context.Context, r *ClientR } func (s *LegacyServer) DeviceToken(ctx context.Context, r *ClientRequest[oidc.DeviceAccessTokenRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.DeviceToken") + defer span.End() + if !s.provider.GrantTypeDeviceCodeSupported() { return nil, unimplementedGrantError(oidc.GrantTypeDeviceCode) } @@ -314,6 +353,9 @@ func (s *LegacyServer) DeviceToken(ctx context.Context, r *ClientRequest[oidc.De } func (s *LegacyServer) authenticateResourceClient(ctx context.Context, cc *ClientCredentials) (string, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.authenticateResourceClient") + defer span.End() + if cc.ClientAssertion != "" { if jp, ok := s.provider.(ClientJWTProfile); ok { return ClientJWTAuth(ctx, oidc.ClientAssertionParams{ClientAssertion: cc.ClientAssertion}, jp) @@ -327,6 +369,9 @@ func (s *LegacyServer) authenticateResourceClient(ctx context.Context, cc *Clien } func (s *LegacyServer) Introspect(ctx context.Context, r *Request[IntrospectionRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.Introspect") + defer span.End() + clientID, err := s.authenticateResourceClient(ctx, r.Data.ClientCredentials) if err != nil { return nil, err @@ -345,6 +390,9 @@ func (s *LegacyServer) Introspect(ctx context.Context, r *Request[IntrospectionR } func (s *LegacyServer) UserInfo(ctx context.Context, r *Request[oidc.UserInfoRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.UserInfo") + defer span.End() + tokenID, subject, ok := getTokenIDAndSubject(ctx, s.provider, r.Data.AccessToken) if !ok { return nil, NewStatusError(oidc.ErrAccessDenied().WithDescription("access token invalid"), http.StatusUnauthorized) @@ -358,6 +406,9 @@ func (s *LegacyServer) UserInfo(ctx context.Context, r *Request[oidc.UserInfoReq } func (s *LegacyServer) Revocation(ctx context.Context, r *ClientRequest[oidc.RevocationRequest]) (*Response, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.Revocation") + defer span.End() + var subject string doDecrypt := true if r.Data.TokenTypeHint != "access_token" { @@ -387,6 +438,9 @@ func (s *LegacyServer) Revocation(ctx context.Context, r *ClientRequest[oidc.Rev } func (s *LegacyServer) EndSession(ctx context.Context, r *Request[oidc.EndSessionRequest]) (*Redirect, error) { + ctx, span := tracer.Start(ctx, "LegacyServer.EndSession") + defer span.End() + session, err := ValidateEndSessionRequest(ctx, r.Data, s.provider) if err != nil { return nil, err diff --git a/pkg/op/session.go b/pkg/op/session.go index 6af7d7c..8ac530d 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -27,6 +27,10 @@ func endSessionHandler(ender SessionEnder) func(http.ResponseWriter, *http.Reque } func EndSession(w http.ResponseWriter, r *http.Request, ender SessionEnder) { + ctx, span := tracer.Start(r.Context(), "EndSession") + defer span.End() + r = r.WithContext(ctx) + req, err := ParseEndSessionRequest(r, ender.Decoder()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -64,6 +68,9 @@ func ParseEndSessionRequest(r *http.Request, decoder httphelper.Decoder) (*oidc. } func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, ender SessionEnder) (*EndSessionRequest, error) { + ctx, span := tracer.Start(ctx, "ValidateEndSessionRequest") + defer span.End() + session := &EndSessionRequest{ RedirectURI: ender.DefaultLogoutRedirectURI(), } diff --git a/pkg/op/token.go b/pkg/op/token.go index 83889f0..19edcce 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -69,6 +69,9 @@ func CreateTokenResponse(ctx context.Context, request IDTokenRequest, client Cli } func createTokens(ctx context.Context, tokenRequest TokenRequest, storage Storage, refreshToken string, client AccessTokenClient) (id, newRefreshToken string, exp time.Time, err error) { + ctx, span := tracer.Start(ctx, "createTokens") + defer span.End() + if needsRefreshToken(tokenRequest, client) { return storage.CreateAccessAndRefreshTokens(ctx, tokenRequest, refreshToken) } diff --git a/pkg/op/token_exchange.go b/pkg/op/token_exchange.go index db3e468..fcb4468 100644 --- a/pkg/op/token_exchange.go +++ b/pkg/op/token_exchange.go @@ -193,6 +193,9 @@ func ValidateTokenExchangeRequest( clientID, clientSecret string, exchanger Exchanger, ) (TokenExchangeRequest, Client, error) { + ctx, span := tracer.Start(ctx, "ValidateTokenExchangeRequest") + defer span.End() + if oidcTokenExchangeRequest.SubjectToken == "" { return nil, nil, oidc.ErrInvalidRequest().WithDescription("subject_token missing") } @@ -231,6 +234,9 @@ func CreateTokenExchangeRequest( client Client, exchanger Exchanger, ) (TokenExchangeRequest, error) { + ctx, span := tracer.Start(ctx, "CreateTokenExchangeRequest") + defer span.End() + teStorage, ok := exchanger.Storage().(TokenExchangeStorage) if !ok { return nil, unimplementedGrantError(oidc.GrantTypeTokenExchange) @@ -294,6 +300,9 @@ func GetTokenIDAndSubjectFromToken( tokenType oidc.TokenType, isActor bool, ) (tokenIDOrToken, subject string, claims map[string]any, ok bool) { + ctx, span := tracer.Start(ctx, "GetTokenIDAndSubjectFromToken") + defer span.End() + switch tokenType { case oidc.AccessTokenType: var accessTokenClaims *oidc.AccessTokenClaims @@ -341,6 +350,9 @@ func GetTokenIDAndSubjectFromToken( // AuthorizeTokenExchangeClient authorizes a client by validating the client_id and client_secret func AuthorizeTokenExchangeClient(ctx context.Context, clientID, clientSecret string, exchanger Exchanger) (client Client, err error) { + ctx, span := tracer.Start(ctx, "AuthorizeTokenExchangeClient") + defer span.End() + if err := AuthorizeClientIDSecret(ctx, clientID, clientSecret, exchanger.Storage()); err != nil { return nil, err } @@ -359,6 +371,8 @@ func CreateTokenExchangeResponse( client Client, creator TokenCreator, ) (_ *oidc.TokenExchangeResponse, err error) { + ctx, span := tracer.Start(ctx, "CreateTokenExchangeResponse") + defer span.End() var ( token, refreshToken, tokenType string diff --git a/pkg/op/token_intospection.go b/pkg/op/token_intospection.go index 9c45ef8..29234e1 100644 --- a/pkg/op/token_intospection.go +++ b/pkg/op/token_intospection.go @@ -28,6 +28,10 @@ func introspectionHandler(introspector Introspector) func(http.ResponseWriter, * } func Introspect(w http.ResponseWriter, r *http.Request, introspector Introspector) { + ctx, span := tracer.Start(r.Context(), "Introspect") + defer span.End() + r = r.WithContext(ctx) + response := new(oidc.IntrospectionResponse) token, clientID, err := ParseTokenIntrospectionRequest(r, introspector) if err != nil { diff --git a/pkg/op/token_refresh.go b/pkg/op/token_refresh.go index afca3bf..92ef476 100644 --- a/pkg/op/token_refresh.go +++ b/pkg/op/token_refresh.go @@ -141,6 +141,9 @@ func AuthorizeRefreshClient(ctx context.Context, tokenReq *oidc.RefreshTokenRequ // RefreshTokenRequestByRefreshToken returns the RefreshTokenRequest (data representing the original auth request) // corresponding to the refresh_token from Storage or an error func RefreshTokenRequestByRefreshToken(ctx context.Context, storage Storage, refreshToken string) (RefreshTokenRequest, error) { + ctx, span := tracer.Start(ctx, "RefreshTokenRequestByRefreshToken") + defer span.End() + request, err := storage.TokenRequestByRefreshToken(ctx, refreshToken) if err != nil { return nil, oidc.ErrInvalidGrant().WithParent(err) diff --git a/pkg/op/token_request.go b/pkg/op/token_request.go index 2006725..85e2270 100644 --- a/pkg/op/token_request.go +++ b/pkg/op/token_request.go @@ -37,6 +37,10 @@ func tokenHandler(exchanger Exchanger) func(w http.ResponseWriter, r *http.Reque // Exchange performs a token exchange appropriate for the grant type func Exchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { + ctx, span := tracer.Start(r.Context(), "Exchange") + r = r.WithContext(ctx) + defer span.End() + grantType := r.FormValue("grant_type") switch grantType { case string(oidc.GrantTypeCode): @@ -115,6 +119,9 @@ func ParseAuthenticatedTokenRequest(r *http.Request, decoder httphelper.Decoder, // AuthorizeClientIDSecret authorizes a client by validating the client_id and client_secret (Basic Auth and POST) func AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string, storage Storage) error { + ctx, span := tracer.Start(ctx, "AuthorizeClientIDSecret") + defer span.End() + err := storage.AuthorizeClientIDSecret(ctx, clientID, clientSecret) if err != nil { return oidc.ErrInvalidClient().WithDescription("invalid client_id / client_secret").WithParent(err) diff --git a/pkg/op/token_revocation.go b/pkg/op/token_revocation.go index d19c7f7..537b164 100644 --- a/pkg/op/token_revocation.go +++ b/pkg/op/token_revocation.go @@ -32,6 +32,10 @@ func revocationHandler(revoker Revoker) func(http.ResponseWriter, *http.Request) } func Revoke(w http.ResponseWriter, r *http.Request, revoker Revoker) { + ctx, span := tracer.Start(r.Context(), "Revoke") + r = r.WithContext(ctx) + defer span.End() + token, tokenTypeHint, clientID, err := ParseTokenRevocationRequest(r, revoker) if err != nil { RevocationRequestError(w, r, err) @@ -68,6 +72,10 @@ func Revoke(w http.ResponseWriter, r *http.Request, revoker Revoker) { } func ParseTokenRevocationRequest(r *http.Request, revoker Revoker) (token, tokenTypeHint, clientID string, err error) { + ctx, span := tracer.Start(r.Context(), "ParseTokenRevocationRequest") + r = r.WithContext(ctx) + defer span.End() + err = r.ParseForm() if err != nil { return "", "", "", oidc.ErrInvalidRequest().WithDescription("unable to parse request").WithParent(err) @@ -148,6 +156,9 @@ func RevocationError(err error) StatusError { } func getTokenIDAndSubjectForRevocation(ctx context.Context, userinfoProvider UserinfoProvider, accessToken string) (string, string, bool) { + ctx, span := tracer.Start(ctx, "getTokenIDAndSubjectFromRevocation") + defer span.End() + tokenIDSubject, err := userinfoProvider.Crypto().Decrypt(accessToken) if err == nil { splitToken := strings.Split(tokenIDSubject, ":") diff --git a/pkg/op/userinfo.go b/pkg/op/userinfo.go index 86205b5..4b8f398 100644 --- a/pkg/op/userinfo.go +++ b/pkg/op/userinfo.go @@ -24,6 +24,10 @@ func userinfoHandler(userinfoProvider UserinfoProvider) func(http.ResponseWriter } func Userinfo(w http.ResponseWriter, r *http.Request, userinfoProvider UserinfoProvider) { + ctx, span := tracer.Start(r.Context(), "Userinfo") + r = r.WithContext(ctx) + defer span.End() + accessToken, err := ParseUserinfoRequest(r, userinfoProvider.Decoder()) if err != nil { http.Error(w, "access token missing", http.StatusUnauthorized) @@ -44,6 +48,10 @@ func Userinfo(w http.ResponseWriter, r *http.Request, userinfoProvider UserinfoP } func ParseUserinfoRequest(r *http.Request, decoder httphelper.Decoder) (string, error) { + ctx, span := tracer.Start(r.Context(), "ParseUserinfoRequest") + r = r.WithContext(ctx) + defer span.End() + accessToken, err := getAccessToken(r) if err == nil { return accessToken, nil @@ -61,6 +69,10 @@ func ParseUserinfoRequest(r *http.Request, decoder httphelper.Decoder) (string, } func getAccessToken(r *http.Request) (string, error) { + ctx, span := tracer.Start(r.Context(), "RefreshTokens") + r = r.WithContext(ctx) + defer span.End() + authHeader := r.Header.Get("authorization") if authHeader == "" { return "", errors.New("no auth header") @@ -73,6 +85,9 @@ func getAccessToken(r *http.Request) (string, error) { } func getTokenIDAndSubject(ctx context.Context, userinfoProvider UserinfoProvider, accessToken string) (string, string, bool) { + ctx, span := tracer.Start(ctx, "getTokenIDAndSubject") + defer span.End() + tokenIDSubject, err := userinfoProvider.Crypto().Decrypt(accessToken) if err == nil { splitToken := strings.Split(tokenIDSubject, ":") diff --git a/pkg/op/verifier_access_token.go b/pkg/op/verifier_access_token.go index 120bfa7..6ac29f2 100644 --- a/pkg/op/verifier_access_token.go +++ b/pkg/op/verifier_access_token.go @@ -30,6 +30,9 @@ func NewAccessTokenVerifier(issuer string, keySet oidc.KeySet, opts ...AccessTok // VerifyAccessToken validates the access token (issuer, signature and expiration). func VerifyAccessToken[C oidc.Claims](ctx context.Context, token string, v *AccessTokenVerifier) (claims C, err error) { + ctx, span := tracer.Start(ctx, "VerifyAccessToken") + defer span.End() + var nilClaims C decrypted, err := oidc.DecryptToken(token) diff --git a/pkg/op/verifier_id_token_hint.go b/pkg/op/verifier_id_token_hint.go index b5ec72e..331c64c 100644 --- a/pkg/op/verifier_id_token_hint.go +++ b/pkg/op/verifier_id_token_hint.go @@ -46,6 +46,9 @@ func (e IDTokenHintExpiredError) Is(err error) bool { // is returned of type [IDTokenHintExpiredError]. In that case the caller can choose to still // trust the token for cases like logout, as signature and other verifications succeeded. func VerifyIDTokenHint[C oidc.Claims](ctx context.Context, token string, v *IDTokenHintVerifier) (claims C, err error) { + ctx, span := tracer.Start(ctx, "VerifyIDTokenHint") + defer span.End() + var nilClaims C decrypted, err := oidc.DecryptToken(token) diff --git a/pkg/op/verifier_jwt_profile.go b/pkg/op/verifier_jwt_profile.go index 38b8ee4..ced99ad 100644 --- a/pkg/op/verifier_jwt_profile.go +++ b/pkg/op/verifier_jwt_profile.go @@ -118,6 +118,9 @@ type jwtProfileKeySet struct { // VerifySignature implements oidc.KeySet by getting the public key from Storage implementation func (k *jwtProfileKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error) { + ctx, span := tracer.Start(ctx, "VerifySignature") + defer span.End() + keyID, _ := oidc.GetKeyIDAndAlg(jws) key, err := k.storage.GetKeyByIDAndClientID(ctx, keyID, k.clientID) if err != nil { From bdcccc3303a96cdf5d8e410abc77f2a09c64e1a1 Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Wed, 6 Mar 2024 18:39:27 +0100 Subject: [PATCH 046/185] feat(client): tracing in rp --- pkg/client/rp/device.go | 6 ++++++ pkg/client/rp/jwks.go | 15 ++++++++++++++ pkg/client/rp/relying_party.go | 37 ++++++++++++++++++++++++++++++++++ pkg/client/rp/verifier.go | 6 ++++++ pkg/op/op.go | 1 + 5 files changed, 65 insertions(+) diff --git a/pkg/client/rp/device.go b/pkg/client/rp/device.go index 02c647e..ec4dabe 100644 --- a/pkg/client/rp/device.go +++ b/pkg/client/rp/device.go @@ -33,6 +33,9 @@ func newDeviceClientCredentialsRequest(scopes []string, rp RelyingParty) (*oidc. // in RFC 8628, section 3.1 and 3.2: // https://www.rfc-editor.org/rfc/rfc8628#section-3.1 func DeviceAuthorization(ctx context.Context, scopes []string, rp RelyingParty, authFn any) (*oidc.DeviceAuthorizationResponse, error) { + ctx, span := tracer.Start(ctx, "DeviceAuthorization") + defer span.End() + ctx = logCtxWithRPData(ctx, rp, "function", "DeviceAuthorization") req, err := newDeviceClientCredentialsRequest(scopes, rp) if err != nil { @@ -46,6 +49,9 @@ func DeviceAuthorization(ctx context.Context, scopes []string, rp RelyingParty, // by means of polling as defined in RFC, section 3.3 and 3.4: // https://www.rfc-editor.org/rfc/rfc8628#section-3.4 func DeviceAccessToken(ctx context.Context, deviceCode string, interval time.Duration, rp RelyingParty) (resp *oidc.AccessTokenResponse, err error) { + ctx, span := tracer.Start(ctx, "DeviceAccessToken") + defer span.End() + ctx = logCtxWithRPData(ctx, rp, "function", "DeviceAccessToken") req := &client.DeviceAccessTokenRequest{ DeviceAccessTokenRequest: oidc.DeviceAccessTokenRequest{ diff --git a/pkg/client/rp/jwks.go b/pkg/client/rp/jwks.go index 28aec9b..a3c1647 100644 --- a/pkg/client/rp/jwks.go +++ b/pkg/client/rp/jwks.go @@ -83,6 +83,9 @@ func (i *inflight) result() ([]jose.JSONWebKey, error) { } func (r *remoteKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { + ctx, span := tracer.Start(ctx, "VerifySignature") + defer span.End() + keyID, alg := oidc.GetKeyIDAndAlg(jws) if alg == "" { alg = r.defaultAlg @@ -135,6 +138,9 @@ func (r *remoteKeySet) exactMatch(jwkID, jwsID string) bool { } func (r *remoteKeySet) verifySignatureRemote(ctx context.Context, jws *jose.JSONWebSignature, keyID, alg string) ([]byte, error) { + ctx, span := tracer.Start(ctx, "verifySignatureRemote") + defer span.End() + keys, err := r.keysFromRemote(ctx) if err != nil { return nil, fmt.Errorf("unable to fetch key for signature validation: %w", err) @@ -159,6 +165,9 @@ func (r *remoteKeySet) keysFromCache() (keys []jose.JSONWebKey) { // keysFromRemote syncs the key set from the remote set, records the values in the // cache, and returns the key set. func (r *remoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, error) { + ctx, span := tracer.Start(ctx, "keysFromRemote") + defer span.End() + // Need to lock to inspect the inflight request field. r.mu.Lock() // If there's not a current inflight request, create one. @@ -182,6 +191,9 @@ func (r *remoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, e } func (r *remoteKeySet) updateKeys(ctx context.Context) { + ctx, span := tracer.Start(ctx, "updateKeys") + defer span.End() + // Sync keys and finish inflight when that's done. keys, err := r.fetchRemoteKeys(ctx) @@ -201,6 +213,9 @@ func (r *remoteKeySet) updateKeys(ctx context.Context) { } func (r *remoteKeySet) fetchRemoteKeys(ctx context.Context) ([]jose.JSONWebKey, error) { + ctx, span := tracer.Start(ctx, "fetchRemoteKeys") + defer span.End() + req, err := http.NewRequest("GET", r.jwksURL, nil) if err != nil { return nil, fmt.Errorf("oidc: can't create request: %v", err) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 74da71e..3022035 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -12,6 +12,8 @@ import ( "github.com/go-jose/go-jose/v3" "github.com/google/uuid" "github.com/zitadel/logging" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" "golang.org/x/oauth2" "golang.org/x/oauth2/clientcredentials" @@ -28,6 +30,12 @@ const ( var ErrUserInfoSubNotMatching = errors.New("sub from userinfo does not match the sub from the id_token") +var tracer trace.Tracer + +func init() { + tracer = otel.Tracer("github.com/zitadel/oidc/pkg/client/rp") +} + // RelyingParty declares the minimal interface for oidc clients type RelyingParty interface { // OAuthConfig returns the oauth2 Config @@ -428,6 +436,9 @@ func GenerateAndStoreCodeChallenge(w http.ResponseWriter, rp RelyingParty) (stri var ErrMissingIDToken = errors.New("id_token missing") func verifyTokenResponse[C oidc.IDClaims](ctx context.Context, token *oauth2.Token, rp RelyingParty) (*oidc.Tokens[C], error) { + ctx, span := tracer.Start(ctx, "verifyTokenResponse") + defer span.End() + if rp.IsOAuth2Only() { return &oidc.Tokens[C]{Token: token}, nil } @@ -445,6 +456,9 @@ func verifyTokenResponse[C oidc.IDClaims](ctx context.Context, token *oauth2.Tok // CodeExchange handles the oauth2 code exchange, extracting and validating the id_token // returning it parsed together with the oauth2 tokens (access, refresh) func CodeExchange[C oidc.IDClaims](ctx context.Context, code string, rp RelyingParty, opts ...CodeExchangeOpt) (tokens *oidc.Tokens[C], err error) { + ctx, codeExchangeSpan := tracer.Start(ctx, "CodeExchange") + defer codeExchangeSpan.End() + ctx = logCtxWithRPData(ctx, rp, "function", "CodeExchange") ctx = context.WithValue(ctx, oauth2.HTTPClient, rp.HttpClient()) codeOpts := make([]oauth2.AuthCodeOption, 0) @@ -452,10 +466,12 @@ func CodeExchange[C oidc.IDClaims](ctx context.Context, code string, rp RelyingP codeOpts = append(codeOpts, opt()...) } + ctx, oauthExchangeSpan := tracer.Start(ctx, "OAuthExchange") token, err := rp.OAuthConfig().Exchange(ctx, code, codeOpts...) if err != nil { return nil, err } + oauthExchangeSpan.End() return verifyTokenResponse[C](ctx, token, rp) } @@ -469,6 +485,9 @@ func CodeExchange[C oidc.IDClaims](ctx context.Context, code string, rp RelyingP // [RFC 6749, section 4.4]: https://datatracker.ietf.org/doc/html/rfc6749#section-4.4 func ClientCredentials(ctx context.Context, rp RelyingParty, endpointParams url.Values) (token *oauth2.Token, err error) { ctx = logCtxWithRPData(ctx, rp, "function", "ClientCredentials") + ctx, span := tracer.Start(ctx, "ClientCredentials") + defer span.End() + ctx = context.WithValue(ctx, oauth2.HTTPClient, rp.HttpClient()) config := clientcredentials.Config{ ClientID: rp.OAuthConfig().ClientID, @@ -489,6 +508,10 @@ type CodeExchangeCallback[C oidc.IDClaims] func(w http.ResponseWriter, r *http.R // Custom parameters can optionally be set to the token URL. func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp RelyingParty, urlParam ...URLParamOpt) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + ctx, span := tracer.Start(r.Context(), "CodeExchangeHandler") + r = r.WithContext(ctx) + defer span.End() + state, err := tryReadStateCookie(w, r, rp) if err != nil { unauthorizedError(w, r, "failed to get state: "+err.Error(), state, rp) @@ -540,6 +563,10 @@ type CodeExchangeUserinfoCallback[C oidc.IDClaims, U SubjectGetter] func(w http. // on success it will pass the userinfo into its callback function as well func UserinfoCallback[C oidc.IDClaims, U SubjectGetter](f CodeExchangeUserinfoCallback[C, U]) CodeExchangeCallback[C] { return func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[C], state string, rp RelyingParty) { + ctx, span := tracer.Start(r.Context(), "UserinfoCallback") + r = r.WithContext(ctx) + defer span.End() + info, err := Userinfo[U](r.Context(), tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.GetSubject(), rp) if err != nil { unauthorizedError(w, r, "userinfo failed: "+err.Error(), state, rp) @@ -558,6 +585,8 @@ func UserinfoCallback[C oidc.IDClaims, U SubjectGetter](f CodeExchangeUserinfoCa func Userinfo[U SubjectGetter](ctx context.Context, token, tokenType, subject string, rp RelyingParty) (userinfo U, err error) { var nilU U ctx = logCtxWithRPData(ctx, rp, "function", "Userinfo") + ctx, span := tracer.Start(ctx, "Userinfo") + defer span.End() req, err := http.NewRequestWithContext(ctx, http.MethodGet, rp.UserinfoEndpoint(), nil) if err != nil { @@ -716,6 +745,9 @@ type RefreshTokenRequest struct { // the IDToken and AccessToken will be verfied // and the IDToken and IDTokenClaims fields will be populated in the returned object. func RefreshTokens[C oidc.IDClaims](ctx context.Context, rp RelyingParty, refreshToken, clientAssertion, clientAssertionType string) (*oidc.Tokens[C], error) { + ctx, span := tracer.Start(ctx, "RefreshTokens") + defer span.End() + ctx = logCtxWithRPData(ctx, rp, "function", "RefreshTokens") request := RefreshTokenRequest{ RefreshToken: refreshToken, @@ -741,6 +773,9 @@ func RefreshTokens[C oidc.IDClaims](ctx context.Context, rp RelyingParty, refres func EndSession(ctx context.Context, rp RelyingParty, idToken, optionalRedirectURI, optionalState string) (*url.URL, error) { ctx = logCtxWithRPData(ctx, rp, "function", "EndSession") + ctx, span := tracer.Start(ctx, "RefreshTokens") + defer span.End() + request := oidc.EndSessionRequest{ IdTokenHint: idToken, ClientID: rp.OAuthConfig().ClientID, @@ -757,6 +792,8 @@ func EndSession(ctx context.Context, rp RelyingParty, idToken, optionalRedirectU // tokenTypeHint should be either "id_token" or "refresh_token". func RevokeToken(ctx context.Context, rp RelyingParty, token string, tokenTypeHint string) error { ctx = logCtxWithRPData(ctx, rp, "function", "RevokeToken") + ctx, span := tracer.Start(ctx, "RefreshTokens") + defer span.End() request := client.RevokeRequest{ Token: token, TokenTypeHint: tokenTypeHint, diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index adf8872..ebc10cc 100644 --- a/pkg/client/rp/verifier.go +++ b/pkg/client/rp/verifier.go @@ -12,6 +12,9 @@ import ( // VerifyTokens implement the Token Response Validation as defined in OIDC specification // https://openid.net/specs/openid-connect-core-1_0.html#TokenResponseValidation func VerifyTokens[C oidc.IDClaims](ctx context.Context, accessToken, idToken string, v *IDTokenVerifier) (claims C, err error) { + ctx, span := tracer.Start(ctx, "VerifyTokens") + defer span.End() + var nilClaims C claims, err = VerifyIDToken[C](ctx, idToken, v) @@ -27,6 +30,9 @@ func VerifyTokens[C oidc.IDClaims](ctx context.Context, accessToken, idToken str // VerifyIDToken validates the id token according to // https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation func VerifyIDToken[C oidc.Claims](ctx context.Context, token string, v *IDTokenVerifier) (claims C, err error) { + ctx, span := tracer.Start(ctx, "VerifyIDToken") + defer span.End() + var nilClaims C decrypted, err := oidc.DecryptToken(token) diff --git a/pkg/op/op.go b/pkg/op/op.go index 326737a..2080339 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -135,6 +135,7 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) chi.Router } else { router.Use(cors.New(defaultCORSOptions).Handler) } + router.Use(intercept(o.IssuerFromRequest, interceptors...)) router.HandleFunc(healthEndpoint, healthHandler) router.HandleFunc(readinessEndpoint, readyHandler(o.Probes())) From 88209ac11d0d105bebb5eff9284db80b577c3e32 Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Wed, 6 Mar 2024 19:08:48 +0100 Subject: [PATCH 047/185] fix tests --- pkg/op/auth_request_test.go | 6 +++--- pkg/op/client_test.go | 6 +++--- pkg/op/op_test.go | 2 +- pkg/op/server_http_routes_test.go | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 76cb00d..45627a5 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -1072,7 +1072,7 @@ func TestAuthResponseCode(t *testing.T) { authorizer: func(t *testing.T) op.Authorizer { ctrl := gomock.NewController(t) storage := mock.NewMockStorage(ctrl) - storage.EXPECT().SaveAuthCode(context.Background(), "id1", "id1") + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") authorizer := mock.NewMockAuthorizer(ctrl) authorizer.EXPECT().Storage().Return(storage) @@ -1097,7 +1097,7 @@ func TestAuthResponseCode(t *testing.T) { authorizer: func(t *testing.T) op.Authorizer { ctrl := gomock.NewController(t) storage := mock.NewMockStorage(ctrl) - storage.EXPECT().SaveAuthCode(context.Background(), "id1", "id1") + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") authorizer := mock.NewMockAuthorizer(ctrl) authorizer.EXPECT().Storage().Return(storage) @@ -1124,7 +1124,7 @@ func TestAuthResponseCode(t *testing.T) { authorizer: func(t *testing.T) op.Authorizer { ctrl := gomock.NewController(t) storage := mock.NewMockStorage(ctrl) - storage.EXPECT().SaveAuthCode(context.Background(), "id1", "id1") + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") authorizer := mock.NewMockAuthorizer(ctrl) authorizer.EXPECT().Storage().Return(storage) diff --git a/pkg/op/client_test.go b/pkg/op/client_test.go index 0321f88..b772ba5 100644 --- a/pkg/op/client_test.go +++ b/pkg/op/client_test.go @@ -108,7 +108,7 @@ func TestClientBasicAuth(t *testing.T) { }, storage: func() op.Storage { s := mock.NewMockStorage(gomock.NewController(t)) - s.EXPECT().AuthorizeClientIDSecret(context.Background(), "foo", "wrong").Return(errWrong) + s.EXPECT().AuthorizeClientIDSecret(gomock.Any(), "foo", "wrong").Return(errWrong) return s }(), wantErr: errWrong, @@ -121,7 +121,7 @@ func TestClientBasicAuth(t *testing.T) { }, storage: func() op.Storage { s := mock.NewMockStorage(gomock.NewController(t)) - s.EXPECT().AuthorizeClientIDSecret(context.Background(), "foo", "bar").Return(nil) + s.EXPECT().AuthorizeClientIDSecret(gomock.Any(), "foo", "bar").Return(nil) return s }(), wantClientID: "foo", @@ -207,7 +207,7 @@ func TestClientIDFromRequest(t *testing.T) { p: testClientProvider{ storage: func() op.Storage { s := mock.NewMockStorage(gomock.NewController(t)) - s.EXPECT().AuthorizeClientIDSecret(context.Background(), "foo", "bar").Return(nil) + s.EXPECT().AuthorizeClientIDSecret(gomock.Any(), "foo", "bar").Return(nil) return s }(), }, diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index b2a758c..5e0d675 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -235,7 +235,7 @@ func TestRoutes(t *testing.T) { contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299}`}, }, { - // This call will fail. A successfull test is already + // This call will fail. A successful test is already // part of device_test.go name: "device token", method: http.MethodPost, diff --git a/pkg/op/server_http_routes_test.go b/pkg/op/server_http_routes_test.go index c50e989..8b3fa02 100644 --- a/pkg/op/server_http_routes_test.go +++ b/pkg/op/server_http_routes_test.go @@ -177,7 +177,7 @@ func TestServerRoutes(t *testing.T) { contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299}`}, }, { - // This call will fail. A successfull test is already + // This call will fail. A successful test is already // part of device_test.go name: "device token", method: http.MethodPost, From 7069813ec71e47a5ad7c2cc8c16a708946a83129 Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Thu, 7 Mar 2024 10:44:24 +0100 Subject: [PATCH 048/185] correct span names --- pkg/op/auth_request.go | 3 +-- pkg/op/device.go | 2 +- pkg/op/op.go | 1 - pkg/op/token_revocation.go | 2 +- pkg/op/userinfo.go | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 435e3f4..4b5837a 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -79,7 +79,6 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { AuthRequestError(w, r, nil, err, authorizer) return } - ctx = r.Context() if authReq.RequestParam != "" && authorizer.RequestObjectSupported() { err = ParseRequestObject(ctx, authReq, authorizer.Storage(), IssuerFromContext(ctx)) if err != nil { @@ -452,7 +451,7 @@ func ParseAuthorizeCallbackRequest(r *http.Request) (id string, err error) { // AuthResponse creates the successful authentication response (either code or tokens) func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWriter, r *http.Request) { - ctx, span := tracer.Start(r.Context(), "ValidateAuthRequest") + ctx, span := tracer.Start(r.Context(), "AuthResponse") r = r.WithContext(ctx) defer span.End() diff --git a/pkg/op/device.go b/pkg/op/device.go index d08b4fd..11638b0 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -299,7 +299,7 @@ func (r *DeviceAuthorizationState) GetSubject() string { } func CheckDeviceAuthorizationState(ctx context.Context, clientID, deviceCode string, exchanger Exchanger) (*DeviceAuthorizationState, error) { - ctx, span := tracer.Start(ctx, "CheckDeviceAuthorization") + ctx, span := tracer.Start(ctx, "CheckDeviceAuthorizationState") defer span.End() storage, err := assertDeviceStorage(exchanger.Storage()) diff --git a/pkg/op/op.go b/pkg/op/op.go index 2080339..326737a 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -135,7 +135,6 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) chi.Router } else { router.Use(cors.New(defaultCORSOptions).Handler) } - router.Use(intercept(o.IssuerFromRequest, interceptors...)) router.HandleFunc(healthEndpoint, healthHandler) router.HandleFunc(readinessEndpoint, readyHandler(o.Probes())) diff --git a/pkg/op/token_revocation.go b/pkg/op/token_revocation.go index 537b164..a86a481 100644 --- a/pkg/op/token_revocation.go +++ b/pkg/op/token_revocation.go @@ -156,7 +156,7 @@ func RevocationError(err error) StatusError { } func getTokenIDAndSubjectForRevocation(ctx context.Context, userinfoProvider UserinfoProvider, accessToken string) (string, string, bool) { - ctx, span := tracer.Start(ctx, "getTokenIDAndSubjectFromRevocation") + ctx, span := tracer.Start(ctx, "getTokenIDAndSubjectForRevocation") defer span.End() tokenIDSubject, err := userinfoProvider.Crypto().Decrypt(accessToken) diff --git a/pkg/op/userinfo.go b/pkg/op/userinfo.go index 4b8f398..839b139 100644 --- a/pkg/op/userinfo.go +++ b/pkg/op/userinfo.go @@ -69,7 +69,7 @@ func ParseUserinfoRequest(r *http.Request, decoder httphelper.Decoder) (string, } func getAccessToken(r *http.Request) (string, error) { - ctx, span := tracer.Start(r.Context(), "RefreshTokens") + ctx, span := tracer.Start(r.Context(), "getAccessToken") r = r.WithContext(ctx) defer span.End() From 0fe7c3307f1bb3773b24d54c9ae052420248f58c Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Thu, 7 Mar 2024 15:25:23 +0100 Subject: [PATCH 049/185] fix parse --- pkg/op/client.go | 8 ++++---- pkg/op/op_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/op/client.go b/pkg/op/client.go index e0a0443..913944c 100644 --- a/pkg/op/client.go +++ b/pkg/op/client.go @@ -153,15 +153,15 @@ type clientData struct { // If no client id can be obtained by any method, oidc.ErrInvalidClient // is returned with ErrMissingClientID wrapped in it. func ClientIDFromRequest(r *http.Request, p ClientProvider) (clientID string, authenticated bool, err error) { - ctx, span := tracer.Start(r.Context(), "ClientIDFromRequest") - r = r.WithContext(ctx) - defer span.End() - err = r.ParseForm() if err != nil { return "", false, oidc.ErrInvalidRequest().WithDescription("cannot parse form").WithParent(err) } + ctx, span := tracer.Start(r.Context(), "ClientIDFromRequest") + r = r.WithContext(ctx) + defer span.End() + data := new(clientData) if err = p.Decoder().Decode(data, r.Form); err != nil { return "", false, err diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index 5e0d675..83032d4 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -181,7 +181,7 @@ func TestRoutes(t *testing.T) { }, }, { - // This call will fail. A successfull test is already + // This call will fail. A successful test is already // part of client/integration_test.go name: "code exchange", method: http.MethodGet, From 1532a5c78b8418d91635038e0df4d014813811a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 07:35:47 +0100 Subject: [PATCH 050/185] chore(deps): bump github.com/go-jose/go-jose/v3 from 3.0.2 to 3.0.3 (#566) Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/v3.0.3/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v3.0.2...v3.0.3) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9cb99e6..c7562ea 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.0.12 - github.com/go-jose/go-jose/v3 v3.0.2 + github.com/go-jose/go-jose/v3 v3.0.3 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 9b2c86f..2b1eb7e 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v3 v3.0.2 h1:2Edjn8Nrb44UvTdp84KU0bBPs1cO7noRCybtS3eJEUQ= -github.com/go-jose/go-jose/v3 v3.0.2/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= From ad798029685818564a91afdad5d114031563ae99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 13 Mar 2024 16:26:09 +0200 Subject: [PATCH 051/185] feat: extend token exchange response (#567) * feat: extend token exchange response This change adds fields to the token exchange and token claims types. The `act` claim has been added to describe the actor in case of impersonation or delegation. An actor can be nested in case an obtained token is used as actor token to obtain impersonation or delegation. This allows creating a chain of actors. See [RFC 8693, section 4.1](https://www.rfc-editor.org/rfc/rfc8693#name-act-actor-claim). The `id_token` field has been added to the Token Exchange response so an ID Token can be returned along with an access token. This is not specified in RFC 8693, but it allows us be consistent with OpenID responses when the scope `openid` is set, while the requested token type may remain access token. * allow jwt profile for token exchange client * add invalid target error --- pkg/client/tokenexchange/tokenexchange.go | 13 ++++++ pkg/oidc/error.go | 13 ++++++ pkg/oidc/token.go | 53 +++++++++++++++++------ pkg/oidc/token_request.go | 9 +--- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/pkg/client/tokenexchange/tokenexchange.go b/pkg/client/tokenexchange/tokenexchange.go index fdac833..7bc35a2 100644 --- a/pkg/client/tokenexchange/tokenexchange.go +++ b/pkg/client/tokenexchange/tokenexchange.go @@ -4,7 +4,9 @@ import ( "context" "errors" "net/http" + "time" + "github.com/go-jose/go-jose/v3" "github.com/zitadel/oidc/v3/pkg/client" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" @@ -33,6 +35,17 @@ func NewTokenExchangerClientCredentials(ctx context.Context, issuer, clientID, c return newOAuthTokenExchange(ctx, issuer, authorizer, options...) } +func NewTokenExchangerJWTProfile(ctx context.Context, issuer, clientID string, signer jose.Signer, options ...func(source *OAuthTokenExchange)) (TokenExchanger, error) { + authorizer := func() (any, error) { + assertion, err := client.SignedJWTProfileAssertion(clientID, []string{issuer}, time.Hour, signer) + if err != nil { + return nil, err + } + return client.ClientAssertionFormAuthorization(assertion), nil + } + return newOAuthTokenExchange(ctx, issuer, authorizer, options...) +} + func newOAuthTokenExchange(ctx context.Context, issuer string, authorizer func() (any, error), options ...func(source *OAuthTokenExchange)) (*OAuthTokenExchange, error) { te := &OAuthTokenExchange{ httpClient: httphelper.DefaultHTTPClient, diff --git a/pkg/oidc/error.go b/pkg/oidc/error.go index 86f8724..2f0572d 100644 --- a/pkg/oidc/error.go +++ b/pkg/oidc/error.go @@ -27,6 +27,11 @@ const ( SlowDown errorType = "slow_down" AccessDenied errorType = "access_denied" ExpiredToken errorType = "expired_token" + + // InvalidTarget error is returned by Token Exchange if + // the requested target or audience is invalid. + // [RFC 8693, Section 2.2.2: Error Response](https://www.rfc-editor.org/rfc/rfc8693#section-2.2.2) + InvalidTarget errorType = "invalid_target" ) var ( @@ -112,6 +117,14 @@ var ( Description: "The \"device_code\" has expired.", } } + + // Token exchange error + ErrInvalidTarget = func() *Error { + return &Error{ + ErrorType: InvalidTarget, + Description: "The requested audience or target is invalid.", + } + } ) type Error struct { diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index b4cb6b6..73eb2e5 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -34,19 +34,20 @@ type Tokens[C IDClaims] struct { // TokenClaims implements the Claims interface, // and can be used to extend larger claim types by embedding. type TokenClaims struct { - Issuer string `json:"iss,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - Expiration Time `json:"exp,omitempty"` - IssuedAt Time `json:"iat,omitempty"` - AuthTime Time `json:"auth_time,omitempty"` - NotBefore Time `json:"nbf,omitempty"` - Nonce string `json:"nonce,omitempty"` - AuthenticationContextClassReference string `json:"acr,omitempty"` - AuthenticationMethodsReferences []string `json:"amr,omitempty"` - AuthorizedParty string `json:"azp,omitempty"` - ClientID string `json:"client_id,omitempty"` - JWTID string `json:"jti,omitempty"` + Issuer string `json:"iss,omitempty"` + Subject string `json:"sub,omitempty"` + Audience Audience `json:"aud,omitempty"` + Expiration Time `json:"exp,omitempty"` + IssuedAt Time `json:"iat,omitempty"` + AuthTime Time `json:"auth_time,omitempty"` + NotBefore Time `json:"nbf,omitempty"` + Nonce string `json:"nonce,omitempty"` + AuthenticationContextClassReference string `json:"acr,omitempty"` + AuthenticationMethodsReferences []string `json:"amr,omitempty"` + AuthorizedParty string `json:"azp,omitempty"` + ClientID string `json:"client_id,omitempty"` + JWTID string `json:"jti,omitempty"` + Actor *ActorClaims `json:"act,omitempty"` // Additional information set by this framework SignatureAlg jose.SignatureAlgorithm `json:"-"` @@ -204,6 +205,28 @@ func (i *IDTokenClaims) UnmarshalJSON(data []byte) error { return unmarshalJSONMulti(data, (*itcAlias)(i), &i.Claims) } +// ActorClaims provides the `act` claims used for impersonation or delegation Token Exchange. +// +// An actor can be nested in case an obtained token is used as actor token to obtain impersonation or delegation. +// This allows creating a chain of actors. +// See [RFC 8693, section 4.1](https://www.rfc-editor.org/rfc/rfc8693#name-act-actor-claim). +type ActorClaims struct { + Actor *ActorClaims `json:"act,omitempty"` + Issuer string `json:"iss,omitempty"` + Subject string `json:"sub,omitempty"` + Claims map[string]any `json:"-"` +} + +type acAlias ActorClaims + +func (c *ActorClaims) MarshalJSON() ([]byte, error) { + return mergeAndMarshalClaims((*acAlias)(c), c.Claims) +} + +func (c *ActorClaims) UnmarshalJSON(data []byte) error { + return unmarshalJSONMulti(data, (*acAlias)(c), &c.Claims) +} + type AccessTokenResponse struct { AccessToken string `json:"access_token,omitempty" schema:"access_token,omitempty"` TokenType string `json:"token_type,omitempty" schema:"token_type,omitempty"` @@ -352,4 +375,8 @@ type TokenExchangeResponse struct { ExpiresIn uint64 `json:"expires_in,omitempty"` Scopes SpaceDelimitedArray `json:"scope,omitempty"` RefreshToken string `json:"refresh_token,omitempty"` + + // IDToken field allows returning an additional ID token + // if the requested_token_type was Access Token and scope contained openid. + IDToken string `json:"id_token,omitempty"` } diff --git a/pkg/oidc/token_request.go b/pkg/oidc/token_request.go index b43b249..b07b333 100644 --- a/pkg/oidc/token_request.go +++ b/pkg/oidc/token_request.go @@ -3,6 +3,7 @@ package oidc import ( "encoding/json" "fmt" + "slices" "time" jose "github.com/go-jose/go-jose/v3" @@ -57,13 +58,7 @@ var AllTokenTypes = []TokenType{ type TokenType string func (t TokenType) IsSupported() bool { - for _, tt := range AllTokenTypes { - if t == tt { - return true - } - } - - return false + return slices.Contains(AllTokenTypes, t) } type TokenRequest interface { From 1b94f796eb8443f2f84c16d81b555b0df263cc40 Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Wed, 13 Mar 2024 15:45:03 +0100 Subject: [PATCH 052/185] move tracer to client, add tracing in rs, client --- pkg/client/client.go | 33 ++++++++++++++++++++--- pkg/client/rp/device.go | 4 +-- pkg/client/rp/jwks.go | 11 ++++---- pkg/client/rp/relying_party.go | 30 ++++++++------------- pkg/client/rp/verifier.go | 5 ++-- pkg/client/rs/resource_server.go | 3 +++ pkg/client/tokenexchange/tokenexchange.go | 3 +++ pkg/op/op.go | 7 +---- 8 files changed, 59 insertions(+), 37 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index b329b3d..8b60264 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -12,19 +12,25 @@ import ( "time" jose "github.com/go-jose/go-jose/v3" - "golang.org/x/oauth2" - "github.com/zitadel/logging" "github.com/zitadel/oidc/v3/pkg/crypto" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" + "go.opentelemetry.io/otel" + "golang.org/x/oauth2" ) -var Encoder = httphelper.Encoder(oidc.NewEncoder()) +var ( + Encoder = httphelper.Encoder(oidc.NewEncoder()) + Tracer = otel.Tracer("github.com/zitadel/oidc/pkg/client") +) // Discover calls the discovery endpoint of the provided issuer and returns its configuration // It accepts an optional argument "wellknownUrl" which can be used to overide the dicovery endpoint url func Discover(ctx context.Context, issuer string, httpClient *http.Client, wellKnownUrl ...string) (*oidc.DiscoveryConfiguration, error) { + ctx, span := Tracer.Start(ctx, "Discover") + defer span.End() + wellKnown := strings.TrimSuffix(issuer, "/") + oidc.DiscoveryEndpoint if len(wellKnownUrl) == 1 && wellKnownUrl[0] != "" { wellKnown = wellKnownUrl[0] @@ -58,6 +64,9 @@ func CallTokenEndpoint(ctx context.Context, request any, caller TokenEndpointCal } func callTokenEndpoint(ctx context.Context, request any, authFn any, caller TokenEndpointCaller) (newToken *oauth2.Token, err error) { + ctx, span := Tracer.Start(ctx, "callTokenEndpoint") + defer span.End() + req, err := httphelper.FormRequest(ctx, caller.TokenEndpoint(), request, Encoder, authFn) if err != nil { return nil, err @@ -86,6 +95,9 @@ type EndSessionCaller interface { } func CallEndSessionEndpoint(ctx context.Context, request any, authFn any, caller EndSessionCaller) (*url.URL, error) { + ctx, span := Tracer.Start(ctx, "CallEndSessionEndpoint") + defer span.End() + req, err := httphelper.FormRequest(ctx, caller.GetEndSessionEndpoint(), request, Encoder, authFn) if err != nil { return nil, err @@ -129,6 +141,9 @@ type RevokeRequest struct { } func CallRevokeEndpoint(ctx context.Context, request any, authFn any, caller RevokeCaller) error { + ctx, span := Tracer.Start(ctx, "CallRevokeEndpoint") + defer span.End() + req, err := httphelper.FormRequest(ctx, caller.GetRevokeEndpoint(), request, Encoder, authFn) if err != nil { return err @@ -157,6 +172,9 @@ func CallRevokeEndpoint(ctx context.Context, request any, authFn any, caller Rev } func CallTokenExchangeEndpoint(ctx context.Context, request any, authFn any, caller TokenEndpointCaller) (resp *oidc.TokenExchangeResponse, err error) { + ctx, span := Tracer.Start(ctx, "CallTokenExchangeEndpoint") + defer span.End() + req, err := httphelper.FormRequest(ctx, caller.TokenEndpoint(), request, Encoder, authFn) if err != nil { return nil, err @@ -198,6 +216,9 @@ type DeviceAuthorizationCaller interface { } func CallDeviceAuthorizationEndpoint(ctx context.Context, request *oidc.ClientCredentialsRequest, caller DeviceAuthorizationCaller, authFn any) (*oidc.DeviceAuthorizationResponse, error) { + ctx, span := Tracer.Start(ctx, "CallDeviceAuthorizationEndpoint") + defer span.End() + req, err := httphelper.FormRequest(ctx, caller.GetDeviceAuthorizationEndpoint(), request, Encoder, authFn) if err != nil { return nil, err @@ -219,6 +240,9 @@ type DeviceAccessTokenRequest struct { } func CallDeviceAccessTokenEndpoint(ctx context.Context, request *DeviceAccessTokenRequest, caller TokenEndpointCaller) (*oidc.AccessTokenResponse, error) { + ctx, span := Tracer.Start(ctx, "CallDeviceAccessTokenEndpoint") + defer span.End() + req, err := httphelper.FormRequest(ctx, caller.TokenEndpoint(), request, Encoder, nil) if err != nil { return nil, err @@ -249,6 +273,9 @@ func CallDeviceAccessTokenEndpoint(ctx context.Context, request *DeviceAccessTok } func PollDeviceAccessTokenEndpoint(ctx context.Context, interval time.Duration, request *DeviceAccessTokenRequest, caller TokenEndpointCaller) (*oidc.AccessTokenResponse, error) { + ctx, span := Tracer.Start(ctx, "PollDeviceAccessTokenEndpoint") + defer span.End() + for { timer := time.After(interval) select { diff --git a/pkg/client/rp/device.go b/pkg/client/rp/device.go index ec4dabe..c2d1f8a 100644 --- a/pkg/client/rp/device.go +++ b/pkg/client/rp/device.go @@ -33,7 +33,7 @@ func newDeviceClientCredentialsRequest(scopes []string, rp RelyingParty) (*oidc. // in RFC 8628, section 3.1 and 3.2: // https://www.rfc-editor.org/rfc/rfc8628#section-3.1 func DeviceAuthorization(ctx context.Context, scopes []string, rp RelyingParty, authFn any) (*oidc.DeviceAuthorizationResponse, error) { - ctx, span := tracer.Start(ctx, "DeviceAuthorization") + ctx, span := client.Tracer.Start(ctx, "DeviceAuthorization") defer span.End() ctx = logCtxWithRPData(ctx, rp, "function", "DeviceAuthorization") @@ -49,7 +49,7 @@ func DeviceAuthorization(ctx context.Context, scopes []string, rp RelyingParty, // by means of polling as defined in RFC, section 3.3 and 3.4: // https://www.rfc-editor.org/rfc/rfc8628#section-3.4 func DeviceAccessToken(ctx context.Context, deviceCode string, interval time.Duration, rp RelyingParty) (resp *oidc.AccessTokenResponse, err error) { - ctx, span := tracer.Start(ctx, "DeviceAccessToken") + ctx, span := client.Tracer.Start(ctx, "DeviceAccessToken") defer span.End() ctx = logCtxWithRPData(ctx, rp, "function", "DeviceAccessToken") diff --git a/pkg/client/rp/jwks.go b/pkg/client/rp/jwks.go index a3c1647..a061777 100644 --- a/pkg/client/rp/jwks.go +++ b/pkg/client/rp/jwks.go @@ -9,6 +9,7 @@ import ( jose "github.com/go-jose/go-jose/v3" + "github.com/zitadel/oidc/v3/pkg/client" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" ) @@ -83,7 +84,7 @@ func (i *inflight) result() ([]jose.JSONWebKey, error) { } func (r *remoteKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { - ctx, span := tracer.Start(ctx, "VerifySignature") + ctx, span := client.Tracer.Start(ctx, "VerifySignature") defer span.End() keyID, alg := oidc.GetKeyIDAndAlg(jws) @@ -138,7 +139,7 @@ func (r *remoteKeySet) exactMatch(jwkID, jwsID string) bool { } func (r *remoteKeySet) verifySignatureRemote(ctx context.Context, jws *jose.JSONWebSignature, keyID, alg string) ([]byte, error) { - ctx, span := tracer.Start(ctx, "verifySignatureRemote") + ctx, span := client.Tracer.Start(ctx, "verifySignatureRemote") defer span.End() keys, err := r.keysFromRemote(ctx) @@ -165,7 +166,7 @@ func (r *remoteKeySet) keysFromCache() (keys []jose.JSONWebKey) { // keysFromRemote syncs the key set from the remote set, records the values in the // cache, and returns the key set. func (r *remoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, error) { - ctx, span := tracer.Start(ctx, "keysFromRemote") + ctx, span := client.Tracer.Start(ctx, "keysFromRemote") defer span.End() // Need to lock to inspect the inflight request field. @@ -191,7 +192,7 @@ func (r *remoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, e } func (r *remoteKeySet) updateKeys(ctx context.Context) { - ctx, span := tracer.Start(ctx, "updateKeys") + ctx, span := client.Tracer.Start(ctx, "updateKeys") defer span.End() // Sync keys and finish inflight when that's done. @@ -213,7 +214,7 @@ func (r *remoteKeySet) updateKeys(ctx context.Context) { } func (r *remoteKeySet) fetchRemoteKeys(ctx context.Context) ([]jose.JSONWebKey, error) { - ctx, span := tracer.Start(ctx, "fetchRemoteKeys") + ctx, span := client.Tracer.Start(ctx, "fetchRemoteKeys") defer span.End() req, err := http.NewRequest("GET", r.jwksURL, nil) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 3022035..62c650e 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -11,12 +11,10 @@ import ( "github.com/go-jose/go-jose/v3" "github.com/google/uuid" - "github.com/zitadel/logging" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/trace" "golang.org/x/oauth2" "golang.org/x/oauth2/clientcredentials" + "github.com/zitadel/logging" "github.com/zitadel/oidc/v3/pkg/client" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" @@ -30,12 +28,6 @@ const ( var ErrUserInfoSubNotMatching = errors.New("sub from userinfo does not match the sub from the id_token") -var tracer trace.Tracer - -func init() { - tracer = otel.Tracer("github.com/zitadel/oidc/pkg/client/rp") -} - // RelyingParty declares the minimal interface for oidc clients type RelyingParty interface { // OAuthConfig returns the oauth2 Config @@ -436,7 +428,7 @@ func GenerateAndStoreCodeChallenge(w http.ResponseWriter, rp RelyingParty) (stri var ErrMissingIDToken = errors.New("id_token missing") func verifyTokenResponse[C oidc.IDClaims](ctx context.Context, token *oauth2.Token, rp RelyingParty) (*oidc.Tokens[C], error) { - ctx, span := tracer.Start(ctx, "verifyTokenResponse") + ctx, span := client.Tracer.Start(ctx, "verifyTokenResponse") defer span.End() if rp.IsOAuth2Only() { @@ -456,7 +448,7 @@ func verifyTokenResponse[C oidc.IDClaims](ctx context.Context, token *oauth2.Tok // CodeExchange handles the oauth2 code exchange, extracting and validating the id_token // returning it parsed together with the oauth2 tokens (access, refresh) func CodeExchange[C oidc.IDClaims](ctx context.Context, code string, rp RelyingParty, opts ...CodeExchangeOpt) (tokens *oidc.Tokens[C], err error) { - ctx, codeExchangeSpan := tracer.Start(ctx, "CodeExchange") + ctx, codeExchangeSpan := client.Tracer.Start(ctx, "CodeExchange") defer codeExchangeSpan.End() ctx = logCtxWithRPData(ctx, rp, "function", "CodeExchange") @@ -466,7 +458,7 @@ func CodeExchange[C oidc.IDClaims](ctx context.Context, code string, rp RelyingP codeOpts = append(codeOpts, opt()...) } - ctx, oauthExchangeSpan := tracer.Start(ctx, "OAuthExchange") + ctx, oauthExchangeSpan := client.Tracer.Start(ctx, "OAuthExchange") token, err := rp.OAuthConfig().Exchange(ctx, code, codeOpts...) if err != nil { return nil, err @@ -485,7 +477,7 @@ func CodeExchange[C oidc.IDClaims](ctx context.Context, code string, rp RelyingP // [RFC 6749, section 4.4]: https://datatracker.ietf.org/doc/html/rfc6749#section-4.4 func ClientCredentials(ctx context.Context, rp RelyingParty, endpointParams url.Values) (token *oauth2.Token, err error) { ctx = logCtxWithRPData(ctx, rp, "function", "ClientCredentials") - ctx, span := tracer.Start(ctx, "ClientCredentials") + ctx, span := client.Tracer.Start(ctx, "ClientCredentials") defer span.End() ctx = context.WithValue(ctx, oauth2.HTTPClient, rp.HttpClient()) @@ -508,7 +500,7 @@ type CodeExchangeCallback[C oidc.IDClaims] func(w http.ResponseWriter, r *http.R // Custom parameters can optionally be set to the token URL. func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp RelyingParty, urlParam ...URLParamOpt) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - ctx, span := tracer.Start(r.Context(), "CodeExchangeHandler") + ctx, span := client.Tracer.Start(r.Context(), "CodeExchangeHandler") r = r.WithContext(ctx) defer span.End() @@ -563,7 +555,7 @@ type CodeExchangeUserinfoCallback[C oidc.IDClaims, U SubjectGetter] func(w http. // on success it will pass the userinfo into its callback function as well func UserinfoCallback[C oidc.IDClaims, U SubjectGetter](f CodeExchangeUserinfoCallback[C, U]) CodeExchangeCallback[C] { return func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[C], state string, rp RelyingParty) { - ctx, span := tracer.Start(r.Context(), "UserinfoCallback") + ctx, span := client.Tracer.Start(r.Context(), "UserinfoCallback") r = r.WithContext(ctx) defer span.End() @@ -585,7 +577,7 @@ func UserinfoCallback[C oidc.IDClaims, U SubjectGetter](f CodeExchangeUserinfoCa func Userinfo[U SubjectGetter](ctx context.Context, token, tokenType, subject string, rp RelyingParty) (userinfo U, err error) { var nilU U ctx = logCtxWithRPData(ctx, rp, "function", "Userinfo") - ctx, span := tracer.Start(ctx, "Userinfo") + ctx, span := client.Tracer.Start(ctx, "Userinfo") defer span.End() req, err := http.NewRequestWithContext(ctx, http.MethodGet, rp.UserinfoEndpoint(), nil) @@ -745,7 +737,7 @@ type RefreshTokenRequest struct { // the IDToken and AccessToken will be verfied // and the IDToken and IDTokenClaims fields will be populated in the returned object. func RefreshTokens[C oidc.IDClaims](ctx context.Context, rp RelyingParty, refreshToken, clientAssertion, clientAssertionType string) (*oidc.Tokens[C], error) { - ctx, span := tracer.Start(ctx, "RefreshTokens") + ctx, span := client.Tracer.Start(ctx, "RefreshTokens") defer span.End() ctx = logCtxWithRPData(ctx, rp, "function", "RefreshTokens") @@ -773,7 +765,7 @@ func RefreshTokens[C oidc.IDClaims](ctx context.Context, rp RelyingParty, refres func EndSession(ctx context.Context, rp RelyingParty, idToken, optionalRedirectURI, optionalState string) (*url.URL, error) { ctx = logCtxWithRPData(ctx, rp, "function", "EndSession") - ctx, span := tracer.Start(ctx, "RefreshTokens") + ctx, span := client.Tracer.Start(ctx, "RefreshTokens") defer span.End() request := oidc.EndSessionRequest{ @@ -792,7 +784,7 @@ func EndSession(ctx context.Context, rp RelyingParty, idToken, optionalRedirectU // tokenTypeHint should be either "id_token" or "refresh_token". func RevokeToken(ctx context.Context, rp RelyingParty, token string, tokenTypeHint string) error { ctx = logCtxWithRPData(ctx, rp, "function", "RevokeToken") - ctx, span := tracer.Start(ctx, "RefreshTokens") + ctx, span := client.Tracer.Start(ctx, "RefreshTokens") defer span.End() request := client.RevokeRequest{ Token: token, diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index ebc10cc..94be079 100644 --- a/pkg/client/rp/verifier.go +++ b/pkg/client/rp/verifier.go @@ -6,13 +6,14 @@ import ( jose "github.com/go-jose/go-jose/v3" + "github.com/zitadel/oidc/v3/pkg/client" "github.com/zitadel/oidc/v3/pkg/oidc" ) // VerifyTokens implement the Token Response Validation as defined in OIDC specification // https://openid.net/specs/openid-connect-core-1_0.html#TokenResponseValidation func VerifyTokens[C oidc.IDClaims](ctx context.Context, accessToken, idToken string, v *IDTokenVerifier) (claims C, err error) { - ctx, span := tracer.Start(ctx, "VerifyTokens") + ctx, span := client.Tracer.Start(ctx, "VerifyTokens") defer span.End() var nilClaims C @@ -30,7 +31,7 @@ func VerifyTokens[C oidc.IDClaims](ctx context.Context, accessToken, idToken str // VerifyIDToken validates the id token according to // https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation func VerifyIDToken[C oidc.Claims](ctx context.Context, token string, v *IDTokenVerifier) (claims C, err error) { - ctx, span := tracer.Start(ctx, "VerifyIDToken") + ctx, span := client.Tracer.Start(ctx, "VerifyIDToken") defer span.End() var nilClaims C diff --git a/pkg/client/rs/resource_server.go b/pkg/client/rs/resource_server.go index 57925d5..962af7e 100644 --- a/pkg/client/rs/resource_server.go +++ b/pkg/client/rs/resource_server.go @@ -123,6 +123,9 @@ func WithStaticEndpoints(tokenURL, introspectURL string) Option { // // [RFC7662]: https://www.rfc-editor.org/rfc/rfc7662 func Introspect[R any](ctx context.Context, rp ResourceServer, token string) (resp R, err error) { + ctx, span := client.Tracer.Start(ctx, "Introspect") + defer span.End() + if rp.IntrospectionURL() == "" { return resp, errors.New("resource server: introspection URL is empty") } diff --git a/pkg/client/tokenexchange/tokenexchange.go b/pkg/client/tokenexchange/tokenexchange.go index fdac833..c62f38c 100644 --- a/pkg/client/tokenexchange/tokenexchange.go +++ b/pkg/client/tokenexchange/tokenexchange.go @@ -101,6 +101,9 @@ func ExchangeToken( Scopes []string, RequestedTokenType oidc.TokenType, ) (*oidc.TokenExchangeResponse, error) { + ctx, span := client.Tracer.Start(ctx, "ExchangeToken") + defer span.End() + if SubjectToken == "" { return nil, errors.New("empty subject_token") } diff --git a/pkg/op/op.go b/pkg/op/op.go index 326737a..3248317 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -12,7 +12,6 @@ import ( "github.com/rs/cors" "github.com/zitadel/schema" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/trace" "golang.org/x/text/language" httphelper "github.com/zitadel/oidc/v3/pkg/http" @@ -97,11 +96,7 @@ var ( } ) -var tracer trace.Tracer - -func init() { - tracer = otel.Tracer("github.com/zitadel/oidc/pkg/op") -} +var tracer = otel.Tracer("github.com/zitadel/oidc/pkg/op") type OpenIDProvider interface { http.Handler From 03f3bc693b04e2224515a112f866fd00ec2af4cc Mon Sep 17 00:00:00 2001 From: adlerhurst Date: Thu, 14 Mar 2024 07:50:29 +0100 Subject: [PATCH 053/185] fix test --- pkg/client/rs/resource_server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/client/rs/resource_server_test.go b/pkg/client/rs/resource_server_test.go index bb17c64..7a5ced9 100644 --- a/pkg/client/rs/resource_server_test.go +++ b/pkg/client/rs/resource_server_test.go @@ -201,7 +201,7 @@ func TestIntrospect(t *testing.T) { { name: "missing-introspect-url", args: args{ - ctx: nil, + ctx: context.Background(), rp: rp, token: "my-token", }, From 9afc07c0cbd3d3752a07173ed62b3d3ac31db4a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 06:55:56 +0000 Subject: [PATCH 054/185] chore(deps): bump google.golang.org/protobuf from 1.31.0 to 1.33.0 (#568) Bumps google.golang.org/protobuf from 1.31.0 to 1.33.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index c7562ea..bd7a0e5 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,6 @@ require ( github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.24.0 - go.opentelemetry.io/otel/trace v1.24.0 golang.org/x/oauth2 v0.18.0 golang.org/x/text v0.14.0 ) @@ -32,10 +31,11 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sys v0.18.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2b1eb7e..58029da 100644 --- a/go.sum +++ b/go.sum @@ -136,8 +136,8 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/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= From 4d63d68c9e145dd79269130474984e01e8ef6530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 14 Mar 2024 08:57:44 +0200 Subject: [PATCH 055/185] feat(op): allow setting the actor to Token Requests (#569) For impersonation token exchange we need to persist the actor throughout token requests, including refresh token. This PR adds the optional TokenActorRequest interface which allows to pass such actor. --- pkg/op/token.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/op/token.go b/pkg/op/token.go index 19edcce..b45789b 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -121,6 +121,10 @@ func CreateBearerToken(tokenID, subject string, crypto Crypto) (string, error) { return crypto.Encrypt(tokenID + ":" + subject) } +type TokenActorRequest interface { + GetActor() *oidc.ActorClaims +} + func CreateJWT(ctx context.Context, issuer string, tokenRequest TokenRequest, exp time.Time, id string, client AccessTokenClient, storage Storage) (string, error) { ctx, span := tracer.Start(ctx, "CreateJWT") defer span.End() @@ -150,6 +154,9 @@ func CreateJWT(ctx context.Context, issuer string, tokenRequest TokenRequest, ex } claims.Claims = privateClaims } + if actorReq, ok := tokenRequest.(TokenActorRequest); ok { + claims.Actor = actorReq.GetActor() + } signingKey, err := storage.SigningKey(ctx) if err != nil { return "", err @@ -181,6 +188,10 @@ func CreateIDToken(ctx context.Context, issuer string, request IDTokenRequest, v nonce = authRequest.GetNonce() } claims := oidc.NewIDTokenClaims(issuer, request.GetSubject(), request.GetAudience(), exp, request.GetAuthTime(), nonce, acr, request.GetAMR(), request.GetClientID(), client.ClockSkew()) + if actorReq, ok := request.(TokenActorRequest); ok { + claims.Actor = actorReq.GetActor() + } + scopes := client.RestrictAdditionalIdTokenScopes()(request.GetScopes()) signingKey, err := storage.SigningKey(ctx) if err != nil { From 56397f88d5b8abcda55ead200af66093e428786e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 18 Mar 2024 12:36:16 +0200 Subject: [PATCH 056/185] feat(oidc): add actor claim to introspection response (#570) With impersonation we assign an actor claim to our JWT/ID Tokens. This change adds the actor claim to the introspection response to follow suit. This PR also adds the `auth_time` and `amr` claims for consistency. --- example/client/app/app.go | 4 ++++ pkg/oidc/introspection.go | 27 +++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/example/client/app/app.go b/example/client/app/app.go index 9b43b8d..99aba3d 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -99,6 +99,10 @@ func main() { // for demonstration purposes the returned userinfo response is written as JSON object onto response marshalUserinfo := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[*oidc.IDTokenClaims], state string, rp rp.RelyingParty, info *oidc.UserInfo) { + fmt.Println("access token", tokens.AccessToken) + fmt.Println("refresh token", tokens.RefreshToken) + fmt.Println("id token", tokens.IDToken) + data, err := json.Marshal(info) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/pkg/oidc/introspection.go b/pkg/oidc/introspection.go index 8313dc4..1a200eb 100644 --- a/pkg/oidc/introspection.go +++ b/pkg/oidc/introspection.go @@ -16,18 +16,21 @@ type ClientAssertionParams struct { // https://www.rfc-editor.org/rfc/rfc7662.html#section-2.2. // https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims. type IntrospectionResponse struct { - Active bool `json:"active"` - Scope SpaceDelimitedArray `json:"scope,omitempty"` - ClientID string `json:"client_id,omitempty"` - TokenType string `json:"token_type,omitempty"` - Expiration Time `json:"exp,omitempty"` - IssuedAt Time `json:"iat,omitempty"` - NotBefore Time `json:"nbf,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - Issuer string `json:"iss,omitempty"` - JWTID string `json:"jti,omitempty"` - Username string `json:"username,omitempty"` + Active bool `json:"active"` + Scope SpaceDelimitedArray `json:"scope,omitempty"` + ClientID string `json:"client_id,omitempty"` + TokenType string `json:"token_type,omitempty"` + Expiration Time `json:"exp,omitempty"` + IssuedAt Time `json:"iat,omitempty"` + AuthTime Time `json:"auth_time,omitempty"` + NotBefore Time `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` + Audience Audience `json:"aud,omitempty"` + AuthenticationMethodsReferences []string `json:"amr,omitempty"` + Issuer string `json:"iss,omitempty"` + JWTID string `json:"jti,omitempty"` + Username string `json:"username,omitempty"` + Actor *ActorClaims `json:"act,omitempty"` UserInfoProfile UserInfoEmail UserInfoPhone From 910f55ea7bae83ec053de8218eeed6f65da46212 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 07:15:38 +0100 Subject: [PATCH 057/185] chore(deps): bump actions/add-to-project from 0.6.0 to 0.6.1 (#572) Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 0.6.0 to 0.6.1. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v0.6.0...v0.6.1) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index a2b56eb..1138d78 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: add issue - uses: actions/add-to-project@v0.6.0 + uses: actions/add-to-project@v0.6.1 if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization @@ -28,7 +28,7 @@ jobs: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr - uses: actions/add-to-project@v0.6.0 + uses: actions/add-to-project@v0.6.1 if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization From c89d0ed97073ca5d23e0a793efca80a9bfc9535e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lian=20GARCIA?= Date: Mon, 1 Apr 2024 15:55:22 +0200 Subject: [PATCH 058/185] feat: return oidc.Error in case of call token failure (#571) --- pkg/client/client.go | 21 +++------------------ pkg/http/http.go | 9 ++++++++- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 8b60264..78b412a 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -2,7 +2,6 @@ package client import ( "context" - "encoding/json" "errors" "fmt" "io" @@ -251,25 +250,11 @@ func CallDeviceAccessTokenEndpoint(ctx context.Context, request *DeviceAccessTok req.SetBasicAuth(request.ClientID, request.ClientSecret) } - httpResp, err := caller.HttpClient().Do(req) - if err != nil { + resp := new(oidc.AccessTokenResponse) + if err := httphelper.HttpRequest(caller.HttpClient(), req, &resp); err != nil { return nil, err } - defer httpResp.Body.Close() - - resp := new(struct { - *oidc.AccessTokenResponse - *oidc.Error - }) - if err = json.NewDecoder(httpResp.Body).Decode(resp); err != nil { - return nil, err - } - - if httpResp.StatusCode == http.StatusOK { - return resp.AccessTokenResponse, nil - } - - return nil, resp.Error + return resp, nil } func PollDeviceAccessTokenEndpoint(ctx context.Context, interval time.Duration, request *DeviceAccessTokenRequest, caller TokenEndpointCaller) (*oidc.AccessTokenResponse, error) { diff --git a/pkg/http/http.go b/pkg/http/http.go index fd196b0..33c5f15 100644 --- a/pkg/http/http.go +++ b/pkg/http/http.go @@ -10,6 +10,8 @@ import ( "net/url" "strings" "time" + + "github.com/zitadel/oidc/v3/pkg/oidc" ) var DefaultHTTPClient = &http.Client{ @@ -66,7 +68,12 @@ func HttpRequest(client *http.Client, req *http.Request, response any) error { } if resp.StatusCode != http.StatusOK { - return fmt.Errorf("http status not ok: %s %s", resp.Status, body) + var oidcErr oidc.Error + err = json.Unmarshal(body, &oidcErr) + if err != nil || oidcErr.ErrorType == "" { + return fmt.Errorf("http status not ok: %s %s", resp.Status, body) + } + return &oidcErr } err = json.Unmarshal(body, response) From d729c225265df9f307e82515fc332f553b0b440c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 07:58:28 +0200 Subject: [PATCH 059/185] chore(deps): bump codecov/codecov-action from 4.1.0 to 4.1.1 (#576) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a4a8f87..202596f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.1.0 + - uses: codecov/codecov-action@v4.1.1 with: file: ./profile.cov name: codecov-go From 5cdb65c30b5524716a8096bfbafa26a101fe3acf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 06:22:36 +0000 Subject: [PATCH 060/185] chore(deps): bump actions/add-to-project from 0.6.1 to 1.0.0 (#575) * chore(deps): bump actions/add-to-project from 0.6.1 to 1.0.0 Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 0.6.1 to 1.0.0. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v0.6.1...v1.0.0) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update issue.yml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Livio Spring --- .github/workflows/issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 1138d78..d328058 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: add issue - uses: actions/add-to-project@v0.6.1 + uses: actions/add-to-project@v1 if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization @@ -28,7 +28,7 @@ jobs: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr - uses: actions/add-to-project@v0.6.1 + uses: actions/add-to-project@v1 if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization From a3b73a6950a8b846a6912f64c2b4f5a12b506a83 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Wed, 3 Apr 2024 18:32:50 +0200 Subject: [PATCH 061/185] chore(workflow): fix action/add-to-project version (#578) --- .github/workflows/issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index d328058..5926c59 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: add issue - uses: actions/add-to-project@v1 + uses: actions/add-to-project@v1.0.0 if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization @@ -28,7 +28,7 @@ jobs: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr - uses: actions/add-to-project@v1 + uses: actions/add-to-project@v1.0.0 if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization From 370738772ac77348dd1ef3de9984edffb8857db3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:52:08 +0300 Subject: [PATCH 062/185] chore(deps): bump golang.org/x/oauth2 from 0.18.0 to 0.19.0 (#580) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.18.0 to 0.19.0. - [Commits](https://github.com/golang/oauth2/compare/v0.18.0...v0.19.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 5 +---- go.sum | 17 ++--------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index bd7a0e5..35350de 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.24.0 - golang.org/x/oauth2 v0.18.0 + golang.org/x/oauth2 v0.19.0 golang.org/x/text v0.14.0 ) @@ -27,7 +27,6 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect @@ -35,7 +34,5 @@ require ( golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sys v0.18.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 58029da..5a96136 100644 --- a/go.sum +++ b/go.sum @@ -14,13 +14,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -78,7 +73,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -89,8 +83,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= +golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -115,7 +109,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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= @@ -132,12 +125,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/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= From 33485b82baf39e91577f494396ce46bb7678a1fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:57:09 +0300 Subject: [PATCH 063/185] chore(deps): bump go.opentelemetry.io/otel from 1.24.0 to 1.25.0 (#584) Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.24.0 to 1.25.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.24.0...v1.25.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 35350de..c23916c 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.24.0 + go.opentelemetry.io/otel v1.25.0 golang.org/x/oauth2 v0.19.0 golang.org/x/text v0.14.0 ) @@ -29,8 +29,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.25.0 // indirect + go.opentelemetry.io/otel/trace v1.25.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/go.sum b/go.sum index 5a96136..179b21c 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,12 @@ github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= +go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= +go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= +go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= +go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= +go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= From e75a061807518e681dd803c38f1df5add504a7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9lian=20GARCIA?= Date: Mon, 8 Apr 2024 15:43:31 +0200 Subject: [PATCH 064/185] feat: support verification_url workaround for DeviceAuthorizationResponse unmarshal (#577) --- pkg/oidc/device_authorization.go | 22 ++++++++++++++++++++ pkg/oidc/device_authorization_test.go | 30 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 pkg/oidc/device_authorization_test.go diff --git a/pkg/oidc/device_authorization.go b/pkg/oidc/device_authorization.go index 68b8efa..a6417ba 100644 --- a/pkg/oidc/device_authorization.go +++ b/pkg/oidc/device_authorization.go @@ -1,5 +1,7 @@ package oidc +import "encoding/json" + // DeviceAuthorizationRequest implements // https://www.rfc-editor.org/rfc/rfc8628#section-3.1, // 3.1 Device Authorization Request. @@ -20,6 +22,26 @@ type DeviceAuthorizationResponse struct { Interval int `json:"interval,omitempty"` } +func (resp *DeviceAuthorizationResponse) UnmarshalJSON(data []byte) error { + type Alias DeviceAuthorizationResponse + aux := &struct { + // workaround misspelling of verification_uri + // https://stackoverflow.com/q/76696956/5690223 + // https://developers.google.com/identity/protocols/oauth2/limited-input-device?hl=fr#success-response + VerificationURL string `json:"verification_url"` + *Alias + }{ + Alias: (*Alias)(resp), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + if resp.VerificationURI == "" { + resp.VerificationURI = aux.VerificationURL + } + return nil +} + // DeviceAccessTokenRequest implements // https://www.rfc-editor.org/rfc/rfc8628#section-3.4, // Device Access Token Request. diff --git a/pkg/oidc/device_authorization_test.go b/pkg/oidc/device_authorization_test.go new file mode 100644 index 0000000..c4c6637 --- /dev/null +++ b/pkg/oidc/device_authorization_test.go @@ -0,0 +1,30 @@ +package oidc + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDeviceAuthorizationResponse_UnmarshalJSON(t *testing.T) { + jsonStr := `{ + "device_code": "deviceCode", + "user_code": "userCode", + "verification_url": "http://example.com/verify", + "expires_in": 3600, + "interval": 5 + }` + + expected := &DeviceAuthorizationResponse{ + DeviceCode: "deviceCode", + UserCode: "userCode", + VerificationURI: "http://example.com/verify", + ExpiresIn: 3600, + Interval: 5, + } + + var resp DeviceAuthorizationResponse + err := resp.UnmarshalJSON([]byte(jsonStr)) + assert.NoError(t, err) + assert.Equal(t, expected, &resp) +} From 8a21d3813610c0dc64b349de3d7d01b2480120f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:39:36 +0300 Subject: [PATCH 065/185] chore(deps): bump codecov/codecov-action from 4.1.1 to 4.2.0 (#585) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.1.1 to 4.2.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.1.1...v4.2.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 202596f..8f3c1da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.1.1 + - uses: codecov/codecov-action@v4.2.0 with: file: ./profile.cov name: codecov-go From 06f37f84c1a9263bab1a1350afdbd65502e4a0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Tue, 9 Apr 2024 15:02:31 +0200 Subject: [PATCH 066/185] fix: Fail safe, if optional endpoints are not given (#582) --- pkg/client/client.go | 23 +++++++++++++++++++---- pkg/client/errors.go | 5 +++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 pkg/client/errors.go diff --git a/pkg/client/client.go b/pkg/client/client.go index 78b412a..a65b7b8 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -10,7 +10,7 @@ import ( "strings" "time" - jose "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v3" "github.com/zitadel/logging" "github.com/zitadel/oidc/v3/pkg/crypto" httphelper "github.com/zitadel/oidc/v3/pkg/http" @@ -97,7 +97,12 @@ func CallEndSessionEndpoint(ctx context.Context, request any, authFn any, caller ctx, span := Tracer.Start(ctx, "CallEndSessionEndpoint") defer span.End() - req, err := httphelper.FormRequest(ctx, caller.GetEndSessionEndpoint(), request, Encoder, authFn) + endpoint := caller.GetEndSessionEndpoint() + if endpoint == "" { + return nil, fmt.Errorf("end session %w", ErrEndpointNotSet) + } + + req, err := httphelper.FormRequest(ctx, endpoint, request, Encoder, authFn) if err != nil { return nil, err } @@ -143,7 +148,12 @@ func CallRevokeEndpoint(ctx context.Context, request any, authFn any, caller Rev ctx, span := Tracer.Start(ctx, "CallRevokeEndpoint") defer span.End() - req, err := httphelper.FormRequest(ctx, caller.GetRevokeEndpoint(), request, Encoder, authFn) + endpoint := caller.GetRevokeEndpoint() + if endpoint == "" { + return fmt.Errorf("revoke %w", ErrEndpointNotSet) + } + + req, err := httphelper.FormRequest(ctx, endpoint, request, Encoder, authFn) if err != nil { return err } @@ -218,7 +228,12 @@ func CallDeviceAuthorizationEndpoint(ctx context.Context, request *oidc.ClientCr ctx, span := Tracer.Start(ctx, "CallDeviceAuthorizationEndpoint") defer span.End() - req, err := httphelper.FormRequest(ctx, caller.GetDeviceAuthorizationEndpoint(), request, Encoder, authFn) + endpoint := caller.GetDeviceAuthorizationEndpoint() + if endpoint == "" { + return nil, fmt.Errorf("device authorization %w", ErrEndpointNotSet) + } + + req, err := httphelper.FormRequest(ctx, endpoint, request, Encoder, authFn) if err != nil { return nil, err } diff --git a/pkg/client/errors.go b/pkg/client/errors.go new file mode 100644 index 0000000..47210e5 --- /dev/null +++ b/pkg/client/errors.go @@ -0,0 +1,5 @@ +package client + +import "errors" + +var ErrEndpointNotSet = errors.New("endpoint not set") From 33f8df7eb28f19fd27ffd8ad12390b3cc74a247a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 11 Apr 2024 18:13:30 +0300 Subject: [PATCH 067/185] feat(deps): update go-jose to v4 (#588) This change updates to go-jose v4, which was a new major release. jose.ParseSigned now expects the supported signing algorithms to be passed, on which we previously did our own check. As they use a dedicated type for this, the slice of string needs to be converted. The returned error also need to be handled in a non-standard way in order to stay compatible. For OIDC v4 we should use the jose.SignatureAlgorithm type directly and wrap errors, instead of returned static defined errors. Closes #583 --- example/server/storage/storage.go | 2 +- example/server/storage/storage_dynamic.go | 2 +- go.mod | 6 ++-- go.sum | 39 ++++------------------- internal/testutil/token.go | 2 +- pkg/client/client.go | 2 +- pkg/client/profile/jwt_profile.go | 2 +- pkg/client/rp/jwks.go | 2 +- pkg/client/rp/relying_party.go | 2 +- pkg/client/rp/verifier.go | 2 +- pkg/client/rp/verifier_test.go | 2 +- pkg/client/tokenexchange/tokenexchange.go | 2 +- pkg/crypto/hash.go | 2 +- pkg/crypto/sign.go | 2 +- pkg/oidc/keyset.go | 2 +- pkg/oidc/keyset_test.go | 2 +- pkg/oidc/token.go | 2 +- pkg/oidc/token_request.go | 2 +- pkg/oidc/token_test.go | 2 +- pkg/oidc/types.go | 2 +- pkg/oidc/verifier.go | 27 +++++++++++----- pkg/op/discovery.go | 2 +- pkg/op/discovery_test.go | 2 +- pkg/op/keys.go | 2 +- pkg/op/keys_test.go | 2 +- pkg/op/mock/authorizer.mock.impl.go | 2 +- pkg/op/mock/discovery.mock.go | 2 +- pkg/op/mock/signer.mock.go | 2 +- pkg/op/mock/storage.mock.go | 2 +- pkg/op/op.go | 2 +- pkg/op/signer.go | 2 +- pkg/op/storage.go | 2 +- pkg/op/verifier_jwt_profile.go | 2 +- 33 files changed, 58 insertions(+), 74 deletions(-) diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index b556828..d8b7a5d 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -11,7 +11,7 @@ import ( "sync" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/google/uuid" "github.com/zitadel/oidc/v3/pkg/oidc" diff --git a/example/server/storage/storage_dynamic.go b/example/server/storage/storage_dynamic.go index a08f60e..d112d71 100644 --- a/example/server/storage/storage_dynamic.go +++ b/example/server/storage/storage_dynamic.go @@ -4,7 +4,7 @@ import ( "context" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/oidc/v3/pkg/op" diff --git a/go.mod b/go.mod index c23916c..17efbc3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.0.12 - github.com/go-jose/go-jose/v3 v3.0.3 + github.com/go-jose/go-jose/v4 v4.0.1 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 @@ -31,8 +31,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.25.0 // indirect go.opentelemetry.io/otel/trace v1.25.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 179b21c..0f48ad9 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= -github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= +github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -16,7 +16,6 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= @@ -51,7 +50,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank= github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= @@ -64,22 +62,14 @@ go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1 go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -87,39 +77,22 @@ golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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-20220715151400-c0bba94af5f8/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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.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/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= 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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/testutil/token.go b/internal/testutil/token.go index 2dd788f..7ad8893 100644 --- a/internal/testutil/token.go +++ b/internal/testutil/token.go @@ -8,7 +8,7 @@ import ( "errors" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/muhlemmer/gu" "github.com/zitadel/oidc/v3/pkg/oidc" ) diff --git a/pkg/client/client.go b/pkg/client/client.go index a65b7b8..e17c70a 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v4" "github.com/zitadel/logging" "github.com/zitadel/oidc/v3/pkg/crypto" httphelper "github.com/zitadel/oidc/v3/pkg/http" diff --git a/pkg/client/profile/jwt_profile.go b/pkg/client/profile/jwt_profile.go index a24033c..060f390 100644 --- a/pkg/client/profile/jwt_profile.go +++ b/pkg/client/profile/jwt_profile.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "golang.org/x/oauth2" "github.com/zitadel/oidc/v3/pkg/client" diff --git a/pkg/client/rp/jwks.go b/pkg/client/rp/jwks.go index a061777..4a8c41b 100644 --- a/pkg/client/rp/jwks.go +++ b/pkg/client/rp/jwks.go @@ -7,7 +7,7 @@ import ( "net/http" "sync" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/zitadel/oidc/v3/pkg/client" httphelper "github.com/zitadel/oidc/v3/pkg/http" diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 62c650e..7075eb1 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -9,7 +9,7 @@ import ( "net/url" "time" - "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v4" "github.com/google/uuid" "golang.org/x/oauth2" "golang.org/x/oauth2/clientcredentials" diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index 94be079..5a07d8a 100644 --- a/pkg/client/rp/verifier.go +++ b/pkg/client/rp/verifier.go @@ -4,7 +4,7 @@ import ( "context" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/zitadel/oidc/v3/pkg/client" "github.com/zitadel/oidc/v3/pkg/oidc" diff --git a/pkg/client/rp/verifier_test.go b/pkg/client/rp/verifier_test.go index ea15c21..cd2fab4 100644 --- a/pkg/client/rp/verifier_test.go +++ b/pkg/client/rp/verifier_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tu "github.com/zitadel/oidc/v3/internal/testutil" diff --git a/pkg/client/tokenexchange/tokenexchange.go b/pkg/client/tokenexchange/tokenexchange.go index a2ea1bb..61975a4 100644 --- a/pkg/client/tokenexchange/tokenexchange.go +++ b/pkg/client/tokenexchange/tokenexchange.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v4" "github.com/zitadel/oidc/v3/pkg/client" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" diff --git a/pkg/crypto/hash.go b/pkg/crypto/hash.go index 0ed2774..ab9f8c1 100644 --- a/pkg/crypto/hash.go +++ b/pkg/crypto/hash.go @@ -8,7 +8,7 @@ import ( "fmt" "hash" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" ) var ErrUnsupportedAlgorithm = errors.New("unsupported signing algorithm") diff --git a/pkg/crypto/sign.go b/pkg/crypto/sign.go index a197955..937a846 100644 --- a/pkg/crypto/sign.go +++ b/pkg/crypto/sign.go @@ -4,7 +4,7 @@ import ( "encoding/json" "errors" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" ) func Sign(object any, signer jose.Signer) (string, error) { diff --git a/pkg/oidc/keyset.go b/pkg/oidc/keyset.go index 6031c01..833878d 100644 --- a/pkg/oidc/keyset.go +++ b/pkg/oidc/keyset.go @@ -7,7 +7,7 @@ import ( "crypto/rsa" "errors" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" ) const ( diff --git a/pkg/oidc/keyset_test.go b/pkg/oidc/keyset_test.go index f8641f2..e01074e 100644 --- a/pkg/oidc/keyset_test.go +++ b/pkg/oidc/keyset_test.go @@ -7,7 +7,7 @@ import ( "reflect" "testing" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" ) func TestFindKey(t *testing.T) { diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index 73eb2e5..8d2880c 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -5,7 +5,7 @@ import ( "os" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "golang.org/x/oauth2" "github.com/muhlemmer/gu" diff --git a/pkg/oidc/token_request.go b/pkg/oidc/token_request.go index b07b333..f3b2ec4 100644 --- a/pkg/oidc/token_request.go +++ b/pkg/oidc/token_request.go @@ -6,7 +6,7 @@ import ( "slices" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" ) const ( diff --git a/pkg/oidc/token_test.go b/pkg/oidc/token_test.go index 9f9ee2d..ccc3467 100644 --- a/pkg/oidc/token_test.go +++ b/pkg/oidc/token_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/stretchr/testify/assert" "golang.org/x/text/language" ) diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 0e7152c..e7292e6 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -9,7 +9,7 @@ import ( "strings" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/muhlemmer/gu" "github.com/zitadel/schema" "golang.org/x/text/language" diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index fe28857..410b383 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -10,7 +10,7 @@ import ( "strings" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" str "github.com/zitadel/oidc/v3/pkg/strings" ) @@ -148,8 +148,13 @@ func CheckAuthorizedParty(claims Claims, clientID string) error { } func CheckSignature(ctx context.Context, token string, payload []byte, claims ClaimsSignature, supportedSigAlgs []string, set KeySet) error { - jws, err := jose.ParseSigned(token) + jws, err := jose.ParseSigned(token, toJoseSignatureAlgorithms(supportedSigAlgs)) if err != nil { + if strings.HasPrefix(err.Error(), "go-jose/go-jose: unexpected signature algorithm") { + // TODO(v4): we should wrap errors instead of returning static ones. + // This is a workaround so we keep returning the same error for now. + return ErrSignatureUnsupportedAlg + } return ErrParse } if len(jws.Signatures) == 0 { @@ -159,12 +164,6 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl return ErrSignatureMultiple } sig := jws.Signatures[0] - if len(supportedSigAlgs) == 0 { - supportedSigAlgs = []string{"RS256"} - } - if !str.Contains(supportedSigAlgs, sig.Header.Algorithm) { - return fmt.Errorf("%w: id token signed with unsupported algorithm, expected %q got %q", ErrSignatureUnsupportedAlg, supportedSigAlgs, sig.Header.Algorithm) - } signedPayload, err := set.VerifySignature(ctx, jws) if err != nil { @@ -180,6 +179,18 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl return nil } +// TODO(v4): Use the new jose.SignatureAlgorithm type directly, instead of string. +func toJoseSignatureAlgorithms(algorithms []string) []jose.SignatureAlgorithm { + out := make([]jose.SignatureAlgorithm, len(algorithms)) + for i := range algorithms { + out[i] = jose.SignatureAlgorithm(algorithms[i]) + } + if len(out) == 0 { + out = append(out, jose.RS256) + } + return out +} + func CheckExpiration(claims Claims, offset time.Duration) error { expiration := claims.GetExpiration() if !time.Now().Add(offset).Before(expiration) { diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index 7b5ecbe..cd08580 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -4,7 +4,7 @@ import ( "context" "net/http" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" diff --git a/pkg/op/discovery_test.go b/pkg/op/discovery_test.go index 84e1216..cb4cfba 100644 --- a/pkg/op/discovery_test.go +++ b/pkg/op/discovery_test.go @@ -6,7 +6,7 @@ import ( "net/http/httptest" "testing" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/pkg/op/keys.go b/pkg/op/keys.go index d55c8d1..c96c456 100644 --- a/pkg/op/keys.go +++ b/pkg/op/keys.go @@ -4,7 +4,7 @@ import ( "context" "net/http" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" httphelper "github.com/zitadel/oidc/v3/pkg/http" ) diff --git a/pkg/op/keys_test.go b/pkg/op/keys_test.go index e1a3851..3662739 100644 --- a/pkg/op/keys_test.go +++ b/pkg/op/keys_test.go @@ -7,7 +7,7 @@ import ( "net/http/httptest" "testing" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" diff --git a/pkg/op/mock/authorizer.mock.impl.go b/pkg/op/mock/authorizer.mock.impl.go index ba5082f..59e8fa3 100644 --- a/pkg/op/mock/authorizer.mock.impl.go +++ b/pkg/op/mock/authorizer.mock.impl.go @@ -4,7 +4,7 @@ import ( "context" "testing" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/golang/mock/gomock" "github.com/zitadel/schema" diff --git a/pkg/op/mock/discovery.mock.go b/pkg/op/mock/discovery.mock.go index c5d3d3a..a27f8ef 100644 --- a/pkg/op/mock/discovery.mock.go +++ b/pkg/op/mock/discovery.mock.go @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" gomock "github.com/golang/mock/gomock" ) diff --git a/pkg/op/mock/signer.mock.go b/pkg/op/mock/signer.mock.go index 15718e0..e1bab91 100644 --- a/pkg/op/mock/signer.mock.go +++ b/pkg/op/mock/signer.mock.go @@ -7,7 +7,7 @@ package mock import ( reflect "reflect" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" gomock "github.com/golang/mock/gomock" ) diff --git a/pkg/op/mock/storage.mock.go b/pkg/op/mock/storage.mock.go index a1ce598..02a7c5c 100644 --- a/pkg/op/mock/storage.mock.go +++ b/pkg/op/mock/storage.mock.go @@ -9,7 +9,7 @@ import ( reflect "reflect" time "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" gomock "github.com/golang/mock/gomock" oidc "github.com/zitadel/oidc/v3/pkg/oidc" op "github.com/zitadel/oidc/v3/pkg/op" diff --git a/pkg/op/op.go b/pkg/op/op.go index 3248317..9fd6b30 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -8,7 +8,7 @@ import ( "time" "github.com/go-chi/chi/v5" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/rs/cors" "github.com/zitadel/schema" "go.opentelemetry.io/otel" diff --git a/pkg/op/signer.go b/pkg/op/signer.go index b220739..5c3dd6a 100644 --- a/pkg/op/signer.go +++ b/pkg/op/signer.go @@ -3,7 +3,7 @@ package op import ( "errors" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" ) var ErrSignerCreationFailed = errors.New("signer creation failed") diff --git a/pkg/op/storage.go b/pkg/op/storage.go index a1a00ed..8488b28 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -5,7 +5,7 @@ import ( "errors" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/zitadel/oidc/v3/pkg/oidc" ) diff --git a/pkg/op/verifier_jwt_profile.go b/pkg/op/verifier_jwt_profile.go index ced99ad..06a7d34 100644 --- a/pkg/op/verifier_jwt_profile.go +++ b/pkg/op/verifier_jwt_profile.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - jose "github.com/go-jose/go-jose/v3" + jose "github.com/go-jose/go-jose/v4" "github.com/zitadel/oidc/v3/pkg/oidc" ) From 3fa4891f3e1ee55482212721499d6a6ab2ecd163 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:15:39 +0300 Subject: [PATCH 068/185] chore(deps): bump actions/add-to-project from 1.0.0 to 1.0.1 (#589) Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v1.0.0...v1.0.1) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 5926c59..5b1febf 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: add issue - uses: actions/add-to-project@v1.0.0 + uses: actions/add-to-project@v1.0.1 if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization @@ -28,7 +28,7 @@ jobs: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr - uses: actions/add-to-project@v1.0.0 + uses: actions/add-to-project@v1.0.1 if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization From a77d773ca3dee5ec73dd96aed99bb303a0d66406 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 08:16:57 +0000 Subject: [PATCH 069/185] chore(deps): bump codecov/codecov-action from 4.2.0 to 4.3.0 (#590) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8f3c1da..a6d3826 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.2.0 + - uses: codecov/codecov-action@v4.3.0 with: file: ./profile.cov name: codecov-go From 959376bde763f958f3f430b6534de73fd700d7a7 Mon Sep 17 00:00:00 2001 From: Ethan Heilman Date: Tue, 16 Apr 2024 04:18:32 -0400 Subject: [PATCH 070/185] Fixes typos in GoDoc and comments (#591) --- example/server/exampleop/op.go | 2 +- pkg/client/rp/relying_party.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/server/exampleop/op.go b/example/server/exampleop/op.go index 893628e..e502536 100644 --- a/example/server/exampleop/op.go +++ b/example/server/exampleop/op.go @@ -56,7 +56,7 @@ func SetupServer(issuer string, storage Storage, logger *slog.Logger, wrapServer // for simplicity, we provide a very small default page for users who have signed out router.HandleFunc(pathLoggedOut, func(w http.ResponseWriter, req *http.Request) { w.Write([]byte("signed out successfully")) - // no need to check/log error, this will be handeled by the middleware. + // no need to check/log error, this will be handled by the middleware. }) // creation of the OpenIDProvider with the just created in-memory Storage diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 7075eb1..bd2041b 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -60,7 +60,7 @@ type RelyingParty interface { // UserinfoEndpoint returns the userinfo UserinfoEndpoint() string - // GetDeviceAuthorizationEndpoint returns the enpoint which can + // GetDeviceAuthorizationEndpoint returns the endpoint which can // be used to start a DeviceAuthorization flow. GetDeviceAuthorizationEndpoint() string @@ -388,7 +388,7 @@ func AuthURL(state string, rp RelyingParty, opts ...AuthURLOpt) string { // AuthURLHandler extends the `AuthURL` method with a http redirect handler // including handling setting cookie for secure `state` transfer. -// Custom paramaters can optionally be set to the redirect URL. +// Custom parameters can optionally be set to the redirect URL. func AuthURLHandler(stateFn func() string, rp RelyingParty, urlParam ...URLParamOpt) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { opts := make([]AuthURLOpt, len(urlParam)) @@ -642,7 +642,7 @@ func GetEndpoints(discoveryConfig *oidc.DiscoveryConfiguration) Endpoints { } } -// withURLParam sets custom url paramaters. +// withURLParam sets custom url parameters. // This is the generalized, unexported, function used by both // URLParamOpt and AuthURLOpt. func withURLParam(key, value string) func() []oauth2.AuthCodeOption { @@ -734,7 +734,7 @@ type RefreshTokenRequest struct { // the old one should be considered invalid. // // In case the RP is not OAuth2 only and an IDToken was part of the response, -// the IDToken and AccessToken will be verfied +// the IDToken and AccessToken will be verified // and the IDToken and IDTokenClaims fields will be populated in the returned object. func RefreshTokens[C oidc.IDClaims](ctx context.Context, rp RelyingParty, refreshToken, clientAssertion, clientAssertionType string) (*oidc.Tokens[C], error) { ctx, span := client.Tracer.Start(ctx, "RefreshTokens") From 68d4e08f6deb96fa7d39b32bf8484d72f782203d Mon Sep 17 00:00:00 2001 From: Kotaro Otaka <117251387+otakakot@users.noreply.github.com> Date: Tue, 16 Apr 2024 17:41:31 +0900 Subject: [PATCH 071/185] feat: Added the ability to verify ID tokens using the value of id_token_signing_alg_values_supported retrieved from DiscoveryEndpoint (#579) * feat(rp): to use signing algorithms from discovery configuration (#574) * feat: WithSigningAlgsFromDiscovery to verify IDTokenVerifier() behavior in RP with --- pkg/client/integration_test.go | 86 ++++++++++++++++++++++++++++++++++ pkg/client/rp/relying_party.go | 25 +++++++--- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/pkg/client/integration_test.go b/pkg/client/integration_test.go index 9145c1e..98a9d3a 100644 --- a/pkg/client/integration_test.go +++ b/pkg/client/integration_test.go @@ -111,6 +111,92 @@ func testRelyingPartySession(t *testing.T, wrapServer bool) { } } +func TestRelyingPartyWithSigningAlgsFromDiscovery(t *testing.T) { + targetURL := "http://local-site" + localURL, err := url.Parse(targetURL + "/login?requestID=1234") + require.NoError(t, err, "local url") + + t.Log("------- start example OP ------") + seed := rand.New(rand.NewSource(int64(os.Getpid()) + time.Now().UnixNano())) + clientID := t.Name() + "-" + strconv.FormatInt(seed.Int63(), 25) + clientSecret := "secret" + client := storage.WebClient(clientID, clientSecret, targetURL) + storage.RegisterClients(client) + exampleStorage := storage.NewStorage(storage.NewUserStore(targetURL)) + var dh deferredHandler + opServer := httptest.NewServer(&dh) + defer opServer.Close() + dh.Handler = exampleop.SetupServer(opServer.URL, exampleStorage, Logger, true) + + t.Log("------- create RP ------") + provider, err := rp.NewRelyingPartyOIDC( + CTX, + opServer.URL, + clientID, + clientSecret, + targetURL, + []string{"openid"}, + rp.WithSigningAlgsFromDiscovery(), + ) + require.NoError(t, err, "new rp") + + t.Log("------- run authorization code flow ------") + jar, err := cookiejar.New(nil) + require.NoError(t, err, "create cookie jar") + httpClient := &http.Client{ + Timeout: time.Second * 5, + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse + }, + Jar: jar, + } + state := "state-" + strconv.FormatInt(seed.Int63(), 25) + capturedW := httptest.NewRecorder() + get := httptest.NewRequest("GET", localURL.String(), nil) + rp.AuthURLHandler(func() string { return state }, provider, + rp.WithPromptURLParam("Hello, World!", "Goodbye, World!"), + rp.WithURLParam("custom", "param"), + )(capturedW, get) + defer func() { + if t.Failed() { + t.Log("response body (redirect from RP to OP)", capturedW.Body.String()) + } + }() + resp := capturedW.Result() + startAuthURL, err := resp.Location() + require.NoError(t, err, "get redirect") + loginPageURL := getRedirect(t, "get redirect to login page", httpClient, startAuthURL) + form := getForm(t, "get login form", httpClient, loginPageURL) + defer func() { + if t.Failed() { + t.Logf("login form (unfilled): %s", string(form)) + } + }() + postLoginRedirectURL := fillForm(t, "fill login form", httpClient, form, loginPageURL, + gosubmit.Set("username", "test-user@local-site"), + gosubmit.Set("password", "verysecure"), + ) + codeBearingURL := getRedirect(t, "get redirect with code", httpClient, postLoginRedirectURL) + capturedW = httptest.NewRecorder() + get = httptest.NewRequest("GET", codeBearingURL.String(), nil) + var idToken string + redirect := func(w http.ResponseWriter, r *http.Request, newTokens *oidc.Tokens[*oidc.IDTokenClaims], state string, rp rp.RelyingParty, info *oidc.UserInfo) { + idToken = newTokens.IDToken + http.Redirect(w, r, targetURL, http.StatusFound) + } + rp.CodeExchangeHandler(rp.UserinfoCallback(redirect), provider)(capturedW, get) + defer func() { + if t.Failed() { + t.Log("token exchange response body", capturedW.Body.String()) + require.GreaterOrEqual(t, capturedW.Code, 200, "captured response code") + } + }() + + t.Log("------- verify id token ------") + _, err = rp.VerifyIDToken[*oidc.IDTokenClaims](CTX, idToken, provider.IDTokenVerifier()) + require.NoError(t, err, "verify id token") +} + func TestResourceServerTokenExchange(t *testing.T) { for _, wrapServer := range []bool{false, true} { t.Run(fmt.Sprint("wrapServer ", wrapServer), func(t *testing.T) { diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index bd2041b..ac7f466 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -90,12 +90,13 @@ var DefaultUnauthorizedHandler UnauthorizedHandler = func(w http.ResponseWriter, } type relyingParty struct { - issuer string - DiscoveryEndpoint string - endpoints Endpoints - oauthConfig *oauth2.Config - oauth2Only bool - pkce bool + issuer string + DiscoveryEndpoint string + endpoints Endpoints + oauthConfig *oauth2.Config + oauth2Only bool + pkce bool + useSigningAlgsFromDiscovery bool httpClient *http.Client cookieHandler *httphelper.CookieHandler @@ -238,6 +239,9 @@ func NewRelyingPartyOIDC(ctx context.Context, issuer, clientID, clientSecret, re if err != nil { return nil, err } + if rp.useSigningAlgsFromDiscovery { + rp.verifierOpts = append(rp.verifierOpts, WithSupportedSigningAlgorithms(discoveryConfiguration.IDTokenSigningAlgValuesSupported...)) + } endpoints := GetEndpoints(discoveryConfiguration) rp.oauthConfig.Endpoint = endpoints.Endpoint rp.endpoints = endpoints @@ -348,6 +352,15 @@ func WithLogger(logger *slog.Logger) Option { } } +// WithSigningAlgsFromDiscovery appends the [WithSupportedSigningAlgorithms] option to the Verifier Options. +// The algorithms returned in the `id_token_signing_alg_values_supported` from the discovery response will be set. +func WithSigningAlgsFromDiscovery() Option { + return func(rp *relyingParty) error { + rp.useSigningAlgsFromDiscovery = true + return nil + } +} + type SignerFromKey func() (jose.Signer, error) func SignerFromKeyPath(path string) SignerFromKey { From 79daaf1a7aa81f94c308a92995bcaa408fb167d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:27:12 +0300 Subject: [PATCH 072/185] chore(deps): bump golang.org/x/net from 0.22.0 to 0.23.0 (#592) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 17efbc3..79c7b5b 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( go.opentelemetry.io/otel/metric v1.25.0 // indirect go.opentelemetry.io/otel/trace v1.25.0 // indirect golang.org/x/crypto v0.22.0 // indirect - golang.org/x/net v0.22.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/sys v0.19.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0f48ad9..a933e2f 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= From 3512c72f1c158e1c40157d84d50c97ecaa1d91d8 Mon Sep 17 00:00:00 2001 From: Kotaro Otaka <117251387+otakakot@users.noreply.github.com> Date: Mon, 22 Apr 2024 20:40:21 +0900 Subject: [PATCH 073/185] fix: to propagate context (#593) Co-authored-by: Livio Spring --- pkg/client/rp/jwks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/client/rp/jwks.go b/pkg/client/rp/jwks.go index 4a8c41b..c44a267 100644 --- a/pkg/client/rp/jwks.go +++ b/pkg/client/rp/jwks.go @@ -217,7 +217,7 @@ func (r *remoteKeySet) fetchRemoteKeys(ctx context.Context) ([]jose.JSONWebKey, ctx, span := client.Tracer.Start(ctx, "fetchRemoteKeys") defer span.End() - req, err := http.NewRequest("GET", r.jwksURL, nil) + req, err := http.NewRequestWithContext(ctx, "GET", r.jwksURL, nil) if err != nil { return nil, fmt.Errorf("oidc: can't create request: %v", err) } From 3e329dd0495b1e26aa5eda25969b096209db65f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:15:22 +0200 Subject: [PATCH 074/185] chore(deps): bump go.opentelemetry.io/otel from 1.25.0 to 1.26.0 (#595) Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.25.0 to 1.26.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.25.0...v1.26.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 79c7b5b..a715abb 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.25.0 + go.opentelemetry.io/otel v1.26.0 golang.org/x/oauth2 v0.19.0 golang.org/x/text v0.14.0 ) @@ -29,8 +29,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.25.0 // indirect - go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/trace v1.26.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index a933e2f..aae5a55 100644 --- a/go.sum +++ b/go.sum @@ -54,12 +54,12 @@ github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= From 099081fc1e4d455e56c3122b0f67fc6f76dde312 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 08:17:21 +0000 Subject: [PATCH 075/185] chore(deps): bump github.com/rs/cors from 1.10.1 to 1.11.0 (#596) Bumps [github.com/rs/cors](https://github.com/rs/cors) from 1.10.1 to 1.11.0. - [Commits](https://github.com/rs/cors/compare/v1.10.1...v1.11.0) --- updated-dependencies: - dependency-name: github.com/rs/cors dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a715abb..80e8933 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/jeremija/gosubmit v0.2.7 github.com/muhlemmer/gu v0.3.1 github.com/muhlemmer/httpforwarded v0.1.0 - github.com/rs/cors v1.10.1 + github.com/rs/cors v1.11.0 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 diff --git a/go.sum b/go.sum index aae5a55..2034402 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,8 @@ github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/ github.com/muhlemmer/httpforwarded v0.1.0/go.mod h1:yo9czKedo2pdZhoXe+yDkGVbU0TJ0q9oQ90BVoDEtw0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= -github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From 37ca0e472a239c6623d083c3d05052fe0b576237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 30 Apr 2024 20:27:12 +0300 Subject: [PATCH 076/185] feat(op): authorize callback handler as argument in legacy server registration (#598) This change requires an additional argument to the op.RegisterLegacyServer constructor which passes the Authorize Callback Handler. This allows implementations to use their own handler instead of the one provided by the package. The current handler is exported for legacy behavior. This change is not considered breaking, as RegisterLegacyServer is flagged experimental. Related to https://github.com/zitadel/zitadel/issues/6882 --- example/server/exampleop/op.go | 2 +- pkg/op/auth_request.go | 2 +- pkg/op/op.go | 2 +- pkg/op/server_http_routes_test.go | 2 +- pkg/op/server_legacy.go | 11 +++++------ 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/example/server/exampleop/op.go b/example/server/exampleop/op.go index e502536..e8ef892 100644 --- a/example/server/exampleop/op.go +++ b/example/server/exampleop/op.go @@ -80,7 +80,7 @@ func SetupServer(issuer string, storage Storage, logger *slog.Logger, wrapServer handler := http.Handler(provider) if wrapServer { - handler = op.RegisterLegacyServer(op.NewLegacyServer(provider, *op.DefaultEndpoints)) + handler = op.RegisterLegacyServer(op.NewLegacyServer(provider, *op.DefaultEndpoints), op.AuthorizeCallbackHandler(provider)) } // we register the http handler of the OP on the root, so that the discovery endpoint (/.well-known/openid-configuration) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 4b5837a..923b9a7 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -61,7 +61,7 @@ func authorizeHandler(authorizer Authorizer) func(http.ResponseWriter, *http.Req } } -func authorizeCallbackHandler(authorizer Authorizer) func(http.ResponseWriter, *http.Request) { +func AuthorizeCallbackHandler(authorizer Authorizer) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { AuthorizeCallback(w, r, authorizer) } diff --git a/pkg/op/op.go b/pkg/op/op.go index 9fd6b30..61c2449 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -135,7 +135,7 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) chi.Router router.HandleFunc(readinessEndpoint, readyHandler(o.Probes())) router.HandleFunc(oidc.DiscoveryEndpoint, discoveryHandler(o, o.Storage())) router.HandleFunc(o.AuthorizationEndpoint().Relative(), authorizeHandler(o)) - router.HandleFunc(authCallbackPath(o), authorizeCallbackHandler(o)) + router.HandleFunc(authCallbackPath(o), AuthorizeCallbackHandler(o)) router.HandleFunc(o.TokenEndpoint().Relative(), tokenHandler(o)) router.HandleFunc(o.IntrospectionEndpoint().Relative(), introspectionHandler(o)) router.HandleFunc(o.UserinfoEndpoint().Relative(), userinfoHandler(o)) diff --git a/pkg/op/server_http_routes_test.go b/pkg/op/server_http_routes_test.go index 8b3fa02..2c83ad3 100644 --- a/pkg/op/server_http_routes_test.go +++ b/pkg/op/server_http_routes_test.go @@ -32,7 +32,7 @@ func jwtProfile() (string, error) { } func TestServerRoutes(t *testing.T) { - server := op.RegisterLegacyServer(op.NewLegacyServer(testProvider, *op.DefaultEndpoints)) + server := op.RegisterLegacyServer(op.NewLegacyServer(testProvider, *op.DefaultEndpoints), op.AuthorizeCallbackHandler(testProvider)) storage := testProvider.Storage().(routesTestStorage) ctx := op.ContextWithIssuer(context.Background(), testIssuer) diff --git a/pkg/op/server_legacy.go b/pkg/op/server_legacy.go index 6b6d4b3..126fde1 100644 --- a/pkg/op/server_legacy.go +++ b/pkg/op/server_legacy.go @@ -22,17 +22,16 @@ type ExtendedLegacyServer interface { } // RegisterLegacyServer registers a [LegacyServer] or an extension thereof. -// It takes care of registering the IssuerFromRequest middleware -// and Authorization Callback Routes. +// It takes care of registering the IssuerFromRequest middleware. +// The authorizeCallbackHandler is registered on `/callback` under the authorization endpoint. // Neither are part of the bare [Server] interface. // // EXPERIMENTAL: may change until v4 -func RegisterLegacyServer(s ExtendedLegacyServer, options ...ServerOption) http.Handler { - provider := s.Provider() +func RegisterLegacyServer(s ExtendedLegacyServer, authorizeCallbackHandler http.HandlerFunc, options ...ServerOption) http.Handler { options = append(options, - WithHTTPMiddleware(intercept(provider.IssuerFromRequest)), + WithHTTPMiddleware(intercept(s.Provider().IssuerFromRequest)), WithSetRouter(func(r chi.Router) { - r.HandleFunc(s.Endpoints().Authorization.Relative()+authCallbackPathSuffix, authorizeCallbackHandler(provider)) + r.HandleFunc(s.Endpoints().Authorization.Relative()+authCallbackPathSuffix, authorizeCallbackHandler) }), ) return RegisterServer(s, s.Endpoints(), options...) From 24d43f538ebf85b8eb1884b5dac5fbec82a9c103 Mon Sep 17 00:00:00 2001 From: Yuval Marcus Date: Thu, 2 May 2024 03:46:12 -0400 Subject: [PATCH 077/185] fix: Handle case where verifier Nonce func is nil (#594) * Skip nonce check if verifier nonce func is nil * add unit test --- pkg/client/rp/verifier.go | 6 ++-- pkg/client/rp/verifier_test.go | 60 +++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index 5a07d8a..ca59454 100644 --- a/pkg/client/rp/verifier.go +++ b/pkg/client/rp/verifier.go @@ -73,8 +73,10 @@ func VerifyIDToken[C oidc.Claims](ctx context.Context, token string, v *IDTokenV return nilClaims, err } - if err = oidc.CheckNonce(claims, v.Nonce(ctx)); err != nil { - return nilClaims, err + if v.Nonce != nil { + if err = oidc.CheckNonce(claims, v.Nonce(ctx)); err != nil { + return nilClaims, err + } } if err = oidc.CheckAuthorizationContextClassReference(claims, v.ACR); err != nil { diff --git a/pkg/client/rp/verifier_test.go b/pkg/client/rp/verifier_test.go index cd2fab4..24d35af 100644 --- a/pkg/client/rp/verifier_test.go +++ b/pkg/client/rp/verifier_test.go @@ -100,22 +100,21 @@ func TestVerifyIDToken(t *testing.T) { MaxAge: 2 * time.Minute, ACR: tu.ACRVerify, Nonce: func(context.Context) string { return tu.ValidNonce }, + ClientID: tu.ValidClientID, } tests := []struct { - name string - clientID string - tokenClaims func() (string, *oidc.IDTokenClaims) - wantErr bool + name string + tokenClaims func() (string, *oidc.IDTokenClaims) + customVerifier func(verifier *IDTokenVerifier) + wantErr bool }{ { name: "success", - clientID: tu.ValidClientID, tokenClaims: tu.ValidIDToken, }, { - name: "custom claims", - clientID: tu.ValidClientID, + name: "custom claims", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDTokenCustom( tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, @@ -125,21 +124,31 @@ func TestVerifyIDToken(t *testing.T) { ) }, }, + { + name: "skip nonce check", + customVerifier: func(verifier *IDTokenVerifier) { + verifier.Nonce = nil + }, + tokenClaims: func() (string, *oidc.IDTokenClaims) { + return tu.NewIDToken( + tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, + tu.ValidExpiration, tu.ValidAuthTime, "foo", + tu.ValidACR, tu.ValidAMR, tu.ValidClientID, tu.ValidSkew, "", + ) + }, + }, { name: "parse err", - clientID: tu.ValidClientID, tokenClaims: func() (string, *oidc.IDTokenClaims) { return "~~~~", nil }, wantErr: true, }, { name: "invalid signature", - clientID: tu.ValidClientID, tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.InvalidSignatureToken, nil }, wantErr: true, }, { - name: "empty subject", - clientID: tu.ValidClientID, + name: "empty subject", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( tu.ValidIssuer, "", tu.ValidAudience, @@ -150,8 +159,7 @@ func TestVerifyIDToken(t *testing.T) { wantErr: true, }, { - name: "wrong issuer", - clientID: tu.ValidClientID, + name: "wrong issuer", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( "foo", tu.ValidSubject, tu.ValidAudience, @@ -162,14 +170,15 @@ func TestVerifyIDToken(t *testing.T) { wantErr: true, }, { - name: "wrong clientID", - clientID: "foo", + name: "wrong clientID", + customVerifier: func(verifier *IDTokenVerifier) { + verifier.ClientID = "foo" + }, tokenClaims: tu.ValidIDToken, wantErr: true, }, { - name: "expired", - clientID: tu.ValidClientID, + name: "expired", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, @@ -180,8 +189,7 @@ func TestVerifyIDToken(t *testing.T) { wantErr: true, }, { - name: "wrong IAT", - clientID: tu.ValidClientID, + name: "wrong IAT", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, @@ -192,8 +200,7 @@ func TestVerifyIDToken(t *testing.T) { wantErr: true, }, { - name: "wrong acr", - clientID: tu.ValidClientID, + name: "wrong acr", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, @@ -204,8 +211,7 @@ func TestVerifyIDToken(t *testing.T) { wantErr: true, }, { - name: "expired auth", - clientID: tu.ValidClientID, + name: "expired auth", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, @@ -216,8 +222,7 @@ func TestVerifyIDToken(t *testing.T) { wantErr: true, }, { - name: "wrong nonce", - clientID: tu.ValidClientID, + name: "wrong nonce", tokenClaims: func() (string, *oidc.IDTokenClaims) { return tu.NewIDToken( tu.ValidIssuer, tu.ValidSubject, tu.ValidAudience, @@ -231,7 +236,10 @@ func TestVerifyIDToken(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { token, want := tt.tokenClaims() - verifier.ClientID = tt.clientID + if tt.customVerifier != nil { + tt.customVerifier(verifier) + } + got, err := VerifyIDToken[*oidc.IDTokenClaims](context.Background(), token, verifier) if tt.wantErr { assert.Error(t, err) From 5a84d8c4bcf9236616081224f15f91eaae2d4538 Mon Sep 17 00:00:00 2001 From: Yuval Marcus Date: Mon, 6 May 2024 02:13:52 -0400 Subject: [PATCH 078/185] fix: Omit non-standard, empty fields in `RefreshTokenRequest` when performing a token refresh (#599) * Add omitempty tags * Add omitempty to more fields --- pkg/client/rp/relying_party.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index ac7f466..029a897 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -734,11 +734,11 @@ func (t tokenEndpointCaller) TokenEndpoint() string { type RefreshTokenRequest struct { RefreshToken string `schema:"refresh_token"` - Scopes oidc.SpaceDelimitedArray `schema:"scope"` - ClientID string `schema:"client_id"` - ClientSecret string `schema:"client_secret"` - ClientAssertion string `schema:"client_assertion"` - ClientAssertionType string `schema:"client_assertion_type"` + Scopes oidc.SpaceDelimitedArray `schema:"scope,omitempty"` + ClientID string `schema:"client_id,omitempty"` + ClientSecret string `schema:"client_secret,omitempty"` + ClientAssertion string `schema:"client_assertion,omitempty"` + ClientAssertionType string `schema:"client_assertion_type,omitempty"` GrantType oidc.GrantType `schema:"grant_type"` } From 30184ae0545c571a9f3b5537cacb8e60e888ac6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 06:41:53 +0000 Subject: [PATCH 079/185] chore(deps): bump golang.org/x/text from 0.14.0 to 0.15.0 (#600) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.14.0 to 0.15.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.14.0...v0.15.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Livio Spring --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 80e8933..4416887 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.26.0 golang.org/x/oauth2 v0.19.0 - golang.org/x/text v0.14.0 + golang.org/x/text v0.15.0 ) require ( diff --git a/go.sum b/go.sum index 2034402..4e3024a 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +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/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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From 20d0f189a85fe2bb00cdaaaa737333ea8b728213 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 06:44:21 +0000 Subject: [PATCH 080/185] chore(deps): bump golang.org/x/oauth2 from 0.19.0 to 0.20.0 (#601) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.19.0 to 0.20.0. - [Commits](https://github.com/golang/oauth2/compare/v0.19.0...v0.20.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4416887..7cf8a68 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.26.0 - golang.org/x/oauth2 v0.19.0 + golang.org/x/oauth2 v0.20.0 golang.org/x/text v0.15.0 ) diff --git a/go.sum b/go.sum index 4e3024a..14be2fc 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 6d1231cb37c27f29ed6fc52bb52d5e7e260ca2dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 07:58:56 +0200 Subject: [PATCH 081/185] chore(deps): bump codecov/codecov-action from 4.3.0 to 4.3.1 (#604) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.3.0 to 4.3.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.3.0...v4.3.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a6d3826..e149a84 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.3.0 + - uses: codecov/codecov-action@v4.3.1 with: file: ./profile.cov name: codecov-go From 7437309a42c70191dfdf63ab8713d1c8048e0a63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 10:56:21 +0200 Subject: [PATCH 082/185] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.1 to 4.0.2 (#608) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v4.0.1...v4.0.2) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7cf8a68..e00f653 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.0.12 - github.com/go-jose/go-jose/v4 v4.0.1 + github.com/go-jose/go-jose/v4 v4.0.2 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 14be2fc..fa16701 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= -github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= +github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= From 8a47532a8efa40edb765881ab128ce0a233c3af6 Mon Sep 17 00:00:00 2001 From: minami yoshihiko Date: Fri, 17 May 2024 19:17:54 +0900 Subject: [PATCH 083/185] feat: add default signature algorithms (#606) --- pkg/oidc/verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index 410b383..cb66676 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -186,7 +186,7 @@ func toJoseSignatureAlgorithms(algorithms []string) []jose.SignatureAlgorithm { out[i] = jose.SignatureAlgorithm(algorithms[i]) } if len(out) == 0 { - out = append(out, jose.RS256) + out = append(out, jose.RS256, jose.ES256, jose.PS256) } return out } From 7714a3b1137af89f87cae691189406600eddc785 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 12:56:32 +0200 Subject: [PATCH 084/185] --- (#609) updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e149a84..8beba66 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.3.1 + - uses: codecov/codecov-action@v4.4.1 with: file: ./profile.cov name: codecov-go From 7037344cf40cbc781532bca0f2eaa80aca8a6909 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 10:23:36 +0200 Subject: [PATCH 085/185] --- (#610) updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index e00f653..6cd07aa 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel v1.27.0 golang.org/x/oauth2 v0.20.0 golang.org/x/text v0.15.0 ) @@ -29,8 +29,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index fa16701..e70bbcf 100644 --- a/go.sum +++ b/go.sum @@ -54,12 +54,12 @@ github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= From 7a8f8ade4dd93239d9f697c3ac4d3d95dfa306de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jun 2024 10:14:04 +0200 Subject: [PATCH 086/185] chore(deps): bump golang.org/x/text from 0.15.0 to 0.16.0 (#612) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.15.0 to 0.16.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.15.0...v0.16.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6cd07aa..6ad9cb0 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.27.0 golang.org/x/oauth2 v0.20.0 - golang.org/x/text v0.15.0 + golang.org/x/text v0.16.0 ) require ( diff --git a/go.sum b/go.sum index e70bbcf..f81cd1b 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From 9ecdd0cf9a73bf339b737a6459b07aa0a251c603 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jun 2024 08:16:06 +0000 Subject: [PATCH 087/185] chore(deps): bump golang.org/x/oauth2 from 0.20.0 to 0.21.0 (#611) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.20.0 to 0.21.0. - [Commits](https://github.com/golang/oauth2/compare/v0.20.0...v0.21.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6ad9cb0..4f180c6 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.27.0 - golang.org/x/oauth2 v0.20.0 + golang.org/x/oauth2 v0.21.0 golang.org/x/text v0.16.0 ) diff --git a/go.sum b/go.sum index f81cd1b..4cb8219 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From a7b53555808637136ce591513282b7c9dae63131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 13 Jun 2024 08:16:46 +0200 Subject: [PATCH 088/185] feat(op): allow scope without openid (#613) This changes removes the requirement of the openid scope to be set for all token requests. As this library also support OAuth2-only authentication mechanisms we still want to sanitize requested scopes, but not enforce the openid scope. Related to https://github.com/zitadel/zitadel/discussions/8068 --- pkg/op/auth_request.go | 29 ++++++++--------------------- pkg/op/auth_request_test.go | 15 --------------- 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 923b9a7..fe73180 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -11,6 +11,7 @@ import ( "net" "net/http" "net/url" + "slices" "strings" "time" @@ -250,37 +251,23 @@ func ValidateAuthReqPrompt(prompts []string, maxAge *uint) (_ *uint, err error) return maxAge, nil } -// ValidateAuthReqScopes validates the passed scopes +// ValidateAuthReqScopes validates the passed scopes and deletes any unsupported scopes. +// An error is returned if scopes is empty. func ValidateAuthReqScopes(client Client, scopes []string) ([]string, error) { if len(scopes) == 0 { return nil, oidc.ErrInvalidRequest(). WithDescription("The scope of your request is missing. Please ensure some scopes are requested. " + "If you have any questions, you may contact the administrator of the application.") } - openID := false - for i := len(scopes) - 1; i >= 0; i-- { - scope := scopes[i] - if scope == oidc.ScopeOpenID { - openID = true - continue - } - if !(scope == oidc.ScopeProfile || + scopes = slices.DeleteFunc(scopes, func(scope string) bool { + return !(scope == oidc.ScopeOpenID || + scope == oidc.ScopeProfile || scope == oidc.ScopeEmail || scope == oidc.ScopePhone || scope == oidc.ScopeAddress || scope == oidc.ScopeOfflineAccess) && - !client.IsScopeAllowed(scope) { - scopes[i] = scopes[len(scopes)-1] - scopes[len(scopes)-1] = "" - scopes = scopes[:len(scopes)-1] - } - } - if !openID { - return nil, oidc.ErrInvalidScope().WithDescription("The scope openid is missing in your request. " + - "Please ensure the scope openid is added to the request. " + - "If you have any questions, you may contact the administrator of the application.") - } - + !client.IsScopeAllowed(scope) + }) return scopes, nil } diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 45627a5..6b4af17 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -137,11 +137,6 @@ func TestValidateAuthRequest(t *testing.T) { args{&oidc.AuthRequest{}, mock.NewMockStorageExpectValidClientID(t), nil}, oidc.ErrInvalidRequest(), }, - { - "scope openid missing fails", - args{&oidc.AuthRequest{Scopes: []string{"profile"}}, mock.NewMockStorageExpectValidClientID(t), nil}, - oidc.ErrInvalidScope(), - }, { "response_type missing fails", args{&oidc.AuthRequest{Scopes: []string{"openid"}}, mock.NewMockStorageExpectValidClientID(t), nil}, @@ -287,16 +282,6 @@ func TestValidateAuthReqScopes(t *testing.T) { err: true, }, }, - { - "scope openid missing fails", - args{ - mock.NewClientExpectAny(t, op.ApplicationTypeWeb), - []string{"email"}, - }, - res{ - err: true, - }, - }, { "scope ok", args{ From da4e683bd3a2d08206d4e7dd0e34423fec5e7419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 14 Jun 2024 07:40:05 +0200 Subject: [PATCH 089/185] fix(example): set content-type in the userinfo response (#614) This change sets the `content-type` header to `application/json` for the response sent to the browser in the app example. This enables pretty-printing of the userinfo json document in at least Chromium. --- example/client/app/app.go | 1 + 1 file changed, 1 insertion(+) diff --git a/example/client/app/app.go b/example/client/app/app.go index 99aba3d..448c530 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -108,6 +108,7 @@ func main() { http.Error(w, err.Error(), http.StatusInternalServerError) return } + w.Header().Set("content-type", "application/json") w.Write(data) } From 1c2dc2c0e1a8a0f20f8923363d4ddb5b35213ecf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:31:39 +0200 Subject: [PATCH 090/185] chore(deps): bump codecov/codecov-action from 4.4.1 to 4.5.0 (#615) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.4.1 to 4.5.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.4.1...v4.5.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8beba66..48690cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.4.1 + - uses: codecov/codecov-action@v4.5.0 with: file: ./profile.cov name: codecov-go From 371a5aaab4dd2a5e140e7b242553e72cbe5087fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Jun 2024 10:08:01 +0200 Subject: [PATCH 091/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.0.12 to 5.0.13 (#616) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.12 to 5.0.13. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.0.12...v5.0.13) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4f180c6..f85fa14 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 - github.com/go-chi/chi/v5 v5.0.12 + github.com/go-chi/chi/v5 v5.0.13 github.com/go-jose/go-jose/v4 v4.0.2 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index 4cb8219..1e6c057 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTS github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= -github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.13 h1:JlH2F2M8qnwl0N1+JFFzlX9TlKJYas3aPXdiuTmJL+w= +github.com/go-chi/chi/v5 v5.0.13/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From a09d9f7390c05ed5e3a63e4f84b533078a015ffb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 10:42:22 +0200 Subject: [PATCH 092/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.0.13 to 5.0.14 (#617) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.13 to 5.0.14. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.0.13...v5.0.14) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f85fa14..682ba30 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 - github.com/go-chi/chi/v5 v5.0.13 + github.com/go-chi/chi/v5 v5.0.14 github.com/go-jose/go-jose/v4 v4.0.2 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index 1e6c057..a6011da 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTS github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.0.13 h1:JlH2F2M8qnwl0N1+JFFzlX9TlKJYas3aPXdiuTmJL+w= -github.com/go-chi/chi/v5 v5.0.13/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.14 h1:PyEwo2Vudraa0x/Wl6eDRRW2NXBvekgfxyydcM0WGE0= +github.com/go-chi/chi/v5 v5.0.14/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From 954802b63b38599ae3d652b1e2a7b20f7a3224ab Mon Sep 17 00:00:00 2001 From: dkaminer Date: Thu, 27 Jun 2024 12:05:47 +0300 Subject: [PATCH 093/185] Updating indirect dependencies version in the OIDC GitHub library (#618) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit golang.org/x/crypto, Version: v0.22.0 -→ v0.24.0 golang.org/x/net, Version: v0.23.0 -→ v0.26.0 golang.org/x/sys, Version: v0.19.0 -→ v0.21.0 Co-authored-by: Daphna Kaminer --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 682ba30..da1adb1 100644 --- a/go.mod +++ b/go.mod @@ -31,8 +31,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.19.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a6011da..6db9376 100644 --- a/go.sum +++ b/go.sum @@ -62,16 +62,16 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -83,8 +83,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= From e87f433e099afabc8b10f5684ad142fc3d8b4a0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:20:28 +0300 Subject: [PATCH 094/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.0.14 to 5.1.0 (#619) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.14 to 5.1.0. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.0.14...v5.1.0) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index da1adb1..0bce56f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 - github.com/go-chi/chi/v5 v5.0.14 + github.com/go-chi/chi/v5 v5.1.0 github.com/go-jose/go-jose/v4 v4.0.2 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index 6db9376..19894c4 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTS github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.0.14 h1:PyEwo2Vudraa0x/Wl6eDRRW2NXBvekgfxyydcM0WGE0= -github.com/go-chi/chi/v5 v5.0.14/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From d6b4dc6b2f673b07a06e8fde3ee75ce1886f364e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:20:44 +0200 Subject: [PATCH 095/185] chore(deps): bump actions/add-to-project from 1.0.1 to 1.0.2 (#620) Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v1.0.1...v1.0.2) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 5b1febf..480c339 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: add issue - uses: actions/add-to-project@v1.0.1 + uses: actions/add-to-project@v1.0.2 if: ${{ github.event_name == 'issues' }} with: # You can target a repository in a different organization @@ -28,7 +28,7 @@ jobs: username: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.ADD_TO_PROJECT_PAT }} - name: add pr - uses: actions/add-to-project@v1.0.1 + uses: actions/add-to-project@v1.0.2 if: ${{ github.event_name == 'pull_request_target' && github.actor != 'dependabot[bot]' && !contains(steps.checkUserMember.outputs.teams, 'engineers')}} with: # You can target a repository in a different organization From fc6716bf22416fc339ce4ae254bbadf92739c0f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 08:32:12 +0200 Subject: [PATCH 096/185] chore(deps): bump go.opentelemetry.io/otel from 1.27.0 to 1.28.0 (#622) Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.27.0 to 1.28.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.27.0...v1.28.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 0bce56f..80906a4 100644 --- a/go.mod +++ b/go.mod @@ -18,19 +18,19 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.27.0 + go.opentelemetry.io/otel v1.28.0 golang.org/x/oauth2 v0.21.0 golang.org/x/text v0.16.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/crypto v0.24.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.21.0 // indirect diff --git a/go.sum b/go.sum index 19894c4..280feb7 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITL github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= @@ -54,12 +54,12 @@ github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= From e5a428d4be261ce6fac5bbd1183698c170289b36 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Tue, 9 Jul 2024 15:55:50 +0200 Subject: [PATCH 097/185] feat: support PKCS#8 (#623) --- pkg/client/client.go | 9 +-- pkg/crypto/key.go | 35 ++++++++++-- pkg/crypto/key_test.go | 122 ++++++++++++++++++++++++++++++++--------- pkg/oidc/token.go | 5 +- 4 files changed, 134 insertions(+), 37 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index e17c70a..990da9b 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -12,11 +12,12 @@ import ( "github.com/go-jose/go-jose/v4" "github.com/zitadel/logging" + "go.opentelemetry.io/otel" + "golang.org/x/oauth2" + "github.com/zitadel/oidc/v3/pkg/crypto" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - "go.opentelemetry.io/otel" - "golang.org/x/oauth2" ) var ( @@ -196,12 +197,12 @@ func CallTokenExchangeEndpoint(ctx context.Context, request any, authFn any, cal } func NewSignerFromPrivateKeyByte(key []byte, keyID string) (jose.Signer, error) { - privateKey, err := crypto.BytesToPrivateKey(key) + privateKey, algorithm, err := crypto.BytesToPrivateKey(key) if err != nil { return nil, err } signingKey := jose.SigningKey{ - Algorithm: jose.RS256, + Algorithm: algorithm, Key: &jose.JSONWebKey{Key: privateKey, KeyID: keyID}, } return jose.NewSigner(signingKey, &jose.SignerOptions{}) diff --git a/pkg/crypto/key.go b/pkg/crypto/key.go index 79e2046..12bca28 100644 --- a/pkg/crypto/key.go +++ b/pkg/crypto/key.go @@ -1,22 +1,45 @@ package crypto import ( + "crypto" + "crypto/ecdsa" + "crypto/ed25519" "crypto/rsa" "crypto/x509" "encoding/pem" "errors" + + "github.com/go-jose/go-jose/v4" ) -func BytesToPrivateKey(b []byte) (*rsa.PrivateKey, error) { +var ( + ErrPEMDecode = errors.New("PEM decode failed") + ErrUnsupportedFormat = errors.New("key is neither in PKCS#1 nor PKCS#8 format") + ErrUnsupportedPrivateKey = errors.New("unsupported key type, must be RSA, ECDSA or ED25519 private key") +) + +func BytesToPrivateKey(b []byte) (crypto.PublicKey, jose.SignatureAlgorithm, error) { block, _ := pem.Decode(b) if block == nil { - return nil, errors.New("PEM decode failed") + return nil, "", ErrPEMDecode } - key, err := x509.ParsePKCS1PrivateKey(block.Bytes) + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err == nil { + return privateKey, jose.RS256, nil + } + key, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { - return nil, err + return nil, "", ErrUnsupportedFormat + } + switch privateKey := key.(type) { + case *rsa.PrivateKey: + return privateKey, jose.RS256, nil + case ed25519.PrivateKey: + return privateKey, jose.EdDSA, nil + case *ecdsa.PrivateKey: + return privateKey, jose.ES256, nil + default: + return nil, "", ErrUnsupportedPrivateKey } - - return key, nil } diff --git a/pkg/crypto/key_test.go b/pkg/crypto/key_test.go index 23ebdc0..8ed5cb5 100644 --- a/pkg/crypto/key_test.go +++ b/pkg/crypto/key_test.go @@ -1,21 +1,64 @@ package crypto_test import ( + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" "testing" + "github.com/go-jose/go-jose/v4" "github.com/stretchr/testify/assert" - "github.com/zitadel/oidc/v3/pkg/crypto" + zcrypto "github.com/zitadel/oidc/v3/pkg/crypto" ) -func TestBytesToPrivateKey(tt *testing.T) { - tt.Run("PEMDecodeError", func(t *testing.T) { - _, err := crypto.BytesToPrivateKey([]byte("The non-PEM sequence")) - assert.EqualError(t, err, "PEM decode failed") - }) - - tt.Run("InvalidKeyFormat", func(t *testing.T) { - _, err := crypto.BytesToPrivateKey([]byte(`-----BEGIN PRIVATE KEY----- +func TestBytesToPrivateKey(t *testing.T) { + type args struct { + key []byte + } + type want struct { + key crypto.Signer + algorithm jose.SignatureAlgorithm + err error + } + tests := []struct { + name string + args args + want want + }{ + { + name: "PEMDecodeError", + args: args{ + key: []byte("The non-PEM sequence"), + }, + want: want{ + err: zcrypto.ErrPEMDecode, + }, + }, + { + name: "PKCS#1 RSA", + args: args{ + key: []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu +KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm +o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k +TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7 +9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy +v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs +/5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00 +-----END RSA PRIVATE KEY-----`), + }, + want: want{ + key: &rsa.PrivateKey{}, + algorithm: jose.RS256, + err: nil, + }, + }, + { + name: "PKCS#8 RSA", + args: args{ + key: []byte(`-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCfaDB7pK/fmP/I 7IusSK8lTCBnPZghqIbVLt2QHYAMoEF1CaF4F4rxo2vl1Mt8gwsq4T3osQFZMvnL YHb7KNyUoJgTjLxJQADv2u4Q3U38heAzK5Tp4ry4MCnuyJIqAPK1GiruwEq4zQrx @@ -42,21 +85,50 @@ srJnjF0H8oKmAY6hw+1Tm/n/b08p+RyL48TgVSE2vhUCgYA3BWpkD4PlCcn/FZsq OrLFyFXI6jIaxskFtsRW1IxxIlAdZmxfB26P/2gx6VjLdxJI/RRPkJyEN2dP7CbR BDjb565dy1O9D6+UrY70Iuwjz+OcALRBBGTaiF2pLn6IhSzNI2sy/tXX8q8dBlg9 OFCrqT/emes3KytTPfa5NZtYeQ== ------END PRIVATE KEY-----`)) - assert.EqualError(t, err, "x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)") - }) +-----END PRIVATE KEY-----`), + }, + want: want{ + key: &rsa.PrivateKey{}, + algorithm: jose.RS256, + err: nil, + }, + }, + { + name: "PKCS#8 ECDSA", + args: args{ + key: []byte(`-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgwwOZSU4GlP7ps/Wp +V6o0qRwxultdfYo/uUuj48QZjSuhRANCAATMiI2Han+ABKmrk5CNlxRAGC61w4d3 +G4TAeuBpyzqJ7x/6NjCxoQzJzZHtNjIfjVATI59XFZWF59GhtSZbShAr +-----END PRIVATE KEY-----`), + }, + want: want{ + key: &ecdsa.PrivateKey{}, + algorithm: jose.ES256, + err: nil, + }, + }, + { + name: "PKCS#8 ED25519", + args: args{ + key: []byte(`-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIHu6ZtDsjjauMasBxnS9Fg87UJwKfcT/oiq6S0ktbky8 +-----END PRIVATE KEY-----`), + }, + want: want{ + key: ed25519.PrivateKey{}, + algorithm: jose.EdDSA, + err: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + key, algorithm, err := zcrypto.BytesToPrivateKey(tt.args.key) + assert.IsType(t, tt.want.key, key) + assert.Equal(t, tt.want.algorithm, algorithm) + assert.ErrorIs(t, tt.want.err, err) + }) - tt.Run("Ok", func(t *testing.T) { - key, err := crypto.BytesToPrivateKey([]byte(`-----BEGIN RSA PRIVATE KEY----- -MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu -KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm -o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k -TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7 -9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy -v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs -/5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00 ------END RSA PRIVATE KEY-----`)) - assert.NoError(t, err) - assert.NotNil(t, key) - }) + } } diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index 8d2880c..5b18dac 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -9,6 +9,7 @@ import ( "golang.org/x/oauth2" "github.com/muhlemmer/gu" + "github.com/zitadel/oidc/v3/pkg/crypto" ) @@ -344,12 +345,12 @@ func AppendClientIDToAudience(clientID string, audience []string) []string { } func GenerateJWTProfileToken(assertion *JWTProfileAssertionClaims) (string, error) { - privateKey, err := crypto.BytesToPrivateKey(assertion.PrivateKey) + privateKey, algorithm, err := crypto.BytesToPrivateKey(assertion.PrivateKey) if err != nil { return "", err } key := jose.SigningKey{ - Algorithm: jose.RS256, + Algorithm: algorithm, Key: &jose.JSONWebKey{Key: privateKey, KeyID: assertion.PrivateKeyID}, } signer, err := jose.NewSigner(key, &jose.SignerOptions{}) From 7b8be4387a20a2ceeb5dfd7a229f308e1a6e01ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 13:37:53 +0200 Subject: [PATCH 098/185] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.2 to 4.0.3 (#624) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.2 to 4.0.3. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v4.0.2...v4.0.3) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 80906a4..c49ddb7 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.1.0 - github.com/go-jose/go-jose/v4 v4.0.2 + github.com/go-jose/go-jose/v4 v4.0.3 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 @@ -31,8 +31,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - golang.org/x/crypto v0.24.0 // indirect + golang.org/x/crypto v0.25.0 // indirect golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 280feb7..affa77e 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.3 h1:o8aphO8Hv6RPmH+GfzVuyf7YXSBibp+8YyHdOoDESGo= +github.com/go-jose/go-jose/v4 v4.0.3/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -62,8 +62,8 @@ go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+ go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -83,8 +83,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= From b9bcd6aef9c19673fa9ef942a41ef987bf825a56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:14:03 +0300 Subject: [PATCH 099/185] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.3 to 4.0.4 (#625) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.3 to 4.0.4. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v4.0.3...v4.0.4) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c49ddb7..a3b616b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/go-chi/chi/v5 v5.1.0 - github.com/go-jose/go-jose/v4 v4.0.3 + github.com/go-jose/go-jose/v4 v4.0.4 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index affa77e..ac8e156 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-jose/go-jose/v4 v4.0.3 h1:o8aphO8Hv6RPmH+GfzVuyf7YXSBibp+8YyHdOoDESGo= -github.com/go-jose/go-jose/v4 v4.0.3/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= From 8f80225a2039a9a4b504fbe1dbb0dde567ab2d13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 12:07:00 +0300 Subject: [PATCH 100/185] chore(deps): bump golang.org/x/oauth2 from 0.21.0 to 0.22.0 (#631) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.21.0 to 0.22.0. - [Commits](https://github.com/golang/oauth2/compare/v0.21.0...v0.22.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a3b616b..b5fa9c7 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.28.0 - golang.org/x/oauth2 v0.21.0 + golang.org/x/oauth2 v0.22.0 golang.org/x/text v0.16.0 ) diff --git a/go.sum b/go.sum index ac8e156..a857be9 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 6f0a630ad407ec6c1ad389d46a22d1bbef9313a1 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 6 Aug 2024 11:58:52 +0200 Subject: [PATCH 101/185] fix: overwrite redirect content length (#632) * fix: overwrite redirect content length * copy redirect struct headers --- pkg/op/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/op/server.go b/pkg/op/server.go index 829618c..6faee87 100644 --- a/pkg/op/server.go +++ b/pkg/op/server.go @@ -246,7 +246,7 @@ func NewRedirect(url string) *Redirect { } func (red *Redirect) writeOut(w http.ResponseWriter, r *http.Request) { - gu.MapMerge(r.Header, w.Header()) + gu.MapMerge(red.Header, w.Header()) http.Redirect(w, r, red.URL, http.StatusFound) } From b6f3b1e65b9142bd8b23342c0e2820841b2dac49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 9 Aug 2024 08:10:11 +0300 Subject: [PATCH 102/185] feat(op): allow returning of parent errors to client (#629) * feat(op): allow returning of parent errors to client * update godoc --------- Co-authored-by: Livio Spring --- pkg/oidc/error.go | 31 +++++++++++++++++++++++++++++++ pkg/oidc/error_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/pkg/oidc/error.go b/pkg/oidc/error.go index 2f0572d..1100f73 100644 --- a/pkg/oidc/error.go +++ b/pkg/oidc/error.go @@ -1,6 +1,7 @@ package oidc import ( + "encoding/json" "errors" "fmt" "log/slog" @@ -133,6 +134,24 @@ type Error struct { Description string `json:"error_description,omitempty" schema:"error_description,omitempty"` State string `json:"state,omitempty" schema:"state,omitempty"` redirectDisabled bool `schema:"-"` + returnParent bool `schema:"-"` +} + +func (e *Error) MarshalJSON() ([]byte, error) { + m := struct { + Error errorType `json:"error"` + ErrorDescription string `json:"error_description,omitempty"` + State string `json:"state,omitempty"` + Parent string `json:"parent,omitempty"` + }{ + Error: e.ErrorType, + ErrorDescription: e.Description, + State: e.State, + } + if e.returnParent { + m.Parent = e.Parent.Error() + } + return json.Marshal(m) } func (e *Error) Error() string { @@ -165,6 +184,18 @@ func (e *Error) WithParent(err error) *Error { return e } +// WithReturnParentToClient allows returning the set parent error to the HTTP client. +// Currently it only supports setting the parent inside JSON responses, not redirect URLs. +// As Go errors don't unmarshal well, only the marshaller is implemented for the moment. +// +// Warning: parent errors may contain sensitive data or unwanted details about the server status. +// Also, the `parent` field is not a standard error field and might confuse certain clients +// that require fully compliant responses. +func (e *Error) WithReturnParentToClient(b bool) *Error { + e.returnParent = b + return e +} + func (e *Error) WithDescription(desc string, args ...any) *Error { e.Description = fmt.Sprintf(desc, args...) return e diff --git a/pkg/oidc/error_test.go b/pkg/oidc/error_test.go index 2eeb4e6..40d30b1 100644 --- a/pkg/oidc/error_test.go +++ b/pkg/oidc/error_test.go @@ -1,11 +1,14 @@ package oidc import ( + "encoding/json" + "errors" "io" "log/slog" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDefaultToServerError(t *testing.T) { @@ -151,3 +154,39 @@ func TestError_LogValue(t *testing.T) { }) } } + +func TestError_MarshalJSON(t *testing.T) { + tests := []struct { + name string + e *Error + want string + }{ + { + name: "simple error", + e: ErrAccessDenied(), + want: `{"error":"access_denied","error_description":"The authorization request was denied."}`, + }, + { + name: "with description", + e: ErrAccessDenied().WithDescription("oops"), + want: `{"error":"access_denied","error_description":"oops"}`, + }, + { + name: "with parent", + e: ErrServerError().WithParent(errors.New("oops")), + want: `{"error":"server_error"}`, + }, + { + name: "with return parent", + e: ErrServerError().WithParent(errors.New("oops")).WithReturnParentToClient(true), + want: `{"error":"server_error","parent":"oops"}`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := json.Marshal(tt.e) + require.NoError(t, err) + assert.JSONEq(t, tt.want, string(got)) + }) + } +} From de034c8d24498884e82adf7027059dec80aafd95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:52:23 +0000 Subject: [PATCH 103/185] chore(deps): bump golang.org/x/text from 0.16.0 to 0.17.0 (#633) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.16.0 to 0.17.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b5fa9c7..6533530 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.28.0 golang.org/x/oauth2 v0.22.0 - golang.org/x/text v0.16.0 + golang.org/x/text v0.17.0 ) require ( diff --git a/go.sum b/go.sum index a857be9..19c1724 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From 0aa61b0b989fdfdecd02f923048ce80620a84d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 21 Aug 2024 10:29:14 +0300 Subject: [PATCH 104/185] fix(op): do not redirect to unverified uri on error (#640) Closes #627 --- pkg/op/auth_request.go | 48 +++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index fe73180..52fda2e 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -83,19 +83,27 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { if authReq.RequestParam != "" && authorizer.RequestObjectSupported() { err = ParseRequestObject(ctx, authReq, authorizer.Storage(), IssuerFromContext(ctx)) if err != nil { - AuthRequestError(w, r, authReq, err, authorizer) + AuthRequestError(w, r, nil, err, authorizer) return } } if authReq.ClientID == "" { - AuthRequestError(w, r, authReq, fmt.Errorf("auth request is missing client_id"), authorizer) + AuthRequestError(w, r, nil, fmt.Errorf("auth request is missing client_id"), authorizer) return } if authReq.RedirectURI == "" { - AuthRequestError(w, r, authReq, fmt.Errorf("auth request is missing redirect_uri"), authorizer) + AuthRequestError(w, r, nil, fmt.Errorf("auth request is missing redirect_uri"), authorizer) return } - validation := ValidateAuthRequest + + var client Client + validation := func(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error) { + client, err = authorizer.Storage().GetClientByClientID(ctx, authReq.ClientID) + if err != nil { + return "", oidc.ErrInvalidRequestRedirectURI().WithDescription("unable to retrieve client by id").WithParent(err) + } + return ValidateAuthRequestClient(ctx, authReq, client, verifier) + } if validater, ok := authorizer.(AuthorizeValidator); ok { validation = validater.ValidateAuthRequest } @@ -113,11 +121,6 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { AuthRequestError(w, r, authReq, oidc.DefaultToServerError(err, "unable to save auth request"), authorizer) return } - client, err := authorizer.Storage().GetClientByClientID(ctx, req.GetClientID()) - if err != nil { - AuthRequestError(w, r, req, oidc.DefaultToServerError(err, "unable to retrieve client by id"), authorizer) - return - } RedirectToLogin(req.GetID(), client, w, r) } @@ -212,26 +215,37 @@ func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oi authReq.RequestParam = "" } -// ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed +// ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed. +// +// Deprecated: Use [ValidateAuthRequestClient] to prevent querying for the Client twice. func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier *IDTokenHintVerifier) (sub string, err error) { ctx, span := tracer.Start(ctx, "ValidateAuthRequest") defer span.End() + client, err := storage.GetClientByClientID(ctx, authReq.ClientID) + if err != nil { + return "", oidc.ErrInvalidRequestRedirectURI().WithDescription("unable to retrieve client by id").WithParent(err) + } + return ValidateAuthRequestClient(ctx, authReq, client, verifier) +} + +// ValidateAuthRequestClient validates the Auth request against the passed client. +// If id_token_hint is part of the request, the subject of the token is returned. +func ValidateAuthRequestClient(ctx context.Context, authReq *oidc.AuthRequest, client Client, verifier *IDTokenHintVerifier) (sub string, err error) { + ctx, span := tracer.Start(ctx, "ValidateAuthRequestClient") + defer span.End() + + if err := ValidateAuthReqRedirectURI(client, authReq.RedirectURI, authReq.ResponseType); err != nil { + return "", err + } authReq.MaxAge, err = ValidateAuthReqPrompt(authReq.Prompt, authReq.MaxAge) if err != nil { return "", err } - client, err := storage.GetClientByClientID(ctx, authReq.ClientID) - if err != nil { - return "", oidc.DefaultToServerError(err, "unable to retrieve client by id") - } authReq.Scopes, err = ValidateAuthReqScopes(client, authReq.Scopes) if err != nil { return "", err } - if err := ValidateAuthReqRedirectURI(client, authReq.RedirectURI, authReq.ResponseType); err != nil { - return "", err - } if err := ValidateAuthReqResponseType(client, authReq.ResponseType); err != nil { return "", err } From 99301930edd3e37083107f8ca0685f446ef0d5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 21 Aug 2024 10:32:13 +0300 Subject: [PATCH 105/185] feat(crypto): hash algorithm for EdDSA (#638) * feat(crypto): hash algorithm for EdDSA * update code comment * rp: modify keytype check to support EdDSA * example: signing algs from discovery --------- Co-authored-by: Livio Spring --- example/client/app/app.go | 1 + pkg/crypto/hash.go | 8 ++++++++ pkg/oidc/keyset.go | 17 +++++++++-------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/example/client/app/app.go b/example/client/app/app.go index 448c530..0b9b19d 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -56,6 +56,7 @@ func main() { rp.WithVerifierOpts(rp.WithIssuedAtOffset(5 * time.Second)), rp.WithHTTPClient(client), rp.WithLogger(logger), + rp.WithSigningAlgsFromDiscovery(), } if clientSecret == "" { options = append(options, rp.WithPKCE(cookieHandler)) diff --git a/pkg/crypto/hash.go b/pkg/crypto/hash.go index ab9f8c1..14acdee 100644 --- a/pkg/crypto/hash.go +++ b/pkg/crypto/hash.go @@ -21,6 +21,14 @@ func GetHashAlgorithm(sigAlgorithm jose.SignatureAlgorithm) (hash.Hash, error) { return sha512.New384(), nil case jose.RS512, jose.ES512, jose.PS512: return sha512.New(), nil + + // There is no published spec for this yet, but we have confirmation it will get published. + // There is consensus here: https://bitbucket.org/openid/connect/issues/1125/_hash-algorithm-for-eddsa-id-tokens + // Currently Go and go-jose only supports the ed25519 curve key for EdDSA, so we can safely assume sha512 here. + // It is unlikely ed448 will ever be supported: https://github.com/golang/go/issues/29390 + case jose.EdDSA: + return sha512.New(), nil + default: return nil, fmt.Errorf("%w: %q", ErrUnsupportedAlgorithm, sigAlgorithm) } diff --git a/pkg/oidc/keyset.go b/pkg/oidc/keyset.go index 833878d..a8b89b0 100644 --- a/pkg/oidc/keyset.go +++ b/pkg/oidc/keyset.go @@ -6,6 +6,7 @@ import ( "crypto/ed25519" "crypto/rsa" "errors" + "strings" jose "github.com/go-jose/go-jose/v4" ) @@ -92,17 +93,17 @@ func FindMatchingKey(keyID, use, expectedAlg string, keys ...jose.JSONWebKey) (k } func algToKeyType(key any, alg string) bool { - switch alg[0] { - case 'R', 'P': + if strings.HasPrefix(alg, "RS") || strings.HasPrefix(alg, "PS") { _, ok := key.(*rsa.PublicKey) return ok - case 'E': + } + if strings.HasPrefix(alg, "ES") { _, ok := key.(*ecdsa.PublicKey) return ok - case 'O': - _, ok := key.(*ed25519.PublicKey) - return ok - default: - return false } + if alg == string(jose.EdDSA) { + _, ok := key.(ed25519.PublicKey) + return ok + } + return false } From 1e75773eaadb655ea96cf37bc3f35ee2666f5a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 21 Aug 2024 10:34:26 +0300 Subject: [PATCH 106/185] fix(op): initialize http Headers in response objects (#637) * fix(op): initialize http Headers in response objects * fix test --------- Co-authored-by: Livio Spring --- pkg/op/error_test.go | 3 ++- pkg/op/server.go | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/op/error_test.go b/pkg/op/error_test.go index 170039c..107f9d0 100644 --- a/pkg/op/error_test.go +++ b/pkg/op/error_test.go @@ -428,7 +428,8 @@ func TestTryErrorRedirect(t *testing.T) { parent: oidc.ErrInteractionRequired().WithDescription("sign in"), }, want: &Redirect{ - URL: "http://example.com/callback?error=interaction_required&error_description=sign+in&state=state1", + Header: make(http.Header), + URL: "http://example.com/callback?error=interaction_required&error_description=sign+in&state=state1", }, wantLog: `{ "level":"WARN", diff --git a/pkg/op/server.go b/pkg/op/server.go index 6faee87..b500e43 100644 --- a/pkg/op/server.go +++ b/pkg/op/server.go @@ -218,7 +218,8 @@ type Response struct { // without custom headers. func NewResponse(data any) *Response { return &Response{ - Data: data, + Header: make(http.Header), + Data: data, } } @@ -242,7 +243,10 @@ type Redirect struct { } func NewRedirect(url string) *Redirect { - return &Redirect{URL: url} + return &Redirect{ + Header: make(http.Header), + URL: url, + } } func (red *Redirect) writeOut(w http.ResponseWriter, r *http.Request) { From 67688db4c114c5b5595bf4ec784f15a74415413a Mon Sep 17 00:00:00 2001 From: David Sharnoff Date: Mon, 26 Aug 2024 01:11:01 -0700 Subject: [PATCH 107/185] fix: client assertions for Okta (#636) * fix client assertions for Okta * review feedback --- pkg/client/rp/relying_party.go | 2 +- pkg/oidc/token_request.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index 029a897..e6fa078 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -541,7 +541,7 @@ func CodeExchangeHandler[C oidc.IDClaims](callback CodeExchangeCallback[C], rp R rp.CookieHandler().DeleteCookie(w, pkceCode) } if rp.Signer() != nil { - assertion, err := client.SignedJWTProfileAssertion(rp.OAuthConfig().ClientID, []string{rp.Issuer()}, time.Hour, rp.Signer()) + assertion, err := client.SignedJWTProfileAssertion(rp.OAuthConfig().ClientID, []string{rp.Issuer(), rp.OAuthConfig().Endpoint.TokenURL}, time.Hour, rp.Signer()) if err != nil { unauthorizedError(w, r, "failed to build assertion: "+err.Error(), state, rp) return diff --git a/pkg/oidc/token_request.go b/pkg/oidc/token_request.go index f3b2ec4..dadb205 100644 --- a/pkg/oidc/token_request.go +++ b/pkg/oidc/token_request.go @@ -72,10 +72,10 @@ type AccessTokenRequest struct { Code string `schema:"code"` RedirectURI string `schema:"redirect_uri"` ClientID string `schema:"client_id"` - ClientSecret string `schema:"client_secret"` - CodeVerifier string `schema:"code_verifier"` - ClientAssertion string `schema:"client_assertion"` - ClientAssertionType string `schema:"client_assertion_type"` + ClientSecret string `schema:"client_secret,omitempty"` + CodeVerifier string `schema:"code_verifier,omitempty"` + ClientAssertion string `schema:"client_assertion,omitempty"` + ClientAssertionType string `schema:"client_assertion_type,omitempty"` } func (a *AccessTokenRequest) GrantType() GrantType { From 52e8b651d36e638d462a00162af7fab16cb74734 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 08:13:38 +0000 Subject: [PATCH 108/185] chore(deps): bump go.opentelemetry.io/otel from 1.28.0 to 1.29.0 (#643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.28.0 to 1.29.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.28.0...v1.29.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tim Möhlmann --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 6533530..a4b91e7 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 - go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.22.0 golang.org/x/text v0.17.0 ) @@ -29,8 +29,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect golang.org/x/crypto v0.25.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.22.0 // indirect diff --git a/go.sum b/go.sum index 19c1724..5948e97 100644 --- a/go.sum +++ b/go.sum @@ -54,12 +54,12 @@ github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= From 5e464b4ed8d0fd765aa218d11f4f6bd53e1b7275 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 09:58:10 +0300 Subject: [PATCH 109/185] chore(deps): bump github.com/rs/cors from 1.11.0 to 1.11.1 (#645) Bumps [github.com/rs/cors](https://github.com/rs/cors) from 1.11.0 to 1.11.1. - [Commits](https://github.com/rs/cors/compare/v1.11.0...v1.11.1) --- updated-dependencies: - dependency-name: github.com/rs/cors dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a4b91e7..2fcdc8a 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/jeremija/gosubmit v0.2.7 github.com/muhlemmer/gu v0.3.1 github.com/muhlemmer/httpforwarded v0.1.0 - github.com/rs/cors v1.11.0 + github.com/rs/cors v1.11.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 github.com/zitadel/logging v0.6.0 diff --git a/go.sum b/go.sum index 5948e97..e78b896 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,8 @@ github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/ github.com/muhlemmer/httpforwarded v0.1.0/go.mod h1:yo9czKedo2pdZhoXe+yDkGVbU0TJ0q9oQ90BVoDEtw0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= -github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From e1633bdb931f39688b7a43be8318e5a86c71f3e7 Mon Sep 17 00:00:00 2001 From: lanseg Date: Tue, 3 Sep 2024 10:13:06 +0200 Subject: [PATCH 110/185] feat: Define redirect uris with env variables (#644) Co-authored-by: Andrey Rusakov --- example/server/exampleop/op.go | 9 --------- example/server/main.go | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/example/server/exampleop/op.go b/example/server/exampleop/op.go index e8ef892..8f55b0a 100644 --- a/example/server/exampleop/op.go +++ b/example/server/exampleop/op.go @@ -12,7 +12,6 @@ import ( "github.com/zitadel/logging" "golang.org/x/text/language" - "github.com/zitadel/oidc/v3/example/server/storage" "github.com/zitadel/oidc/v3/pkg/op" ) @@ -20,14 +19,6 @@ const ( pathLoggedOut = "/logged-out" ) -func init() { - storage.RegisterClients( - storage.NativeClient("native"), - storage.WebClient("web", "secret"), - storage.WebClient("api", "secret"), - ) -} - type Storage interface { op.Storage authenticate diff --git a/example/server/main.go b/example/server/main.go index a2ad190..da8e73f 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -5,6 +5,7 @@ import ( "log/slog" "net/http" "os" + "strings" "github.com/zitadel/oidc/v3/example/server/exampleop" "github.com/zitadel/oidc/v3/example/server/storage" @@ -16,6 +17,12 @@ func main() { //which gives us the issuer: http://localhost:9998/ issuer := fmt.Sprintf("http://localhost:%s/", port) + storage.RegisterClients( + storage.NativeClient("native", strings.Split(os.Getenv("REDIRECT_URI"), ",")...), + storage.WebClient("web", "secret"), + storage.WebClient("api", "secret"), + ) + // the OpenIDProvider interface needs a Storage interface handling various checks and state manipulations // this might be the layer for accessing your database // in this example it will be handled in-memory From 6c28e8cb4b912d5d56d70da77dc0dd8514437d44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:31:08 +0300 Subject: [PATCH 111/185] chore(deps): bump golang.org/x/oauth2 from 0.22.0 to 0.23.0 (#647) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.22.0 to 0.23.0. - [Commits](https://github.com/golang/oauth2/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2fcdc8a..9a64a1c 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.0 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 - golang.org/x/oauth2 v0.22.0 + golang.org/x/oauth2 v0.23.0 golang.org/x/text v0.17.0 ) diff --git a/go.sum b/go.sum index e78b896..d98c579 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 98c1ab755dafd7117ebbe76c4c42604b704e93ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:49:22 +0300 Subject: [PATCH 112/185] chore(deps): bump golang.org/x/text from 0.17.0 to 0.18.0 (#648) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.17.0 to 0.18.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.17.0...v0.18.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9a64a1c..c0b2b1a 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.23.0 - golang.org/x/text v0.17.0 + golang.org/x/text v0.18.0 ) require ( diff --git a/go.sum b/go.sum index d98c579..87d510a 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From b555396744ffca5af3d8ede409ec262d07b48be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 10 Sep 2024 12:50:54 +0300 Subject: [PATCH 113/185] fix(oidc): set client ID to access token JWT (#650) * fix(oidc): set client ID to access token JWT * fix test --- pkg/oidc/token.go | 1 + pkg/oidc/token_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index 5b18dac..a829df4 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -117,6 +117,7 @@ func NewAccessTokenClaims(issuer, subject string, audience []string, expiration Expiration: FromTime(expiration), IssuedAt: FromTime(now), NotBefore: FromTime(now), + ClientID: clientID, JWTID: jwtid, }, } diff --git a/pkg/oidc/token_test.go b/pkg/oidc/token_test.go index ccc3467..7847cb5 100644 --- a/pkg/oidc/token_test.go +++ b/pkg/oidc/token_test.go @@ -145,6 +145,7 @@ func TestNewAccessTokenClaims(t *testing.T) { Subject: "hello@me.com", Audience: Audience{"foo"}, Expiration: 12345, + ClientID: "foo", JWTID: "900", }, } From 3b64e792ed1c01daf6bb3320a8da4ffa346753c2 Mon Sep 17 00:00:00 2001 From: Ayato Date: Fri, 20 Sep 2024 18:33:28 +0900 Subject: [PATCH 114/185] feat(oidc): return defined error when discovery failed (#653) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(oidc): return defined error when discovery failed * Use errors.Join() to join errors Co-authored-by: Tim Möhlmann * Remove unnecessary field Co-authored-by: Tim Möhlmann * Fix order and message Co-authored-by: Tim Möhlmann * Fix error order * Simplify error assertion Co-authored-by: Tim Möhlmann --------- Co-authored-by: Tim Möhlmann --- pkg/client/client.go | 2 +- pkg/client/client_test.go | 18 +++++++++++------- pkg/oidc/verifier.go | 1 + 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 990da9b..56417b5 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -42,7 +42,7 @@ func Discover(ctx context.Context, issuer string, httpClient *http.Client, wellK discoveryConfig := new(oidc.DiscoveryConfiguration) err = httphelper.HttpRequest(httpClient, req, &discoveryConfig) if err != nil { - return nil, err + return nil, errors.Join(oidc.ErrDiscoveryFailed, err) } if logger, ok := logging.FromContext(ctx); ok { logger.Debug("discover", "config", discoveryConfig) diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index e06c825..1046941 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestDiscover(t *testing.T) { @@ -22,7 +23,7 @@ func TestDiscover(t *testing.T) { name string args args wantFields *wantFields - wantErr bool + wantErr error }{ { name: "spotify", // https://github.com/zitadel/oidc/issues/406 @@ -32,17 +33,20 @@ func TestDiscover(t *testing.T) { wantFields: &wantFields{ UILocalesSupported: true, }, - wantErr: false, + wantErr: nil, + }, + { + name: "discovery failed", + args: args{ + issuer: "https://example.com", + }, + wantErr: oidc.ErrDiscoveryFailed, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := Discover(context.Background(), tt.args.issuer, http.DefaultClient, tt.args.wellKnownUrl...) - if tt.wantErr { - assert.Error(t, err) - return - } - require.NoError(t, err) + require.ErrorIs(t, err, tt.wantErr) if tt.wantFields == nil { return } diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index cb66676..f580da6 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -41,6 +41,7 @@ type IDClaims interface { var ( ErrParse = errors.New("parsing of request failed") ErrIssuerInvalid = errors.New("issuer does not match") + ErrDiscoveryFailed = errors.New("OpenID Provider Configuration Discovery has failed") ErrSubjectMissing = errors.New("subject missing") ErrAudience = errors.New("audience is not valid") ErrAzpMissing = errors.New("authorized party is not set. If Token is valid for multiple audiences, azp must not be empty") From 61c3bb887b5827d9307b1302cb1d6cd5ab052337 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 12:46:21 +0200 Subject: [PATCH 115/185] chore(deps): bump github.com/zitadel/logging from 0.6.0 to 0.6.1 (#657) Bumps [github.com/zitadel/logging](https://github.com/zitadel/logging) from 0.6.0 to 0.6.1. - [Release notes](https://github.com/zitadel/logging/releases) - [Changelog](https://github.com/zitadel/logging/blob/main/.releaserc.js) - [Commits](https://github.com/zitadel/logging/compare/v0.6.0...v0.6.1) --- updated-dependencies: - dependency-name: github.com/zitadel/logging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c0b2b1a..041070b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/cors v1.11.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 - github.com/zitadel/logging v0.6.0 + github.com/zitadel/logging v0.6.1 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.23.0 diff --git a/go.sum b/go.sum index 87d510a..2ca1cfa 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank= -github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= +github.com/zitadel/logging v0.6.1 h1:Vyzk1rl9Kq9RCevcpX6ujUaTYFX43aa4LkvV1TvUk+Y= +github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= From 97d7b28fc080f9929e590ef1989880b0762e0098 Mon Sep 17 00:00:00 2001 From: cui fliter Date: Fri, 4 Oct 2024 19:56:57 +0800 Subject: [PATCH 116/185] fix: fix slice init length (#658) --- example/server/storage/oidc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index 9cd08d9..22c0295 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -121,7 +121,7 @@ func (a *AuthRequest) Done() bool { } func PromptToInternal(oidcPrompt oidc.SpaceDelimitedArray) []string { - prompts := make([]string, len(oidcPrompt)) + prompts := make([]string, 0, len(oidcPrompt)) for _, oidcPrompt := range oidcPrompt { switch oidcPrompt { case oidc.PromptNone, From 2abae36bd9b7c37c3d4c48cf07aa508ab78bfcef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:39:28 +0300 Subject: [PATCH 117/185] chore(deps): bump golang.org/x/text from 0.18.0 to 0.19.0 (#661) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.18.0 to 0.19.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.18.0...v0.19.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 041070b..caf84de 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.23.0 - golang.org/x/text v0.18.0 + golang.org/x/text v0.19.0 ) require ( diff --git a/go.sum b/go.sum index 2ca1cfa..8d4c0db 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From 5ae555e19136066760d02e10af451464c6a3e3c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 12:00:43 +0300 Subject: [PATCH 118/185] chore(deps): bump codecov/codecov-action from 4.5.0 to 4.6.0 (#662) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.5.0...v4.6.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 48690cf..66d68b6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.5.0 + - uses: codecov/codecov-action@v4.6.0 with: file: ./profile.cov name: codecov-go From 9f7cbb0dbfc39ce85ecb2f2024d6f20d44e8fcef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 14:12:28 +0300 Subject: [PATCH 119/185] chore(deps): bump github.com/bmatcuk/doublestar/v4 from 4.6.1 to 4.7.1 (#666) Bumps [github.com/bmatcuk/doublestar/v4](https://github.com/bmatcuk/doublestar) from 4.6.1 to 4.7.1. - [Release notes](https://github.com/bmatcuk/doublestar/releases) - [Commits](https://github.com/bmatcuk/doublestar/compare/v4.6.1...v4.7.1) --- updated-dependencies: - dependency-name: github.com/bmatcuk/doublestar/v4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index caf84de..f50972a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/zitadel/oidc/v3 go 1.21 require ( - github.com/bmatcuk/doublestar/v4 v4.6.1 + github.com/bmatcuk/doublestar/v4 v4.7.1 github.com/go-chi/chi/v5 v5.1.0 github.com/go-jose/go-jose/v4 v4.0.4 github.com/golang/mock v1.6.0 diff --git a/go.sum b/go.sum index 8d4c0db..91de9bf 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= -github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q= +github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 24869d281155064b0a4a6339ad641ba76bac6177 Mon Sep 17 00:00:00 2001 From: lanseg Date: Mon, 21 Oct 2024 20:59:28 +0200 Subject: [PATCH 120/185] feat(example): Allow configuring some parameters with env variables (#663) Co-authored-by: Andrey Rusakov --- README.md | 38 ++++++++++++-- example/server/config/config.go | 40 +++++++++++++++ example/server/config/config_test.go | 77 ++++++++++++++++++++++++++++ example/server/main.go | 44 ++++++++++------ example/server/storage/user.go | 14 +++++ example/server/storage/user_test.go | 70 +++++++++++++++++++++++++ 6 files changed, 262 insertions(+), 21 deletions(-) create mode 100644 example/server/config/config.go create mode 100644 example/server/config/config_test.go create mode 100644 example/server/storage/user_test.go diff --git a/README.md b/README.md index 01d7d47..c1ff0aa 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Whenever possible we tried to reuse / extend existing packages like `OAuth2 for The most important packages of the library:
 /pkg
-    /client            clients using the OP for retrieving, exchanging and verifying tokens       
+    /client            clients using the OP for retrieving, exchanging and verifying tokens
         /rp            definition and implementation of an OIDC Relying Party (client)
         /rs            definition and implementation of an OAuth Resource Server (API)
     /op                definition and implementation of an OIDC OpenID Provider (server)
@@ -55,14 +55,14 @@ CLIENT_ID=web CLIENT_SECRET=secret ISSUER=http://localhost:9998/ SCOPES="openid
 ```
 
 - open http://localhost:9999/login in your browser
-- you will be redirected to op server and the login UI 
+- you will be redirected to op server and the login UI
 - login with user `test-user@localhost` and password `verysecure`
 - the OP will redirect you to the client app, which displays the user info
 
 for the dynamic issuer, just start it with:
 ```bash
 go run github.com/zitadel/oidc/v3/example/server/dynamic
-``` 
+```
 the oidc web client above will still work, but if you add `oidc.local` (pointing to 127.0.0.1) in your hosts file you can also start it with:
 ```bash
 CLIENT_ID=web CLIENT_SECRET=secret ISSUER=http://oidc.local:9998/ SCOPES="openid profile" PORT=9999 go run github.com/zitadel/oidc/v3/example/client/app
@@ -70,6 +70,36 @@ CLIENT_ID=web CLIENT_SECRET=secret ISSUER=http://oidc.local:9998/ SCOPES="openid
 
 > Note: Usernames are suffixed with the hostname (`test-user@localhost` or `test-user@oidc.local`)
 
+### Server configuration
+
+Example server allows extra configuration using environment variables and could be used for end to
+end testing of your services.
+
+| Name          | Format                               | Description                           |
+|---------------|--------------------------------------|---------------------------------------|
+| PORT          | Number between 1 and 65535           | OIDC listen port                      |
+| REDIRECT_URI  | Comma-separated URIs                 | List of allowed redirect URIs         |
+| USERS_FILE    | Path to json in local filesystem     | Users with their data and credentials |
+
+Here is json equivalent for one of the default users
+```json
+{
+    "id2": {
+        "ID":                "id2",
+        "Username":          "test-user2",
+        "Password":          "verysecure",
+        "FirstName":         "Test",
+        "LastName":          "User2",
+        "Email":             "test-user2@zitadel.ch",
+        "EmailVerified":     true,
+        "Phone":             "",
+        "PhoneVerified":     false,
+        "PreferredLanguage": "DE",
+        "IsAdmin":           false
+    }
+}
+```
+
 ## Features
 
 |                      | Relying party | OpenID Provider | Specification                             |
@@ -115,7 +145,7 @@ For your convenience you can find the relevant guides linked below.
 
 ## Supported Go Versions
 
-For security reasons, we only support and recommend the use of one of the latest two Go versions (:white_check_mark:).  
+For security reasons, we only support and recommend the use of one of the latest two Go versions (:white_check_mark:).
 Versions that also build are marked with :warning:.
 
 | Version | Supported          |
diff --git a/example/server/config/config.go b/example/server/config/config.go
new file mode 100644
index 0000000..96837d4
--- /dev/null
+++ b/example/server/config/config.go
@@ -0,0 +1,40 @@
+package config
+
+import (
+	"os"
+	"strings"
+)
+
+const (
+	// default port for the http server to run
+	DefaultIssuerPort = "9998"
+)
+
+type Config struct {
+	Port        string
+	RedirectURI []string
+	UsersFile   string
+}
+
+// FromEnvVars loads configuration parameters from environment variables.
+// If there is no such variable defined, then use default values.
+func FromEnvVars(defaults *Config) *Config {
+	if defaults == nil {
+		defaults = &Config{}
+	}
+	cfg := &Config{
+		Port:        defaults.Port,
+		RedirectURI: defaults.RedirectURI,
+		UsersFile:   defaults.UsersFile,
+	}
+	if value, ok := os.LookupEnv("PORT"); ok {
+		cfg.Port = value
+	}
+	if value, ok := os.LookupEnv("USERS_FILE"); ok {
+		cfg.UsersFile = value
+	}
+	if value, ok := os.LookupEnv("REDIRECT_URI"); ok {
+		cfg.RedirectURI = strings.Split(value, ",")
+	}
+	return cfg
+}
diff --git a/example/server/config/config_test.go b/example/server/config/config_test.go
new file mode 100644
index 0000000..3b73c0b
--- /dev/null
+++ b/example/server/config/config_test.go
@@ -0,0 +1,77 @@
+package config
+
+import (
+	"fmt"
+	"os"
+	"testing"
+)
+
+func TestFromEnvVars(t *testing.T) {
+
+	for _, tc := range []struct {
+		name     string
+		env      map[string]string
+		defaults *Config
+		want     *Config
+	}{
+		{
+			name: "no vars, no default values",
+			env:  map[string]string{},
+			want: &Config{},
+		},
+		{
+			name: "no vars, only defaults",
+			env:  map[string]string{},
+			defaults: &Config{
+				Port:        "6666",
+				UsersFile:   "/default/user/path",
+				RedirectURI: []string{"re", "direct", "uris"},
+			},
+			want: &Config{
+				Port:        "6666",
+				UsersFile:   "/default/user/path",
+				RedirectURI: []string{"re", "direct", "uris"},
+			},
+		},
+		{
+			name: "overriding default values",
+			env: map[string]string{
+				"PORT":         "1234",
+				"USERS_FILE":   "/path/to/users",
+				"REDIRECT_URI": "http://redirect/redirect",
+			},
+			defaults: &Config{
+				Port:        "6666",
+				UsersFile:   "/default/user/path",
+				RedirectURI: []string{"re", "direct", "uris"},
+			},
+			want: &Config{
+				Port:        "1234",
+				UsersFile:   "/path/to/users",
+				RedirectURI: []string{"http://redirect/redirect"},
+			},
+		},
+		{
+			name: "multiple redirect uris",
+			env: map[string]string{
+				"REDIRECT_URI": "http://host_1,http://host_2,http://host_3",
+			},
+			want: &Config{
+				RedirectURI: []string{
+					"http://host_1", "http://host_2", "http://host_3",
+				},
+			},
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			os.Clearenv()
+			for k, v := range tc.env {
+				os.Setenv(k, v)
+			}
+			cfg := FromEnvVars(tc.defaults)
+			if fmt.Sprint(cfg) != fmt.Sprint(tc.want) {
+				t.Errorf("Expected FromEnvVars()=%q, but got %q", tc.want, cfg)
+			}
+		})
+	}
+}
diff --git a/example/server/main.go b/example/server/main.go
index da8e73f..36816d6 100644
--- a/example/server/main.go
+++ b/example/server/main.go
@@ -5,20 +5,33 @@ import (
 	"log/slog"
 	"net/http"
 	"os"
-	"strings"
 
+	"github.com/zitadel/oidc/v3/example/server/config"
 	"github.com/zitadel/oidc/v3/example/server/exampleop"
 	"github.com/zitadel/oidc/v3/example/server/storage"
 )
 
+func getUserStore(cfg *config.Config) (storage.UserStore, error) {
+	if cfg.UsersFile == "" {
+		return storage.NewUserStore(fmt.Sprintf("http://localhost:%s/", cfg.Port)), nil
+	}
+	return storage.StoreFromFile(cfg.UsersFile)
+}
+
 func main() {
-	//we will run on :9998
-	port := "9998"
+	cfg := config.FromEnvVars(&config.Config{Port: "9998"})
+	logger := slog.New(
+		slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
+			AddSource: true,
+			Level:     slog.LevelDebug,
+		}),
+	)
+
 	//which gives us the issuer: http://localhost:9998/
-	issuer := fmt.Sprintf("http://localhost:%s/", port)
+	issuer := fmt.Sprintf("http://localhost:%s/", cfg.Port)
 
 	storage.RegisterClients(
-		storage.NativeClient("native", strings.Split(os.Getenv("REDIRECT_URI"), ",")...),
+		storage.NativeClient("native", cfg.RedirectURI...),
 		storage.WebClient("web", "secret"),
 		storage.WebClient("api", "secret"),
 	)
@@ -26,23 +39,20 @@ func main() {
 	// the OpenIDProvider interface needs a Storage interface handling various checks and state manipulations
 	// this might be the layer for accessing your database
 	// in this example it will be handled in-memory
-	storage := storage.NewStorage(storage.NewUserStore(issuer))
-
-	logger := slog.New(
-		slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
-			AddSource: true,
-			Level:     slog.LevelDebug,
-		}),
-	)
+	store, err := getUserStore(cfg)
+	if err != nil {
+		logger.Error("cannot create UserStore", "error", err)
+		os.Exit(1)
+	}
+	storage := storage.NewStorage(store)
 	router := exampleop.SetupServer(issuer, storage, logger, false)
 
 	server := &http.Server{
-		Addr:    ":" + port,
+		Addr:    ":" + cfg.Port,
 		Handler: router,
 	}
-	logger.Info("server listening, press ctrl+c to stop", "addr", fmt.Sprintf("http://localhost:%s/", port))
-	err := server.ListenAndServe()
-	if err != http.ErrServerClosed {
+	logger.Info("server listening, press ctrl+c to stop", "addr", issuer)
+	if server.ListenAndServe() != http.ErrServerClosed {
 		logger.Error("server terminated", "error", err)
 		os.Exit(1)
 	}
diff --git a/example/server/storage/user.go b/example/server/storage/user.go
index 173daef..ed8cdfa 100644
--- a/example/server/storage/user.go
+++ b/example/server/storage/user.go
@@ -2,6 +2,8 @@ package storage
 
 import (
 	"crypto/rsa"
+	"encoding/json"
+	"os"
 	"strings"
 
 	"golang.org/x/text/language"
@@ -35,6 +37,18 @@ type userStore struct {
 	users map[string]*User
 }
 
+func StoreFromFile(path string) (UserStore, error) {
+	users := map[string]*User{}
+	data, err := os.ReadFile(path)
+	if err != nil {
+		return nil, err
+	}
+	if err := json.Unmarshal(data, &users); err != nil {
+		return nil, err
+	}
+	return userStore{users}, nil
+}
+
 func NewUserStore(issuer string) UserStore {
 	hostname := strings.Split(strings.Split(issuer, "://")[1], ":")[0]
 	return userStore{
diff --git a/example/server/storage/user_test.go b/example/server/storage/user_test.go
new file mode 100644
index 0000000..c2e2212
--- /dev/null
+++ b/example/server/storage/user_test.go
@@ -0,0 +1,70 @@
+package storage
+
+import (
+	"os"
+	"path"
+	"reflect"
+	"testing"
+
+	"golang.org/x/text/language"
+)
+
+func TestStoreFromFile(t *testing.T) {
+	for _, tc := range []struct {
+		name       string
+		pathToFile string
+		content    string
+		want       UserStore
+		wantErr    bool
+	}{
+		{
+			name:       "normal user file",
+			pathToFile: "userfile.json",
+			content: `{
+				"id1": {
+					"ID":                "id1",
+					"EmailVerified":     true,
+					"PreferredLanguage": "DE"
+				}
+			}`,
+			want: userStore{map[string]*User{
+				"id1": {
+					ID:                "id1",
+					EmailVerified:     true,
+					PreferredLanguage: language.German,
+				},
+			}},
+		},
+		{
+			name:       "malformed file",
+			pathToFile: "whatever",
+			content:    "not a json just a text",
+			wantErr:    true,
+		},
+		{
+			name:       "not existing file",
+			pathToFile: "what/ever/file",
+			wantErr:    true,
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			actualPath := path.Join(t.TempDir(), tc.pathToFile)
+
+			if tc.content != "" && tc.pathToFile != "" {
+				if err := os.WriteFile(actualPath, []byte(tc.content), 0666); err != nil {
+					t.Fatalf("cannot create file with test content: %q", tc.content)
+				}
+			}
+			result, err := StoreFromFile(actualPath)
+			if err != nil && !tc.wantErr {
+				t.Errorf("StoreFromFile(%q) returned unexpected error %q", tc.pathToFile, err)
+			} else if err == nil && tc.wantErr {
+				t.Errorf("StoreFromFile(%q) did not return an expected error", tc.pathToFile)
+			}
+			if !tc.wantErr && !reflect.DeepEqual(tc.want, result.(userStore)) {
+				t.Errorf("expected StoreFromFile(%q) = %v, but got %v",
+					tc.pathToFile, tc.want, result)
+			}
+		})
+	}
+}

From f1e4cb22456afeb42d6d16d29a37231ad99224db Mon Sep 17 00:00:00 2001
From: Livio Spring 
Date: Wed, 30 Oct 2024 09:44:31 +0100
Subject: [PATCH 121/185] feat(OP): add back channel logout support (#671)

* feat: add configuration support for back channel logout

* logout token

* indicate back channel logout support in discovery endpoint
---
 README.md                         | 28 ++++++++++++-----------
 pkg/oidc/discovery.go             |  8 +++++++
 pkg/oidc/token.go                 | 37 +++++++++++++++++++++++++++++++
 pkg/oidc/token_test.go            | 36 ++++++++++++++++++++++++++++++
 pkg/op/config.go                  |  3 +++
 pkg/op/discovery.go               |  4 ++++
 pkg/op/mock/configuration.mock.go | 28 +++++++++++++++++++++++
 pkg/op/op.go                      | 30 ++++++++++++++++---------
 8 files changed, 151 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index c1ff0aa..b102815 100644
--- a/README.md
+++ b/README.md
@@ -102,19 +102,20 @@ Here is json equivalent for one of the default users
 
 ## Features
 
-|                      | Relying party | OpenID Provider | Specification                             |
-| -------------------- | ------------- | --------------- | ----------------------------------------- |
-| Code Flow            | yes           | yes             | OpenID Connect Core 1.0, [Section 3.1][1] |
-| Implicit Flow        | no[^1]        | yes             | OpenID Connect Core 1.0, [Section 3.2][2] |
-| Hybrid Flow          | no            | not yet         | OpenID Connect Core 1.0, [Section 3.3][3] |
-| Client Credentials   | yes           | yes             | OpenID Connect Core 1.0, [Section 9][4]   |
-| Refresh Token        | yes           | yes             | OpenID Connect Core 1.0, [Section 12][5]  |
-| Discovery            | yes           | yes             | OpenID Connect [Discovery][6] 1.0         |
-| JWT Profile          | yes           | yes             | [RFC 7523][7]                             |
-| PKCE                 | yes           | yes             | [RFC 7636][8]                             |
-| Token Exchange       | yes           | yes             | [RFC 8693][9]                             |
-| Device Authorization | yes           | yes             | [RFC 8628][10]                            |
-| mTLS                 | not yet       | not yet         | [RFC 8705][11]                            |
+|                      | Relying party | OpenID Provider | Specification                                |
+|----------------------| ------------- | --------------- |----------------------------------------------|
+| Code Flow            | yes           | yes             | OpenID Connect Core 1.0, [Section 3.1][1]    |
+| Implicit Flow        | no[^1]        | yes             | OpenID Connect Core 1.0, [Section 3.2][2]    |
+| Hybrid Flow          | no            | not yet         | OpenID Connect Core 1.0, [Section 3.3][3]    |
+| Client Credentials   | yes           | yes             | OpenID Connect Core 1.0, [Section 9][4]      |
+| Refresh Token        | yes           | yes             | OpenID Connect Core 1.0, [Section 12][5]     |
+| Discovery            | yes           | yes             | OpenID Connect [Discovery][6] 1.0            |
+| JWT Profile          | yes           | yes             | [RFC 7523][7]                                |
+| PKCE                 | yes           | yes             | [RFC 7636][8]                                |
+| Token Exchange       | yes           | yes             | [RFC 8693][9]                                |
+| Device Authorization | yes           | yes             | [RFC 8628][10]                               |
+| mTLS                 | not yet       | not yet         | [RFC 8705][11]                               |
+| Back-Channel Logout  | not yet       | yes             | OpenID Connect [Back-Channel Logout][12] 1.0 |
 
 [1]:  "3.1. Authentication using the Authorization Code Flow"
 [2]:  "3.2. Authentication using the Implicit Flow"
@@ -127,6 +128,7 @@ Here is json equivalent for one of the default users
 [9]:  "OAuth 2.0 Token Exchange"
 [10]:  "OAuth 2.0 Device Authorization Grant"
 [11]:  "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens"
+[12]:  "OpenID Connect Back-Channel Logout 1.0 incorporating errata set 1"
 
 ## Contributors
 
diff --git a/pkg/oidc/discovery.go b/pkg/oidc/discovery.go
index 14fce5e..62288d1 100644
--- a/pkg/oidc/discovery.go
+++ b/pkg/oidc/discovery.go
@@ -145,6 +145,14 @@ type DiscoveryConfiguration struct {
 
 	// OPTermsOfServiceURI is a URL the OpenID Provider provides to the person registering the Client to read about OpenID Provider's terms of service.
 	OPTermsOfServiceURI string `json:"op_tos_uri,omitempty"`
+
+	// BackChannelLogoutSupported specifies whether the OP supports back-channel logout (https://openid.net/specs/openid-connect-backchannel-1_0.html),
+	// with true indicating support. If omitted, the default value is false.
+	BackChannelLogoutSupported bool `json:"backchannel_logout_supported,omitempty"`
+
+	// BackChannelLogoutSessionSupported specifies whether the OP can pass a sid (session ID) Claim in the Logout Token to identify the RP session with the OP.
+	// If supported, the sid Claim is also included in ID Tokens issued by the OP. If omitted, the default value is false.
+	BackChannelLogoutSessionSupported bool `json:"backchannel_logout_session_supported,omitempty"`
 }
 
 type AuthMethod string
diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go
index a829df4..e57d91e 100644
--- a/pkg/oidc/token.go
+++ b/pkg/oidc/token.go
@@ -382,3 +382,40 @@ type TokenExchangeResponse struct {
 	// if the requested_token_type was Access Token and scope contained openid.
 	IDToken string `json:"id_token,omitempty"`
 }
+
+type LogoutTokenClaims struct {
+	Issuer     string         `json:"iss,omitempty"`
+	Subject    string         `json:"sub,omitempty"`
+	Audience   Audience       `json:"aud,omitempty"`
+	IssuedAt   Time           `json:"iat,omitempty"`
+	Expiration Time           `json:"exp,omitempty"`
+	JWTID      string         `json:"jti,omitempty"`
+	Events     map[string]any `json:"events,omitempty"`
+	SessionID  string         `json:"sid,omitempty"`
+	Claims     map[string]any `json:"-"`
+}
+
+type ltcAlias LogoutTokenClaims
+
+func (i *LogoutTokenClaims) MarshalJSON() ([]byte, error) {
+	return mergeAndMarshalClaims((*ltcAlias)(i), i.Claims)
+}
+
+func (i *LogoutTokenClaims) UnmarshalJSON(data []byte) error {
+	return unmarshalJSONMulti(data, (*ltcAlias)(i), &i.Claims)
+}
+
+func NewLogoutTokenClaims(issuer, subject string, audience Audience, expiration time.Time, jwtID, sessionID string, skew time.Duration) *LogoutTokenClaims {
+	return &LogoutTokenClaims{
+		Issuer:     issuer,
+		Subject:    subject,
+		Audience:   audience,
+		IssuedAt:   FromTime(time.Now().Add(-skew)),
+		Expiration: FromTime(expiration),
+		JWTID:      jwtID,
+		Events: map[string]any{
+			"http://schemas.openid.net/event/backchannel-logout": struct{}{},
+		},
+		SessionID: sessionID,
+	}
+}
diff --git a/pkg/oidc/token_test.go b/pkg/oidc/token_test.go
index 7847cb5..621cdbc 100644
--- a/pkg/oidc/token_test.go
+++ b/pkg/oidc/token_test.go
@@ -242,3 +242,39 @@ func TestIDTokenClaims_GetUserInfo(t *testing.T) {
 	got := idTokenData.GetUserInfo()
 	assert.Equal(t, want, got)
 }
+
+func TestNewLogoutTokenClaims(t *testing.T) {
+	want := &LogoutTokenClaims{
+		Issuer:     "zitadel",
+		Subject:    "hello@me.com",
+		Audience:   Audience{"foo", "just@me.com"},
+		Expiration: 12345,
+		JWTID:      "jwtID",
+		Events: map[string]any{
+			"http://schemas.openid.net/event/backchannel-logout": struct{}{},
+		},
+		SessionID: "sessionID",
+		Claims:    nil,
+	}
+
+	got := NewLogoutTokenClaims(
+		want.Issuer,
+		want.Subject,
+		want.Audience,
+		want.Expiration.AsTime(),
+		want.JWTID,
+		want.SessionID,
+		1*time.Second,
+	)
+
+	// test if the dynamic timestamp is around now,
+	// allowing for a delta of 1, just in case we flip on
+	// either side of a second boundry.
+	nowMinusSkew := NowTime() - 1
+	assert.InDelta(t, int64(nowMinusSkew), int64(got.IssuedAt), 1)
+
+	// Make equal not fail on dynamic timestamp
+	got.IssuedAt = 0
+
+	assert.Equal(t, want, got)
+}
diff --git a/pkg/op/config.go b/pkg/op/config.go
index 9fec7cc..2fcede0 100644
--- a/pkg/op/config.go
+++ b/pkg/op/config.go
@@ -49,6 +49,9 @@ type Configuration interface {
 
 	SupportedUILocales() []language.Tag
 	DeviceAuthorization() DeviceAuthorizationConfig
+
+	BackChannelLogoutSupported() bool
+	BackChannelLogoutSessionSupported() bool
 }
 
 type IssuerFromRequest func(r *http.Request) string
diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go
index cd08580..5a79a09 100644
--- a/pkg/op/discovery.go
+++ b/pkg/op/discovery.go
@@ -61,6 +61,8 @@ func CreateDiscoveryConfig(ctx context.Context, config Configuration, storage Di
 		CodeChallengeMethodsSupported:                      CodeChallengeMethods(config),
 		UILocalesSupported:                                 config.SupportedUILocales(),
 		RequestParameterSupported:                          config.RequestObjectSupported(),
+		BackChannelLogoutSupported:                         config.BackChannelLogoutSupported(),
+		BackChannelLogoutSessionSupported:                  config.BackChannelLogoutSessionSupported(),
 	}
 }
 
@@ -92,6 +94,8 @@ func createDiscoveryConfigV2(ctx context.Context, config Configuration, storage
 		CodeChallengeMethodsSupported:                      CodeChallengeMethods(config),
 		UILocalesSupported:                                 config.SupportedUILocales(),
 		RequestParameterSupported:                          config.RequestObjectSupported(),
+		BackChannelLogoutSupported:                         config.BackChannelLogoutSupported(),
+		BackChannelLogoutSessionSupported:                  config.BackChannelLogoutSessionSupported(),
 	}
 }
 
diff --git a/pkg/op/mock/configuration.mock.go b/pkg/op/mock/configuration.mock.go
index f392a45..137c09d 100644
--- a/pkg/op/mock/configuration.mock.go
+++ b/pkg/op/mock/configuration.mock.go
@@ -78,6 +78,34 @@ func (mr *MockConfigurationMockRecorder) AuthorizationEndpoint() *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizationEndpoint", reflect.TypeOf((*MockConfiguration)(nil).AuthorizationEndpoint))
 }
 
+// BackChannelLogoutSessionSupported mocks base method.
+func (m *MockConfiguration) BackChannelLogoutSessionSupported() bool {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "BackChannelLogoutSessionSupported")
+	ret0, _ := ret[0].(bool)
+	return ret0
+}
+
+// BackChannelLogoutSessionSupported indicates an expected call of BackChannelLogoutSessionSupported.
+func (mr *MockConfigurationMockRecorder) BackChannelLogoutSessionSupported() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BackChannelLogoutSessionSupported", reflect.TypeOf((*MockConfiguration)(nil).BackChannelLogoutSessionSupported))
+}
+
+// BackChannelLogoutSupported mocks base method.
+func (m *MockConfiguration) BackChannelLogoutSupported() bool {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "BackChannelLogoutSupported")
+	ret0, _ := ret[0].(bool)
+	return ret0
+}
+
+// BackChannelLogoutSupported indicates an expected call of BackChannelLogoutSupported.
+func (mr *MockConfigurationMockRecorder) BackChannelLogoutSupported() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BackChannelLogoutSupported", reflect.TypeOf((*MockConfiguration)(nil).BackChannelLogoutSupported))
+}
+
 // CodeMethodS256Supported mocks base method.
 func (m *MockConfiguration) CodeMethodS256Supported() bool {
 	m.ctrl.T.Helper()
diff --git a/pkg/op/op.go b/pkg/op/op.go
index 61c2449..2248098 100644
--- a/pkg/op/op.go
+++ b/pkg/op/op.go
@@ -158,16 +158,18 @@ func authCallbackPath(o OpenIDProvider) string {
 }
 
 type Config struct {
-	CryptoKey                [32]byte
-	DefaultLogoutRedirectURI string
-	CodeMethodS256           bool
-	AuthMethodPost           bool
-	AuthMethodPrivateKeyJWT  bool
-	GrantTypeRefreshToken    bool
-	RequestObjectSupported   bool
-	SupportedUILocales       []language.Tag
-	SupportedClaims          []string
-	DeviceAuthorization      DeviceAuthorizationConfig
+	CryptoKey                         [32]byte
+	DefaultLogoutRedirectURI          string
+	CodeMethodS256                    bool
+	AuthMethodPost                    bool
+	AuthMethodPrivateKeyJWT           bool
+	GrantTypeRefreshToken             bool
+	RequestObjectSupported            bool
+	SupportedUILocales                []language.Tag
+	SupportedClaims                   []string
+	DeviceAuthorization               DeviceAuthorizationConfig
+	BackChannelLogoutSupported        bool
+	BackChannelLogoutSessionSupported bool
 }
 
 // Endpoints defines endpoint routes.
@@ -411,6 +413,14 @@ func (o *Provider) DeviceAuthorization() DeviceAuthorizationConfig {
 	return o.config.DeviceAuthorization
 }
 
+func (o *Provider) BackChannelLogoutSupported() bool {
+	return o.config.BackChannelLogoutSupported
+}
+
+func (o *Provider) BackChannelLogoutSessionSupported() bool {
+	return o.config.BackChannelLogoutSessionSupported
+}
+
 func (o *Provider) Storage() Storage {
 	return o.storage
 }

From fbf009fe75dac732dde39e0eb6fe324b337675e0 Mon Sep 17 00:00:00 2001
From: David Sharnoff 
Date: Fri, 1 Nov 2024 01:53:28 -0700
Subject: [PATCH 122/185] fix: ignore all unmarshal errors from locale (#673)

---
 pkg/oidc/types.go      | 15 ++++-----------
 pkg/oidc/types_test.go |  8 +++++---
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go
index e7292e6..7063426 100644
--- a/pkg/oidc/types.go
+++ b/pkg/oidc/types.go
@@ -3,7 +3,6 @@ package oidc
 import (
 	"database/sql/driver"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"reflect"
 	"strings"
@@ -78,22 +77,16 @@ func (l *Locale) MarshalJSON() ([]byte, error) {
 }
 
 // UnmarshalJSON implements json.Unmarshaler.
-// When [language.ValueError] is encountered, the containing tag will be set
+// All unmarshal errors for are ignored.
+// When an error is encountered, the containing tag will be set
 // to an empty value (language "und") and no error will be returned.
 // This state can be checked with the `l.Tag().IsRoot()` method.
 func (l *Locale) UnmarshalJSON(data []byte) error {
 	err := json.Unmarshal(data, &l.tag)
-	if err == nil {
-		return nil
-	}
-
-	// catch "well-formed but unknown" errors
-	var target language.ValueError
-	if errors.As(err, &target) {
+	if err != nil {
 		l.tag = language.Tag{}
-		return nil
 	}
-	return err
+	return nil
 }
 
 type Locales []language.Tag
diff --git a/pkg/oidc/types_test.go b/pkg/oidc/types_test.go
index df93a73..c7ce0ee 100644
--- a/pkg/oidc/types_test.go
+++ b/pkg/oidc/types_test.go
@@ -232,9 +232,11 @@ func TestLocale_UnmarshalJSON(t *testing.T) {
 			},
 		},
 		{
-			name:    "bad form, error",
-			input:   `{"locale": "g!!!!!"}`,
-			wantErr: true,
+			name:  "bad form, error",
+			input: `{"locale": "g!!!!!"}`,
+			want: dst{
+				Locale: &Locale{},
+			},
 		},
 	}
 

From f194951e6194c49f643106c2cc970edbdc9e99ea Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 11 Nov 2024 12:52:23 +0200
Subject: [PATCH 123/185] chore(deps): bump golang.org/x/text from 0.19.0 to
 0.20.0 (#677)

Bumps [golang.org/x/text](https://github.com/golang/text) from 0.19.0 to 0.20.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.19.0...v0.20.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] 
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
 go.mod | 2 +-
 go.sum | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/go.mod b/go.mod
index f50972a..a898848 100644
--- a/go.mod
+++ b/go.mod
@@ -20,7 +20,7 @@ require (
 	github.com/zitadel/schema v1.3.0
 	go.opentelemetry.io/otel v1.29.0
 	golang.org/x/oauth2 v0.23.0
-	golang.org/x/text v0.19.0
+	golang.org/x/text v0.20.0
 )
 
 require (
diff --git a/go.sum b/go.sum
index 91de9bf..8868b30 100644
--- a/go.sum
+++ b/go.sum
@@ -88,8 +88,8 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
-golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
+golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=

From 87ab01115708a2a05c20cfd26db82cc7e0e8e338 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 11 Nov 2024 12:55:25 +0200
Subject: [PATCH 124/185] chore(deps): bump golang.org/x/oauth2 from 0.23.0 to
 0.24.0 (#676)

Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.23.0 to 0.24.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] 
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
 go.mod | 2 +-
 go.sum | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/go.mod b/go.mod
index a898848..82e15e1 100644
--- a/go.mod
+++ b/go.mod
@@ -19,7 +19,7 @@ require (
 	github.com/zitadel/logging v0.6.1
 	github.com/zitadel/schema v1.3.0
 	go.opentelemetry.io/otel v1.29.0
-	golang.org/x/oauth2 v0.23.0
+	golang.org/x/oauth2 v0.24.0
 	golang.org/x/text v0.20.0
 )
 
diff --git a/go.sum b/go.sum
index 8868b30..2f64061 100644
--- a/go.sum
+++ b/go.sum
@@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
 golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
 golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
-golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
+golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

From 8afb8b8d5fb036b2688b773596d5dd992ba63cf5 Mon Sep 17 00:00:00 2001
From: Kevin Schoonover 
Date: Tue, 12 Nov 2024 07:06:24 -0800
Subject: [PATCH 125/185] feat(pkg/op): allow custom SupportedScopes (#675)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Tim Möhlmann 
---
 pkg/op/discovery.go      | 8 ++++++--
 pkg/op/discovery_test.go | 5 +++++
 pkg/op/op.go             | 1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go
index 5a79a09..e30a5a4 100644
--- a/pkg/op/discovery.go
+++ b/pkg/op/discovery.go
@@ -100,7 +100,11 @@ func createDiscoveryConfigV2(ctx context.Context, config Configuration, storage
 }
 
 func Scopes(c Configuration) []string {
-	return DefaultSupportedScopes // TODO: config
+	provider, ok := c.(*Provider)
+	if ok && provider.config.SupportedScopes != nil {
+		return provider.config.SupportedScopes
+	}
+	return DefaultSupportedScopes
 }
 
 func ResponseTypes(c Configuration) []string {
@@ -135,7 +139,7 @@ func GrantTypes(c Configuration) []oidc.GrantType {
 }
 
 func SubjectTypes(c Configuration) []string {
-	return []string{"public"} //TODO: config
+	return []string{"public"} // TODO: config
 }
 
 func SigAlgorithms(ctx context.Context, storage DiscoverStorage) []string {
diff --git a/pkg/op/discovery_test.go b/pkg/op/discovery_test.go
index cb4cfba..61afb62 100644
--- a/pkg/op/discovery_test.go
+++ b/pkg/op/discovery_test.go
@@ -81,6 +81,11 @@ func Test_scopes(t *testing.T) {
 			args{},
 			op.DefaultSupportedScopes,
 		},
+		{
+			"custom scopes",
+			args{newTestProvider(&op.Config{SupportedScopes: []string{"test1", "test2"}})},
+			[]string{"test1", "test2"},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
diff --git a/pkg/op/op.go b/pkg/op/op.go
index 2248098..190c2c4 100644
--- a/pkg/op/op.go
+++ b/pkg/op/op.go
@@ -167,6 +167,7 @@ type Config struct {
 	RequestObjectSupported            bool
 	SupportedUILocales                []language.Tag
 	SupportedClaims                   []string
+	SupportedScopes                   []string
 	DeviceAuthorization               DeviceAuthorizationConfig
 	BackChannelLogoutSupported        bool
 	BackChannelLogoutSessionSupported bool

From 897c720070c0cca82f8b898b5f8db53c73f54881 Mon Sep 17 00:00:00 2001
From: isegura-eos-eng <77284860+isegura-eos-eng@users.noreply.github.com>
Date: Wed, 13 Nov 2024 09:49:55 +0100
Subject: [PATCH 126/185] fix(op): add scope to access token scope (#664)

---
 pkg/oidc/token.go                  | 13 +++++++------
 pkg/op/device.go                   |  1 +
 pkg/op/op_test.go                  |  2 +-
 pkg/op/server_http_routes_test.go  |  4 ++--
 pkg/op/token.go                    |  1 +
 pkg/op/token_client_credentials.go |  1 +
 pkg/op/token_jwt_profile.go        |  1 +
 7 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go
index e57d91e..d2b6f6d 100644
--- a/pkg/oidc/token.go
+++ b/pkg/oidc/token.go
@@ -230,12 +230,13 @@ func (c *ActorClaims) UnmarshalJSON(data []byte) error {
 }
 
 type AccessTokenResponse struct {
-	AccessToken  string `json:"access_token,omitempty" schema:"access_token,omitempty"`
-	TokenType    string `json:"token_type,omitempty" schema:"token_type,omitempty"`
-	RefreshToken string `json:"refresh_token,omitempty" schema:"refresh_token,omitempty"`
-	ExpiresIn    uint64 `json:"expires_in,omitempty" schema:"expires_in,omitempty"`
-	IDToken      string `json:"id_token,omitempty" schema:"id_token,omitempty"`
-	State        string `json:"state,omitempty" schema:"state,omitempty"`
+	AccessToken  string              `json:"access_token,omitempty" schema:"access_token,omitempty"`
+	TokenType    string              `json:"token_type,omitempty" schema:"token_type,omitempty"`
+	RefreshToken string              `json:"refresh_token,omitempty" schema:"refresh_token,omitempty"`
+	ExpiresIn    uint64              `json:"expires_in,omitempty" schema:"expires_in,omitempty"`
+	IDToken      string              `json:"id_token,omitempty" schema:"id_token,omitempty"`
+	State        string              `json:"state,omitempty" schema:"state,omitempty"`
+	Scope        SpaceDelimitedArray `json:"scope,omitempty" schema:"scope,omitempty"`
 }
 
 type JWTProfileAssertionClaims struct {
diff --git a/pkg/op/device.go b/pkg/op/device.go
index 11638b0..3de271a 100644
--- a/pkg/op/device.go
+++ b/pkg/op/device.go
@@ -344,6 +344,7 @@ func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, c
 		RefreshToken: refreshToken,
 		TokenType:    oidc.BearerToken,
 		ExpiresIn:    uint64(validity.Seconds()),
+		Scope:        tokenRequest.GetScopes(),
 	}
 
 	// TODO(v4): remove type assertion
diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go
index 83032d4..9a4a624 100644
--- a/pkg/op/op_test.go
+++ b/pkg/op/op_test.go
@@ -232,7 +232,7 @@ func TestRoutes(t *testing.T) {
 				"scope":      oidc.SpaceDelimitedArray{oidc.ScopeOpenID, oidc.ScopeOfflineAccess}.String(),
 			},
 			wantCode: http.StatusOK,
-			contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299}`},
+			contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299,"scope":"openid offline_access"}`},
 		},
 		{
 			// This call will fail. A successful test is already
diff --git a/pkg/op/server_http_routes_test.go b/pkg/op/server_http_routes_test.go
index 2c83ad3..1bfb32b 100644
--- a/pkg/op/server_http_routes_test.go
+++ b/pkg/op/server_http_routes_test.go
@@ -145,7 +145,7 @@ func TestServerRoutes(t *testing.T) {
 				"assertion":  jwtProfileToken,
 			},
 			wantCode: http.StatusOK,
-			contains: []string{`{"access_token":`, `"token_type":"Bearer","expires_in":299}`},
+			contains: []string{`{"access_token":`, `"token_type":"Bearer","expires_in":299,"scope":"openid"}`},
 		},
 		{
 			name:      "Token exchange",
@@ -174,7 +174,7 @@ func TestServerRoutes(t *testing.T) {
 				"scope":      oidc.SpaceDelimitedArray{oidc.ScopeOpenID, oidc.ScopeOfflineAccess}.String(),
 			},
 			wantCode: http.StatusOK,
-			contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299}`},
+			contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299,"scope":"openid offline_access"}`},
 		},
 		{
 			// This call will fail. A successful test is already
diff --git a/pkg/op/token.go b/pkg/op/token.go
index b45789b..61d7b2f 100644
--- a/pkg/op/token.go
+++ b/pkg/op/token.go
@@ -65,6 +65,7 @@ func CreateTokenResponse(ctx context.Context, request IDTokenRequest, client Cli
 		TokenType:    oidc.BearerToken,
 		ExpiresIn:    exp,
 		State:        state,
+		Scope:        request.GetScopes(),
 	}, nil
 }
 
diff --git a/pkg/op/token_client_credentials.go b/pkg/op/token_client_credentials.go
index 7f1debe..63dcc79 100644
--- a/pkg/op/token_client_credentials.go
+++ b/pkg/op/token_client_credentials.go
@@ -120,5 +120,6 @@ func CreateClientCredentialsTokenResponse(ctx context.Context, tokenRequest Toke
 		AccessToken: accessToken,
 		TokenType:   oidc.BearerToken,
 		ExpiresIn:   uint64(validity.Seconds()),
+		Scope:       tokenRequest.GetScopes(),
 	}, nil
 }
diff --git a/pkg/op/token_jwt_profile.go b/pkg/op/token_jwt_profile.go
index 96ce1ed..d1a7ff5 100644
--- a/pkg/op/token_jwt_profile.go
+++ b/pkg/op/token_jwt_profile.go
@@ -89,6 +89,7 @@ func CreateJWTTokenResponse(ctx context.Context, tokenRequest TokenRequest, crea
 		AccessToken: accessToken,
 		TokenType:   oidc.BearerToken,
 		ExpiresIn:   uint64(validity.Seconds()),
+		Scope:       tokenRequest.GetScopes(),
 	}, nil
 }
 

From 1464268851631e7d3062438fe79206e32a35ed83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= 
Date: Fri, 15 Nov 2024 08:26:03 +0200
Subject: [PATCH 127/185] chore(deps): upgrade go to v1.23 (#681)

---
 .github/workflows/release.yml |  2 +-
 README.md                     | 72 ++++++++++++++++++-----------------
 2 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 66d68b6..a1fb1ba 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -18,7 +18,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        go: ['1.21', '1.22']
+        go: ['1.21', '1.22', '1.23']
     name: Go ${{ matrix.go }} test
     steps:
       - uses: actions/checkout@v4
diff --git a/README.md b/README.md
index b102815..04d551f 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ Whenever possible we tried to reuse / extend existing packages like `OAuth2 for
 ## Basic Overview
 
 The most important packages of the library:
+
 
 /pkg
     /client            clients using the OP for retrieving, exchanging and verifying tokens
@@ -37,7 +38,6 @@ The most important packages of the library:
     /server            examples of an OpenID Provider implementations (including dynamic) with some very basic login UI
 
- ### Semver This package uses [semver](https://semver.org/) for [releases](https://github.com/zitadel/oidc/releases). Major releases ship breaking changes. Starting with the `v2` to `v3` increment we provide an [upgrade guide](UPGRADING.md) to ease migration to a newer version. @@ -60,10 +60,13 @@ CLIENT_ID=web CLIENT_SECRET=secret ISSUER=http://localhost:9998/ SCOPES="openid - the OP will redirect you to the client app, which displays the user info for the dynamic issuer, just start it with: + ```bash go run github.com/zitadel/oidc/v3/example/server/dynamic ``` + the oidc web client above will still work, but if you add `oidc.local` (pointing to 127.0.0.1) in your hosts file you can also start it with: + ```bash CLIENT_ID=web CLIENT_SECRET=secret ISSUER=http://oidc.local:9998/ SCOPES="openid profile" PORT=9999 go run github.com/zitadel/oidc/v3/example/client/app ``` @@ -75,35 +78,36 @@ CLIENT_ID=web CLIENT_SECRET=secret ISSUER=http://oidc.local:9998/ SCOPES="openid Example server allows extra configuration using environment variables and could be used for end to end testing of your services. -| Name | Format | Description | -|---------------|--------------------------------------|---------------------------------------| -| PORT | Number between 1 and 65535 | OIDC listen port | -| REDIRECT_URI | Comma-separated URIs | List of allowed redirect URIs | -| USERS_FILE | Path to json in local filesystem | Users with their data and credentials | +| Name | Format | Description | +| ------------ | -------------------------------- | ------------------------------------- | +| PORT | Number between 1 and 65535 | OIDC listen port | +| REDIRECT_URI | Comma-separated URIs | List of allowed redirect URIs | +| USERS_FILE | Path to json in local filesystem | Users with their data and credentials | Here is json equivalent for one of the default users + ```json { - "id2": { - "ID": "id2", - "Username": "test-user2", - "Password": "verysecure", - "FirstName": "Test", - "LastName": "User2", - "Email": "test-user2@zitadel.ch", - "EmailVerified": true, - "Phone": "", - "PhoneVerified": false, - "PreferredLanguage": "DE", - "IsAdmin": false - } + "id2": { + "ID": "id2", + "Username": "test-user2", + "Password": "verysecure", + "FirstName": "Test", + "LastName": "User2", + "Email": "test-user2@zitadel.ch", + "EmailVerified": true, + "Phone": "", + "PhoneVerified": false, + "PreferredLanguage": "DE", + "IsAdmin": false + } } ``` ## Features | | Relying party | OpenID Provider | Specification | -|----------------------| ------------- | --------------- |----------------------------------------------| +| -------------------- | ------------- | --------------- | -------------------------------------------- | | Code Flow | yes | yes | OpenID Connect Core 1.0, [Section 3.1][1] | | Implicit Flow | no[^1] | yes | OpenID Connect Core 1.0, [Section 3.2][2] | | Hybrid Flow | no | not yet | OpenID Connect Core 1.0, [Section 3.3][3] | @@ -117,18 +121,18 @@ Here is json equivalent for one of the default users | mTLS | not yet | not yet | [RFC 8705][11] | | Back-Channel Logout | not yet | yes | OpenID Connect [Back-Channel Logout][12] 1.0 | -[1]: "3.1. Authentication using the Authorization Code Flow" -[2]: "3.2. Authentication using the Implicit Flow" -[3]: "3.3. Authentication using the Hybrid Flow" -[4]: "9. Client Authentication" -[5]: "12. Using Refresh Tokens" -[6]: "OpenID Connect Discovery 1.0 incorporating errata set 1" -[7]: "JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants" -[8]: "Proof Key for Code Exchange by OAuth Public Clients" -[9]: "OAuth 2.0 Token Exchange" -[10]: "OAuth 2.0 Device Authorization Grant" -[11]: "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens" -[12]: "OpenID Connect Back-Channel Logout 1.0 incorporating errata set 1" +[1]: https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth "3.1. Authentication using the Authorization Code Flow" +[2]: https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth "3.2. Authentication using the Implicit Flow" +[3]: https://openid.net/specs/openid-connect-core-1_0.html#HybridFlowAuth "3.3. Authentication using the Hybrid Flow" +[4]: https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication "9. Client Authentication" +[5]: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens "12. Using Refresh Tokens" +[6]: https://openid.net/specs/openid-connect-discovery-1_0.html "OpenID Connect Discovery 1.0 incorporating errata set 1" +[7]: https://www.rfc-editor.org/rfc/rfc7523.html "JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants" +[8]: https://www.rfc-editor.org/rfc/rfc7636.html "Proof Key for Code Exchange by OAuth Public Clients" +[9]: https://www.rfc-editor.org/rfc/rfc8693.html "OAuth 2.0 Token Exchange" +[10]: https://www.rfc-editor.org/rfc/rfc8628.html "OAuth 2.0 Device Authorization Grant" +[11]: https://www.rfc-editor.org/rfc/rfc8705.html "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens" +[12]: https://openid.net/specs/openid-connect-backchannel-1_0.html "OpenID Connect Back-Channel Logout 1.0 incorporating errata set 1" ## Contributors @@ -153,8 +157,9 @@ Versions that also build are marked with :warning:. | Version | Supported | | ------- | ------------------ | | <1.21 | :x: | -| 1.21 | :white_check_mark: | +| 1.21 | :warning: | | 1.22 | :white_check_mark: | +| 1.23 | :white_check_mark: | ## Why another library @@ -185,5 +190,4 @@ Unless required by applicable law or agreed to in writing, software distributed AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - [^1]: https://github.com/zitadel/oidc/issues/135#issuecomment-950563892 From 6d2092802811f0a9d38cc0a070f2fff708a44181 Mon Sep 17 00:00:00 2001 From: isegura-eos-eng <77284860+isegura-eos-eng@users.noreply.github.com> Date: Fri, 15 Nov 2024 17:47:32 +0100 Subject: [PATCH 128/185] refactor: mark pkg/strings as deprecated in favor of stdlib (#680) * refactor: mark pkg/strings as deprecated in favor of stdlib * format: reword deprecate notice and use doc links --- pkg/oidc/verifier.go | 7 +++---- pkg/op/auth_request.go | 7 +++---- pkg/op/device.go | 6 +++--- pkg/op/token.go | 6 +++--- pkg/op/token_refresh.go | 4 ++-- pkg/strings/strings.go | 11 +++++------ 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index f580da6..d5e0213 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -7,12 +7,11 @@ import ( "encoding/json" "errors" "fmt" + "slices" "strings" "time" jose "github.com/go-jose/go-jose/v4" - - str "github.com/zitadel/oidc/v3/pkg/strings" ) type Claims interface { @@ -84,7 +83,7 @@ type ACRVerifier func(string) error // if none of the provided values matches the acr claim func DefaultACRVerifier(possibleValues []string) ACRVerifier { return func(acr string) error { - if !str.Contains(possibleValues, acr) { + if !slices.Contains(possibleValues, acr) { return fmt.Errorf("expected one of: %v, got: %q", possibleValues, acr) } return nil @@ -123,7 +122,7 @@ func CheckIssuer(claims Claims, issuer string) error { } func CheckAudience(claims Claims, clientID string) error { - if !str.Contains(claims.GetAudience(), clientID) { + if !slices.Contains(claims.GetAudience(), clientID) { return fmt.Errorf("%w: Audience must contain client_id %q", ErrAudience, clientID) } diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 52fda2e..b020f39 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -18,7 +18,6 @@ import ( "github.com/bmatcuk/doublestar/v4" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - str "github.com/zitadel/oidc/v3/pkg/strings" ) type AuthRequest interface { @@ -156,7 +155,7 @@ func ParseRequestObject(ctx context.Context, authReq *oidc.AuthRequest, storage if requestObject.Issuer != requestObject.ClientID { return oidc.ErrInvalidRequest().WithDescription("missing or wrong issuer in request") } - if !str.Contains(requestObject.Audience, issuer) { + if !slices.Contains(requestObject.Audience, issuer) { return oidc.ErrInvalidRequest().WithDescription("issuer missing in audience") } keySet := &jwtProfileKeySet{storage: storage, clientID: requestObject.Issuer} @@ -170,7 +169,7 @@ func ParseRequestObject(ctx context.Context, authReq *oidc.AuthRequest, storage // CopyRequestObjectToAuthRequest overwrites present values from the Request Object into the auth request // and clears the `RequestParam` of the auth request func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oidc.RequestObject) { - if str.Contains(authReq.Scopes, oidc.ScopeOpenID) && len(requestObject.Scopes) > 0 { + if slices.Contains(authReq.Scopes, oidc.ScopeOpenID) && len(requestObject.Scopes) > 0 { authReq.Scopes = requestObject.Scopes } if requestObject.RedirectURI != "" { @@ -288,7 +287,7 @@ func ValidateAuthReqScopes(client Client, scopes []string) ([]string, error) { // checkURIAgainstRedirects just checks aginst the valid redirect URIs and ignores // other factors. func checkURIAgainstRedirects(client Client, uri string) error { - if str.Contains(client.RedirectURIs(), uri) { + if slices.Contains(client.RedirectURIs(), uri) { return nil } if globClient, ok := client.(HasRedirectGlobs); ok { diff --git a/pkg/op/device.go b/pkg/op/device.go index 3de271a..8a0e174 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -9,12 +9,12 @@ import ( "math/big" "net/http" "net/url" + "slices" "strings" "time" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - strs "github.com/zitadel/oidc/v3/pkg/strings" ) type DeviceAuthorizationConfig struct { @@ -276,7 +276,7 @@ func (r *DeviceAuthorizationState) GetAMR() []string { } func (r *DeviceAuthorizationState) GetAudience() []string { - if !strs.Contains(r.Audience, r.ClientID) { + if !slices.Contains(r.Audience, r.ClientID) { r.Audience = append(r.Audience, r.ClientID) } return r.Audience @@ -348,7 +348,7 @@ func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, c } // TODO(v4): remove type assertion - if idTokenRequest, ok := tokenRequest.(IDTokenRequest); ok && strs.Contains(tokenRequest.GetScopes(), oidc.ScopeOpenID) { + if idTokenRequest, ok := tokenRequest.(IDTokenRequest); ok && slices.Contains(tokenRequest.GetScopes(), oidc.ScopeOpenID) { response.IDToken, err = CreateIDToken(ctx, IssuerFromContext(ctx), idTokenRequest, client.IDTokenLifetime(), accessToken, "", creator.Storage(), client) if err != nil { return nil, err diff --git a/pkg/op/token.go b/pkg/op/token.go index 61d7b2f..04cd3cc 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -2,11 +2,11 @@ package op import ( "context" + "slices" "time" "github.com/zitadel/oidc/v3/pkg/crypto" "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/strings" ) type TokenCreator interface { @@ -83,13 +83,13 @@ func createTokens(ctx context.Context, tokenRequest TokenRequest, storage Storag func needsRefreshToken(tokenRequest TokenRequest, client AccessTokenClient) bool { switch req := tokenRequest.(type) { case AuthRequest: - return strings.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && req.GetResponseType() == oidc.ResponseTypeCode && ValidateGrantType(client, oidc.GrantTypeRefreshToken) + return slices.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && req.GetResponseType() == oidc.ResponseTypeCode && ValidateGrantType(client, oidc.GrantTypeRefreshToken) case TokenExchangeRequest: return req.GetRequestedTokenType() == oidc.RefreshTokenType case RefreshTokenRequest: return true case *DeviceAuthorizationState: - return strings.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && ValidateGrantType(client, oidc.GrantTypeRefreshToken) + return slices.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && ValidateGrantType(client, oidc.GrantTypeRefreshToken) default: return false } diff --git a/pkg/op/token_refresh.go b/pkg/op/token_refresh.go index 92ef476..7c8c1c0 100644 --- a/pkg/op/token_refresh.go +++ b/pkg/op/token_refresh.go @@ -4,11 +4,11 @@ import ( "context" "errors" "net/http" + "slices" "time" httphelper "github.com/zitadel/oidc/v3/pkg/http" "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/strings" ) type RefreshTokenRequest interface { @@ -85,7 +85,7 @@ func ValidateRefreshTokenScopes(requestedScopes []string, authRequest RefreshTok return nil } for _, scope := range requestedScopes { - if !strings.Contains(authRequest.GetScopes(), scope) { + if !slices.Contains(authRequest.GetScopes(), scope) { return oidc.ErrInvalidScope() } } diff --git a/pkg/strings/strings.go b/pkg/strings/strings.go index af48cf3..b8f43a1 100644 --- a/pkg/strings/strings.go +++ b/pkg/strings/strings.go @@ -1,10 +1,9 @@ package strings +import "slices" + +// Deprecated: Use standard library [slices.Contains] instead. func Contains(list []string, needle string) bool { - for _, item := range list { - if item == needle { - return true - } - } - return false + // TODO(v4): remove package. + return slices.Contains(list, needle) } From a7833f828c2eafa2d5bc69136c945f85edda6c2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:59:21 +0200 Subject: [PATCH 129/185] chore(deps): bump codecov/codecov-action from 4.6.0 to 5.0.2 (#682) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.6.0 to 5.0.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.6.0...v5.0.2) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a1fb1ba..8cc5896 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v4.6.0 + - uses: codecov/codecov-action@v5.0.2 with: file: ./profile.cov name: codecov-go From e2de68a7dd74797a92da0010ff8cbde807fe8c97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:04:43 +0200 Subject: [PATCH 130/185] chore(deps): bump github.com/jeremija/gosubmit from 0.2.7 to 0.2.8 (#683) Bumps [github.com/jeremija/gosubmit](https://github.com/jeremija/gosubmit) from 0.2.7 to 0.2.8. - [Commits](https://github.com/jeremija/gosubmit/compare/v0.2.7...v0.2.8) --- updated-dependencies: - dependency-name: github.com/jeremija/gosubmit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 82e15e1..69aa537 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 github.com/gorilla/securecookie v1.1.2 - github.com/jeremija/gosubmit v0.2.7 + github.com/jeremija/gosubmit v0.2.8 github.com/muhlemmer/gu v0.3.1 github.com/muhlemmer/httpforwarded v0.1.0 github.com/rs/cors v1.11.1 diff --git a/go.sum b/go.sum index 2f64061..eda85e5 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= -github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= -github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= +github.com/jeremija/gosubmit v0.2.8 h1:mmSITBz9JxVtu8eqbN+zmmwX7Ij2RidQxhcwRVI4wqA= +github.com/jeremija/gosubmit v0.2.8/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= From 67bd2f572032185f0c77751f26df5a0900597909 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:55:33 +0200 Subject: [PATCH 131/185] chore(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#684) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.9.0 to 1.10.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 69aa537..9be2bce 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/muhlemmer/httpforwarded v0.1.0 github.com/rs/cors v1.11.1 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/zitadel/logging v0.6.1 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 diff --git a/go.sum b/go.sum index eda85e5..c76d047 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zitadel/logging v0.6.1 h1:Vyzk1rl9Kq9RCevcpX6ujUaTYFX43aa4LkvV1TvUk+Y= github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= From 057601ff3f65a9db73b2c10840fd11b97a2e3c85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:41:27 +0200 Subject: [PATCH 132/185] chore(deps): bump codecov/codecov-action from 5.0.2 to 5.0.7 (#685) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.2 to 5.0.7. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.0.2...v5.0.7) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8cc5896..cfcada3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.0.2 + - uses: codecov/codecov-action@v5.0.7 with: file: ./profile.cov name: codecov-go From 2513e21531093a5648957801fdbef5102907f586 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 08:42:45 +0100 Subject: [PATCH 133/185] chore(deps): bump golang.org/x/text from 0.20.0 to 0.21.0 (#686) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.20.0 to 0.21.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.20.0...v0.21.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9be2bce..1ad4399 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.24.0 - golang.org/x/text v0.20.0 + golang.org/x/text v0.21.0 ) require ( diff --git a/go.sum b/go.sum index c76d047..d0281cf 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From cf6ce69d79666cef2ac429607286c3aa63bcb677 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:16:13 +0100 Subject: [PATCH 134/185] chore(deps): bump codecov/codecov-action from 5.0.7 to 5.1.1 (#687) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.7 to 5.1.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.0.7...v5.1.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cfcada3..2d013be 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.0.7 + - uses: codecov/codecov-action@v5.1.1 with: file: ./profile.cov name: codecov-go From 9a93b7c70d06e554d68050cba33b8a7b5bd534bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:33:24 +0000 Subject: [PATCH 135/185] chore(deps): bump golang.org/x/crypto from 0.25.0 to 0.31.0 (#688) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.25.0 to 0.31.0. - [Commits](https://github.com/golang/crypto/compare/v0.25.0...v0.31.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 1ad4399..666422f 100644 --- a/go.mod +++ b/go.mod @@ -31,8 +31,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d0281cf..827565f 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt3 go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -83,8 +83,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= From b36a8e2ec14845c33c368c3d178c077d5fc7e7b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 20:27:45 +0200 Subject: [PATCH 136/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.1.0 to 5.2.0 (#689) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.1.0...v5.2.0) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 666422f..25b2eac 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.7.1 - github.com/go-chi/chi/v5 v5.1.0 + github.com/go-chi/chi/v5 v5.2.0 github.com/go-jose/go-jose/v4 v4.0.4 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index 827565f..2927da3 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTS github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0= +github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From 6c90652dfb1f1dbd930283a4c4caef255ff7b406 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:00:57 +0200 Subject: [PATCH 137/185] chore(deps): bump codecov/codecov-action from 5.1.1 to 5.1.2 (#692) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.1.1 to 5.1.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.1.1...v5.1.2) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2d013be..f70bd8b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.1.1 + - uses: codecov/codecov-action@v5.1.2 with: file: ./profile.cov name: codecov-go From 8d971dcad8f6e7aab12e4494de84bf79ecd521c0 Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Mon, 30 Dec 2024 11:47:05 +0100 Subject: [PATCH 138/185] chore: bump dependencies (#694) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 25b2eac..7f38f6d 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2927da3..ec07f36 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= From a0f67c0b4baacb05cfedd564237bc523ef706452 Mon Sep 17 00:00:00 2001 From: Danila Fominykh Date: Fri, 3 Jan 2025 11:27:01 +0300 Subject: [PATCH 139/185] feat: add redirect URI-s ENV setting to web clients (#693) Co-authored-by: FominykhDG --- example/server/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/server/main.go b/example/server/main.go index 36816d6..6d345e1 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -32,8 +32,8 @@ func main() { storage.RegisterClients( storage.NativeClient("native", cfg.RedirectURI...), - storage.WebClient("web", "secret"), - storage.WebClient("api", "secret"), + storage.WebClient("web", "secret", cfg.RedirectURI...), + storage.WebClient("api", "secret", cfg.RedirectURI...), ) // the OpenIDProvider interface needs a Storage interface handling various checks and state manipulations From 1f6a0d5d89452a0b97b3e2d0afce4a5bd13c3b20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:47:02 +0200 Subject: [PATCH 140/185] chore(deps): bump golang.org/x/oauth2 from 0.24.0 to 0.25.0 (#695) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.24.0 to 0.25.0. - [Commits](https://github.com/golang/oauth2/compare/v0.24.0...v0.25.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7f38f6d..ff8f4af 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.1 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 - golang.org/x/oauth2 v0.24.0 + golang.org/x/oauth2 v0.25.0 golang.org/x/text v0.21.0 ) diff --git a/go.sum b/go.sum index ec07f36..f531586 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 867a4806fdad92dcf2db83be62f3444da8e17d68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 14:51:01 +0100 Subject: [PATCH 141/185] chore(deps): bump github.com/bmatcuk/doublestar/v4 from 4.7.1 to 4.8.0 (#696) Bumps [github.com/bmatcuk/doublestar/v4](https://github.com/bmatcuk/doublestar) from 4.7.1 to 4.8.0. - [Release notes](https://github.com/bmatcuk/doublestar/releases) - [Commits](https://github.com/bmatcuk/doublestar/compare/v4.7.1...v4.8.0) --- updated-dependencies: - dependency-name: github.com/bmatcuk/doublestar/v4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ff8f4af..47feab9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/zitadel/oidc/v3 go 1.21 require ( - github.com/bmatcuk/doublestar/v4 v4.7.1 + github.com/bmatcuk/doublestar/v4 v4.8.0 github.com/go-chi/chi/v5 v5.2.0 github.com/go-jose/go-jose/v4 v4.0.4 github.com/golang/mock v1.6.0 diff --git a/go.sum b/go.sum index f531586..60a5125 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q= -github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.8.0 h1:DSXtrypQddoug1459viM9X9D3dp1Z7993fw36I2kNcQ= +github.com/bmatcuk/doublestar/v4 v4.8.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From de2fd41f40f3097734b6b593be3d94dee8b47e2a Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 17 Jan 2025 14:53:19 +0100 Subject: [PATCH 142/185] fix: allow native clients to use https:// on localhost redirects (#691) --- pkg/op/auth_request.go | 21 ++++++++++++--------- pkg/op/auth_request_test.go | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index b020f39..d6db62b 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -312,12 +312,12 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res return oidc.ErrInvalidRequestRedirectURI().WithDescription("The redirect_uri is missing in the request. " + "Please ensure it is added to the request. If you have any questions, you may contact the administrator of the application.") } - if strings.HasPrefix(uri, "https://") { - return checkURIAgainstRedirects(client, uri) - } if client.ApplicationType() == ApplicationTypeNative { return validateAuthReqRedirectURINative(client, uri) } + if strings.HasPrefix(uri, "https://") { + return checkURIAgainstRedirects(client, uri) + } if err := checkURIAgainstRedirects(client, uri); err != nil { return err } @@ -338,12 +338,15 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res // ValidateAuthReqRedirectURINative validates the passed redirect_uri and response_type to the registered uris and client type func validateAuthReqRedirectURINative(client Client, uri string) error { parsedURL, isLoopback := HTTPLoopbackOrLocalhost(uri) - isCustomSchema := !strings.HasPrefix(uri, "http://") + isCustomSchema := !(strings.HasPrefix(uri, "http://") || strings.HasPrefix(uri, "https://")) if err := checkURIAgainstRedirects(client, uri); err == nil { if client.DevMode() { return nil } - // The RedirectURIs are only valid for native clients when localhost or non-"http://" + if !isLoopback && strings.HasPrefix(uri, "https://") { + return nil + } + // The RedirectURIs are only valid for native clients when localhost or non-"http://" and "https://" if isLoopback || isCustomSchema { return nil } @@ -373,11 +376,11 @@ func HTTPLoopbackOrLocalhost(rawURL string) (*url.URL, bool) { if err != nil { return nil, false } - if parsedURL.Scheme != "http" { - return nil, false + if parsedURL.Scheme == "http" || parsedURL.Scheme == "https" { + hostName := parsedURL.Hostname() + return parsedURL, hostName == "localhost" || net.ParseIP(hostName).IsLoopback() } - hostName := parsedURL.Hostname() - return parsedURL, hostName == "localhost" || net.ParseIP(hostName).IsLoopback() + return nil, false } // ValidateAuthReqResponseType validates the passed response_type to the registered response types diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 6b4af17..765e602 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -433,6 +433,24 @@ func TestValidateAuthReqRedirectURI(t *testing.T) { }, false, }, + { + "code flow registered https loopback v4 native ok", + args{ + "https://127.0.0.1:4200/callback", + mock.NewClientWithConfig(t, []string{"https://127.0.0.1/callback"}, op.ApplicationTypeNative, nil, false), + oidc.ResponseTypeCode, + }, + false, + }, + { + "code flow registered https loopback v6 native ok", + args{ + "https://[::1]:4200/callback", + mock.NewClientWithConfig(t, []string{"https://[::1]/callback"}, op.ApplicationTypeNative, nil, false), + oidc.ResponseTypeCode, + }, + false, + }, { "code flow unregistered http native fails", args{ From 24c96c361d657901566c321e5af73efbdc5ad575 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:37:23 +0200 Subject: [PATCH 143/185] chore(deps): bump github.com/bmatcuk/doublestar/v4 from 4.8.0 to 4.8.1 (#701) Bumps [github.com/bmatcuk/doublestar/v4](https://github.com/bmatcuk/doublestar) from 4.8.0 to 4.8.1. - [Release notes](https://github.com/bmatcuk/doublestar/releases) - [Commits](https://github.com/bmatcuk/doublestar/compare/v4.8.0...v4.8.1) --- updated-dependencies: - dependency-name: github.com/bmatcuk/doublestar/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 47feab9..f1e81e8 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/zitadel/oidc/v3 go 1.21 require ( - github.com/bmatcuk/doublestar/v4 v4.8.0 + github.com/bmatcuk/doublestar/v4 v4.8.1 github.com/go-chi/chi/v5 v5.2.0 github.com/go-jose/go-jose/v4 v4.0.4 github.com/golang/mock v1.6.0 diff --git a/go.sum b/go.sum index 60a5125..a300634 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/bmatcuk/doublestar/v4 v4.8.0 h1:DSXtrypQddoug1459viM9X9D3dp1Z7993fw36I2kNcQ= -github.com/bmatcuk/doublestar/v4 v4.8.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= +github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 8c9a5360587d988691f7b27ed1c2fb9d5e49fc00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:29:28 +0200 Subject: [PATCH 144/185] chore(deps): bump codecov/codecov-action from 5.1.2 to 5.3.1 (#703) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.1.2 to 5.3.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.1.2...v5.3.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f70bd8b..9969c58 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.1.2 + - uses: codecov/codecov-action@v5.3.1 with: file: ./profile.cov name: codecov-go From 4250aad1f7b2ea422153af88096bd366d290124f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:08:45 +0200 Subject: [PATCH 145/185] chore(deps): bump golang.org/x/oauth2 from 0.25.0 to 0.26.0 (#707) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.25.0 to 0.26.0. - [Commits](https://github.com/golang/oauth2/compare/v0.25.0...v0.26.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f1e81e8..f29b4bd 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.1 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 - golang.org/x/oauth2 v0.25.0 + golang.org/x/oauth2 v0.26.0 golang.org/x/text v0.21.0 ) diff --git a/go.sum b/go.sum index a300634..8639d99 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= +golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 0d46df908ef4600e139ae5f6fae8b20c7166571b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 10:11:18 +0000 Subject: [PATCH 146/185] chore(deps): bump golang.org/x/text from 0.21.0 to 0.22.0 (#708) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.21.0 to 0.22.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.21.0...v0.22.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f29b4bd..e48719b 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.26.0 - golang.org/x/text v0.21.0 + golang.org/x/text v0.22.0 ) require ( diff --git a/go.sum b/go.sum index 8639d99..9be3f8d 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From c3c1bd3a404fed7d21a536eadc5e3e375b056fc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:45:18 +0200 Subject: [PATCH 147/185] chore(deps): bump github.com/go-chi/chi/v5 from 5.2.0 to 5.2.1 (#706) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.2.0 to 5.2.1. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.2.0...v5.2.1) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e48719b..a4a71b9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.8.1 - github.com/go-chi/chi/v5 v5.2.0 + github.com/go-chi/chi/v5 v5.2.1 github.com/go-jose/go-jose/v4 v4.0.4 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 diff --git a/go.sum b/go.sum index 9be3f8d..41fd786 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTS github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0= -github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8= +github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From 03e5ff83453c58810f1180ff16e969c676fe3857 Mon Sep 17 00:00:00 2001 From: mqf20 Date: Thu, 13 Feb 2025 19:23:44 +0800 Subject: [PATCH 148/185] docs(example): add auth time (#700) --- example/server/storage/storage.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index d8b7a5d..4c5680e 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -151,6 +151,9 @@ func (s *Storage) CheckUsernamePassword(username, password, id string) error { // in this example we'll simply check the username / password and set a boolean to true // therefore we will also just check this boolean if the request / login has been finished request.done = true + + request.authTime = time.Now() + return nil } return fmt.Errorf("username or password wrong") From 37dd41e49b603cabf32e9b82089e456ce0537626 Mon Sep 17 00:00:00 2001 From: mqf20 Date: Thu, 13 Feb 2025 19:26:00 +0800 Subject: [PATCH 149/185] docs(example): simplified deletion (#699) * simplified deletion * added docs --- example/server/storage/storage.go | 24 ++++++++++-------------- example/server/storage/token.go | 1 + 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index 4c5680e..6a66ca8 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -388,14 +388,9 @@ func (s *Storage) RevokeToken(ctx context.Context, tokenIDOrToken string, userID if refreshToken.ApplicationID != clientID { return oidc.ErrInvalidClient().WithDescription("token was not issued for this client") } - // if it is a refresh token, you will have to remove the access token as well delete(s.refreshTokens, refreshToken.ID) - for _, accessToken := range s.tokens { - if accessToken.RefreshTokenID == refreshToken.ID { - delete(s.tokens, accessToken.ID) - return nil - } - } + // if it is a refresh token, you will have to remove the access token as well + delete(s.tokens, refreshToken.AccessToken) return nil } @@ -597,12 +592,17 @@ func (s *Storage) createRefreshToken(accessToken *Token, amr []string, authTime Audience: accessToken.Audience, Expiration: time.Now().Add(5 * time.Hour), Scopes: accessToken.Scopes, + AccessToken: accessToken.ID, } s.refreshTokens[token.ID] = token return token.Token, nil } // renewRefreshToken checks the provided refresh_token and creates a new one based on the current +// +// [Refresh Token Rotation] is implemented. +// +// [Refresh Token Rotation]: https://www.rfc-editor.org/rfc/rfc6819#section-5.2.2.3 func (s *Storage) renewRefreshToken(currentRefreshToken string) (string, string, error) { s.lock.Lock() defer s.lock.Unlock() @@ -610,14 +610,10 @@ func (s *Storage) renewRefreshToken(currentRefreshToken string) (string, string, if !ok { return "", "", fmt.Errorf("invalid refresh token") } - // deletes the refresh token and all access tokens which were issued based on this refresh token + // deletes the refresh token delete(s.refreshTokens, currentRefreshToken) - for _, token := range s.tokens { - if token.RefreshTokenID == currentRefreshToken { - delete(s.tokens, token.ID) - break - } - } + // delete the access token which was issued based on this refresh token + delete(s.tokens, refreshToken.AccessToken) // creates a new refresh token based on the current one token := uuid.NewString() refreshToken.Token = token diff --git a/example/server/storage/token.go b/example/server/storage/token.go index ad907e3..beab38c 100644 --- a/example/server/storage/token.go +++ b/example/server/storage/token.go @@ -22,4 +22,5 @@ type RefreshToken struct { ApplicationID string Expiration time.Time Scopes []string + AccessToken string // Token.ID } From c03a8c59ca8e7fa49f903bb184793cc735834320 Mon Sep 17 00:00:00 2001 From: mqf20 Date: Thu, 13 Feb 2025 19:34:29 +0800 Subject: [PATCH 150/185] docs(example): check access token expiration (#702) --- example/server/storage/storage.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index 6a66ca8..b687a2c 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -486,6 +486,9 @@ func (s *Storage) SetUserinfoFromToken(ctx context.Context, userinfo *oidc.UserI // return err // } //} + if token.Expiration.Before(time.Now()) { + return fmt.Errorf("token is expired") + } return s.setUserinfo(ctx, userinfo, token.Subject, token.ApplicationID, token.Scopes) } From b1e5aca6298b02e5bd2ed7ae52b37cea0e0ee202 Mon Sep 17 00:00:00 2001 From: mqf20 Date: Thu, 13 Feb 2025 19:48:04 +0800 Subject: [PATCH 151/185] docs(example): check and extend refresh token expiration (#698) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * extend refresh token expiration * check refresh token expiration * check refresh token expiration (fixed logic) * formatting --------- Co-authored-by: Tim Möhlmann --- example/server/storage/storage.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index b687a2c..1bc2e94 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -615,12 +615,19 @@ func (s *Storage) renewRefreshToken(currentRefreshToken string) (string, string, } // deletes the refresh token delete(s.refreshTokens, currentRefreshToken) + // delete the access token which was issued based on this refresh token delete(s.tokens, refreshToken.AccessToken) + + if refreshToken.Expiration.Before(time.Now()) { + return "", "", fmt.Errorf("expired refresh token") + } + // creates a new refresh token based on the current one token := uuid.NewString() refreshToken.Token = token refreshToken.ID = token + refreshToken.Expiration = time.Now().Add(5 * time.Hour) s.refreshTokens[token] = refreshToken return token, refreshToken.ID, nil } From add254f60c9dcb4fcac9606f5adba99bd09d8113 Mon Sep 17 00:00:00 2001 From: mqf20 Date: Wed, 19 Feb 2025 20:44:34 +0800 Subject: [PATCH 152/185] docs(example): fixed creation of refresh token (#711) Signed-off-by: mqf20 --- example/server/storage/storage.go | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index 1bc2e94..fee34c5 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -298,15 +298,19 @@ func (s *Storage) CreateAccessAndRefreshTokens(ctx context.Context, request op.T // if we get here, the currentRefreshToken was not empty, so the call is a refresh token request // we therefore will have to check the currentRefreshToken and renew the refresh token - refreshToken, refreshTokenID, err := s.renewRefreshToken(currentRefreshToken) + + newRefreshToken = uuid.NewString() + + accessToken, err := s.accessToken(applicationID, newRefreshToken, request.GetSubject(), request.GetAudience(), request.GetScopes()) if err != nil { return "", "", time.Time{}, err } - accessToken, err := s.accessToken(applicationID, refreshTokenID, request.GetSubject(), request.GetAudience(), request.GetScopes()) - if err != nil { + + if err := s.renewRefreshToken(currentRefreshToken, newRefreshToken, accessToken.ID); err != nil { return "", "", time.Time{}, err } - return accessToken.ID, refreshToken, accessToken.Expiration, nil + + return accessToken.ID, newRefreshToken, accessToken.Expiration, nil } func (s *Storage) exchangeRefreshToken(ctx context.Context, request op.TokenExchangeRequest) (accessTokenID string, newRefreshToken string, expiration time.Time, err error) { @@ -606,12 +610,12 @@ func (s *Storage) createRefreshToken(accessToken *Token, amr []string, authTime // [Refresh Token Rotation] is implemented. // // [Refresh Token Rotation]: https://www.rfc-editor.org/rfc/rfc6819#section-5.2.2.3 -func (s *Storage) renewRefreshToken(currentRefreshToken string) (string, string, error) { +func (s *Storage) renewRefreshToken(currentRefreshToken, newRefreshToken, newAccessToken string) error { s.lock.Lock() defer s.lock.Unlock() refreshToken, ok := s.refreshTokens[currentRefreshToken] if !ok { - return "", "", fmt.Errorf("invalid refresh token") + return fmt.Errorf("invalid refresh token") } // deletes the refresh token delete(s.refreshTokens, currentRefreshToken) @@ -620,16 +624,16 @@ func (s *Storage) renewRefreshToken(currentRefreshToken string) (string, string, delete(s.tokens, refreshToken.AccessToken) if refreshToken.Expiration.Before(time.Now()) { - return "", "", fmt.Errorf("expired refresh token") + return fmt.Errorf("expired refresh token") } // creates a new refresh token based on the current one - token := uuid.NewString() - refreshToken.Token = token - refreshToken.ID = token + refreshToken.Token = newRefreshToken + refreshToken.ID = newRefreshToken refreshToken.Expiration = time.Now().Add(5 * time.Hour) - s.refreshTokens[token] = refreshToken - return token, refreshToken.ID, nil + refreshToken.AccessToken = newAccessToken + s.refreshTokens[newRefreshToken] = refreshToken + return nil } // accessToken will store an access_token in-memory based on the provided information From eb98343a65d0734071746d8d8ffd48db03207c28 Mon Sep 17 00:00:00 2001 From: Steve Ruckdashel Date: Fri, 21 Feb 2025 02:52:02 -0700 Subject: [PATCH 153/185] fix: migrate deprecated io/ioutil.ReadFile to os.ReadFile (#714) --- pkg/client/key.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/client/key.go b/pkg/client/key.go index 0c01dd2..7f38311 100644 --- a/pkg/client/key.go +++ b/pkg/client/key.go @@ -2,7 +2,7 @@ package client import ( "encoding/json" - "io/ioutil" + "os" ) const ( @@ -24,7 +24,7 @@ type KeyFile struct { } func ConfigFromKeyFile(path string) (*KeyFile, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return nil, err } From 4ef9529012125e5c5e1e7778396a9267e3b8dfba Mon Sep 17 00:00:00 2001 From: minami yoshihiko Date: Mon, 24 Feb 2025 19:50:38 +0900 Subject: [PATCH 154/185] feat: support for session_state (#712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add default signature algorithm * implements session_state in auth_request.go * add test * Update pkg/op/auth_request.go link to the standard Co-authored-by: Tim Möhlmann * add check_session_iframe --------- Co-authored-by: Tim Möhlmann Co-authored-by: Tim Möhlmann --- example/server/storage/oidc.go | 9 +++++++++ pkg/oidc/error.go | 9 ++++++++- pkg/op/auth_request.go | 26 ++++++++++++++++++++------ pkg/op/auth_request_test.go | 28 ++++++++++++++++++++++++++++ pkg/op/config.go | 1 + pkg/op/discovery.go | 1 + pkg/op/error.go | 12 ++++++++++++ pkg/op/mock/configuration.mock.go | 14 ++++++++++++++ pkg/op/op.go | 4 ++++ 9 files changed, 97 insertions(+), 7 deletions(-) diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index 22c0295..c04877f 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -164,6 +164,15 @@ func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthReques } } +type AuthRequestWithSessionState struct { + *AuthRequest + SessionState string +} + +func (a *AuthRequestWithSessionState) GetSessionState() string { + return a.SessionState +} + type OIDCCodeChallenge struct { Challenge string Method string diff --git a/pkg/oidc/error.go b/pkg/oidc/error.go index 1100f73..d93cf44 100644 --- a/pkg/oidc/error.go +++ b/pkg/oidc/error.go @@ -133,6 +133,7 @@ type Error struct { ErrorType errorType `json:"error" schema:"error"` Description string `json:"error_description,omitempty" schema:"error_description,omitempty"` State string `json:"state,omitempty" schema:"state,omitempty"` + SessionState string `json:"session_state,omitempty" schema:"session_state,omitempty"` redirectDisabled bool `schema:"-"` returnParent bool `schema:"-"` } @@ -142,11 +143,13 @@ func (e *Error) MarshalJSON() ([]byte, error) { Error errorType `json:"error"` ErrorDescription string `json:"error_description,omitempty"` State string `json:"state,omitempty"` + SessionState string `json:"session_state,omitempty"` Parent string `json:"parent,omitempty"` }{ Error: e.ErrorType, ErrorDescription: e.Description, State: e.State, + SessionState: e.SessionState, } if e.returnParent { m.Parent = e.Parent.Error() @@ -176,7 +179,8 @@ func (e *Error) Is(target error) bool { } return e.ErrorType == t.ErrorType && (e.Description == t.Description || t.Description == "") && - (e.State == t.State || t.State == "") + (e.State == t.State || t.State == "") && + (e.SessionState == t.SessionState || t.SessionState == "") } func (e *Error) WithParent(err error) *Error { @@ -242,6 +246,9 @@ func (e *Error) LogValue() slog.Value { if e.State != "" { attrs = append(attrs, slog.String("state", e.State)) } + if e.SessionState != "" { + attrs = append(attrs, slog.String("session_state", e.SessionState)) + } if e.redirectDisabled { attrs = append(attrs, slog.Bool("redirect_disabled", e.redirectDisabled)) } diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index d6db62b..82f1b58 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -38,6 +38,13 @@ type AuthRequest interface { Done() bool } +// AuthRequestSessionState should be implemented if [OpenID Connect Session Management](https://openid.net/specs/openid-connect-session-1_0.html) is supported +type AuthRequestSessionState interface { + // GetSessionState returns session_state. + // session_state is related to OpenID Connect Session Management. + GetSessionState() string +} + type Authorizer interface { Storage() Storage Decoder() httphelper.Decoder @@ -103,8 +110,8 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { } return ValidateAuthRequestClient(ctx, authReq, client, verifier) } - if validater, ok := authorizer.(AuthorizeValidator); ok { - validation = validater.ValidateAuthRequest + if validator, ok := authorizer.(AuthorizeValidator); ok { + validation = validator.ValidateAuthRequest } userID, err := validation(ctx, authReq, authorizer.Storage(), authorizer.IDTokenHintVerifier(ctx)) if err != nil { @@ -481,12 +488,19 @@ func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthReques AuthRequestError(w, r, authReq, err, authorizer) return } + var sessionState string + authRequestSessionState, ok := authReq.(AuthRequestSessionState) + if ok { + sessionState = authRequestSessionState.GetSessionState() + } codeResponse := struct { - Code string `schema:"code"` - State string `schema:"state,omitempty"` + Code string `schema:"code"` + State string `schema:"state,omitempty"` + SessionState string `schema:"session_state,omitempty"` }{ - Code: code, - State: authReq.GetState(), + Code: code, + State: authReq.GetState(), + SessionState: sessionState, } if authReq.GetResponseMode() == oidc.ResponseModeFormPost { diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 765e602..4878f5e 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -1090,6 +1090,34 @@ func TestAuthResponseCode(t *testing.T) { wantBody: "", }, }, + { + name: "success with state and session_state", + args: args{ + authReq: &storage.AuthRequestWithSessionState{ + AuthRequest: &storage.AuthRequest{ + ID: "id1", + TransferState: "state1", + }, + SessionState: "session_state1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantCode: http.StatusFound, + wantLocationHeader: "/auth/callback/?code=id1&session_state=session_state1&state=state1", + wantBody: "", + }, + }, { name: "success without state", // reproduce issue #415 args: args{ diff --git a/pkg/op/config.go b/pkg/op/config.go index 2fcede0..b271765 100644 --- a/pkg/op/config.go +++ b/pkg/op/config.go @@ -30,6 +30,7 @@ type Configuration interface { EndSessionEndpoint() *Endpoint KeysEndpoint() *Endpoint DeviceAuthorizationEndpoint() *Endpoint + CheckSessionIframe() *Endpoint AuthMethodPostSupported() bool CodeMethodS256Supported() bool diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index e30a5a4..7aa7cf7 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -45,6 +45,7 @@ func CreateDiscoveryConfig(ctx context.Context, config Configuration, storage Di EndSessionEndpoint: config.EndSessionEndpoint().Absolute(issuer), JwksURI: config.KeysEndpoint().Absolute(issuer), DeviceAuthorizationEndpoint: config.DeviceAuthorizationEndpoint().Absolute(issuer), + CheckSessionIframe: config.CheckSessionIframe().Absolute(issuer), ScopesSupported: Scopes(config), ResponseTypesSupported: ResponseTypes(config), GrantTypesSupported: GrantTypes(config), diff --git a/pkg/op/error.go b/pkg/op/error.go index 44b1798..d57da83 100644 --- a/pkg/op/error.go +++ b/pkg/op/error.go @@ -46,6 +46,12 @@ func AuthRequestError(w http.ResponseWriter, r *http.Request, authReq ErrAuthReq return } e.State = authReq.GetState() + var sessionState string + authRequestSessionState, ok := authReq.(AuthRequestSessionState) + if ok { + sessionState = authRequestSessionState.GetSessionState() + } + e.SessionState = sessionState var responseMode oidc.ResponseMode if rm, ok := authReq.(interface{ GetResponseMode() oidc.ResponseMode }); ok { responseMode = rm.GetResponseMode() @@ -92,6 +98,12 @@ func TryErrorRedirect(ctx context.Context, authReq ErrAuthRequest, parent error, } e.State = authReq.GetState() + var sessionState string + authRequestSessionState, ok := authReq.(AuthRequestSessionState) + if ok { + sessionState = authRequestSessionState.GetSessionState() + } + e.SessionState = sessionState var responseMode oidc.ResponseMode if rm, ok := authReq.(interface{ GetResponseMode() oidc.ResponseMode }); ok { responseMode = rm.GetResponseMode() diff --git a/pkg/op/mock/configuration.mock.go b/pkg/op/mock/configuration.mock.go index 137c09d..0ef9d92 100644 --- a/pkg/op/mock/configuration.mock.go +++ b/pkg/op/mock/configuration.mock.go @@ -106,6 +106,20 @@ func (mr *MockConfigurationMockRecorder) BackChannelLogoutSupported() *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BackChannelLogoutSupported", reflect.TypeOf((*MockConfiguration)(nil).BackChannelLogoutSupported)) } +// CheckSessionIframe mocks base method. +func (m *MockConfiguration) CheckSessionIframe() *op.Endpoint { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckSessionIframe") + ret0, _ := ret[0].(*op.Endpoint) + return ret0 +} + +// CheckSessionIframe indicates an expected call of CheckSessionIframe. +func (mr *MockConfigurationMockRecorder) CheckSessionIframe() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckSessionIframe", reflect.TypeOf((*MockConfiguration)(nil).CheckSessionIframe)) +} + // CodeMethodS256Supported mocks base method. func (m *MockConfiguration) CodeMethodS256Supported() bool { m.ctrl.T.Helper() diff --git a/pkg/op/op.go b/pkg/op/op.go index 190c2c4..58ae838 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -339,6 +339,10 @@ func (o *Provider) DeviceAuthorizationEndpoint() *Endpoint { return o.endpoints.DeviceAuthorization } +func (o *Provider) CheckSessionIframe() *Endpoint { + return o.endpoints.CheckSessionIframe +} + func (o *Provider) KeysEndpoint() *Endpoint { return o.endpoints.JwksURI } From 6a80712fbe4b767c77b4483d46b0b2ce0c2b04e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:00:02 +0200 Subject: [PATCH 155/185] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.4 to 4.0.5 (#716) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.4 to 4.0.5. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v4.0.4...v4.0.5) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index a4a71b9..70ace65 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/bmatcuk/doublestar/v4 v4.8.1 github.com/go-chi/chi/v5 v5.2.1 - github.com/go-jose/go-jose/v4 v4.0.4 + github.com/go-jose/go-jose/v4 v4.0.5 github.com/golang/mock v1.6.0 github.com/google/go-github/v31 v31.0.0 github.com/google/uuid v1.6.0 @@ -31,8 +31,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/net v0.33.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 41fd786..03ecdfd 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8= github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= -github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= -github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -62,8 +62,8 @@ go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt3 go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -83,8 +83,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= From eb2f912c5e5a783e6fb682d5eeea3a13b1ad12c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 16:37:54 +0100 Subject: [PATCH 156/185] chore(deps): bump codecov/codecov-action from 5.3.1 to 5.4.0 (#722) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.3.1 to 5.4.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.3.1...v5.4.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9969c58..c4f6f68 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.3.1 + - uses: codecov/codecov-action@v5.4.0 with: file: ./profile.cov name: codecov-go From 7a767d8568772197503dca7f90b5a767f6f23572 Mon Sep 17 00:00:00 2001 From: BitMasher <61257372+BitMasher@users.noreply.github.com> Date: Wed, 12 Mar 2025 07:00:29 -0500 Subject: [PATCH 157/185] feat: add CanGetPrivateClaimsFromRequest interface (#717) --- pkg/op/storage.go | 6 ++++++ pkg/op/token.go | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pkg/op/storage.go b/pkg/op/storage.go index 8488b28..a579810 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -144,6 +144,12 @@ type CanSetUserinfoFromRequest interface { SetUserinfoFromRequest(ctx context.Context, userinfo *oidc.UserInfo, request IDTokenRequest, scopes []string) error } +// CanGetPrivateClaimsFromRequest is an optional additional interface that may be implemented by +// implementors of Storage. It allows setting the jwt token claims based on the request. +type CanGetPrivateClaimsFromRequest interface { + GetPrivateClaimsFromRequest(ctx context.Context, request TokenRequest, restrictedScopes []string) (map[string]any, error) +} + // Storage is a required parameter for NewOpenIDProvider(). In addition to the // embedded interfaces below, if the passed Storage implements ClientCredentialsStorage // then the grant type "client_credentials" will be supported. In that case, the access diff --git a/pkg/op/token.go b/pkg/op/token.go index 04cd3cc..1df9cc2 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -147,7 +147,11 @@ func CreateJWT(ctx context.Context, issuer string, tokenRequest TokenRequest, ex tokenExchangeRequest, ) } else { - privateClaims, err = storage.GetPrivateClaimsFromScopes(ctx, tokenRequest.GetSubject(), client.GetID(), removeUserinfoScopes(restrictedScopes)) + if fromRequest, ok := storage.(CanGetPrivateClaimsFromRequest); ok { + privateClaims, err = fromRequest.GetPrivateClaimsFromRequest(ctx, tokenRequest, removeUserinfoScopes(restrictedScopes)) + } else { + privateClaims, err = storage.GetPrivateClaimsFromScopes(ctx, tokenRequest.GetSubject(), client.GetID(), removeUserinfoScopes(restrictedScopes)) + } } if err != nil { From efd6fdad7aa2382879821fde4d016236bb5c243a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 14 Mar 2025 12:30:08 +0200 Subject: [PATCH 158/185] fix: ignore empty json strings for locale (#678) * Revert "fix: ignore all unmarshal errors from locale (#673)" This reverts commit fbf009fe75dac732dde39e0eb6fe324b337675e0. * fix: ignore empty json strings for locale --- pkg/oidc/types.go | 22 +++++++++++++----- pkg/oidc/types_test.go | 51 ++++++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 7063426..9b307bc 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -3,6 +3,7 @@ package oidc import ( "database/sql/driver" "encoding/json" + "errors" "fmt" "reflect" "strings" @@ -77,16 +78,25 @@ func (l *Locale) MarshalJSON() ([]byte, error) { } // UnmarshalJSON implements json.Unmarshaler. -// All unmarshal errors for are ignored. -// When an error is encountered, the containing tag will be set +// When [language.ValueError] is encountered, the containing tag will be set // to an empty value (language "und") and no error will be returned. // This state can be checked with the `l.Tag().IsRoot()` method. func (l *Locale) UnmarshalJSON(data []byte) error { - err := json.Unmarshal(data, &l.tag) - if err != nil { - l.tag = language.Tag{} + if len(data) == 0 || string(data) == "\"\"" { + return nil } - return nil + err := json.Unmarshal(data, &l.tag) + if err == nil { + return nil + } + + // catch "well-formed but unknown" errors + var target language.ValueError + if errors.As(err, &target) { + l.tag = language.Tag{} + return nil + } + return err } type Locales []language.Tag diff --git a/pkg/oidc/types_test.go b/pkg/oidc/types_test.go index c7ce0ee..53a9779 100644 --- a/pkg/oidc/types_test.go +++ b/pkg/oidc/types_test.go @@ -217,6 +217,30 @@ func TestLocale_UnmarshalJSON(t *testing.T) { want dst wantErr bool }{ + { + name: "value not present", + input: `{}`, + wantErr: false, + want: dst{ + Locale: nil, + }, + }, + { + name: "null", + input: `{"locale": null}`, + wantErr: false, + want: dst{ + Locale: nil, + }, + }, + { + name: "empty, ignored", + input: `{"locale": ""}`, + wantErr: false, + want: dst{ + Locale: &Locale{}, + }, + }, { name: "afrikaans, ok", input: `{"locale": "af"}`, @@ -232,23 +256,22 @@ func TestLocale_UnmarshalJSON(t *testing.T) { }, }, { - name: "bad form, error", - input: `{"locale": "g!!!!!"}`, - want: dst{ - Locale: &Locale{}, - }, + name: "bad form, error", + input: `{"locale": "g!!!!!"}`, + wantErr: true, }, } - for _, tt := range tests { - var got dst - err := json.Unmarshal([]byte(tt.input), &got) - if tt.wantErr { - require.Error(t, err) - return - } - require.NoError(t, err) - assert.Equal(t, tt.want, got) + t.Run(tt.name, func(t *testing.T) { + var got dst + err := json.Unmarshal([]byte(tt.input), &got) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tt.want, got) + }) } } From 2c64de821d850fc4b6bcd9396012f2bdcad4f954 Mon Sep 17 00:00:00 2001 From: Iraq <66622793+kkrime@users.noreply.github.com> Date: Fri, 14 Mar 2025 15:12:26 +0000 Subject: [PATCH 159/185] chore: updating go to 1.24 (#726) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: updating go to 1.24 * fixup! chore: updating go to 1.24 * fixup! fixup! chore: updating go to 1.24 * fix device test (drop read error) * drop older go versions * drop unrelated formatter changes --------- Co-authored-by: Iraq Jaber Co-authored-by: Tim Möhlmann --- .github/workflows/release.yml | 2 +- README.md | 5 ++--- go.mod | 2 +- pkg/op/device.go | 14 +++++++------- pkg/op/device_test.go | 20 +++++--------------- 5 files changed, 16 insertions(+), 27 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c4f6f68..146f9f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - go: ['1.21', '1.22', '1.23'] + go: ['1.23', '1.24'] name: Go ${{ matrix.go }} test steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 04d551f..bc346f5 100644 --- a/README.md +++ b/README.md @@ -156,10 +156,9 @@ Versions that also build are marked with :warning:. | Version | Supported | | ------- | ------------------ | -| <1.21 | :x: | -| 1.21 | :warning: | -| 1.22 | :white_check_mark: | +| <1.23 | :x: | | 1.23 | :white_check_mark: | +| 1.24 | :white_check_mark: | ## Why another library diff --git a/go.mod b/go.mod index 70ace65..d92ef02 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/zitadel/oidc/v3 -go 1.21 +go 1.23.7 require ( github.com/bmatcuk/doublestar/v4 v4.8.1 diff --git a/pkg/op/device.go b/pkg/op/device.go index 8a0e174..b7290cd 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -91,10 +91,7 @@ func createDeviceAuthorization(ctx context.Context, req *oidc.DeviceAuthorizatio } config := o.DeviceAuthorization() - deviceCode, err := NewDeviceCode(RecommendedDeviceCodeBytes) - if err != nil { - return nil, NewStatusError(err, http.StatusInternalServerError) - } + deviceCode, _ := NewDeviceCode(RecommendedDeviceCodeBytes) userCode, err := NewUserCode([]rune(config.UserCode.CharSet), config.UserCode.CharAmount, config.UserCode.DashInterval) if err != nil { return nil, NewStatusError(err, http.StatusInternalServerError) @@ -163,11 +160,14 @@ func ParseDeviceCodeRequest(r *http.Request, o OpenIDProvider) (*oidc.DeviceAuth // results in a 22 character base64 encoded string. const RecommendedDeviceCodeBytes = 16 +// NewDeviceCode generates a new cryptographically secure device code as a base64 encoded string. +// The length of the string is nBytes * 4 / 3. +// An error is never returned. +// +// TODO(v4): change return type to string alone. func NewDeviceCode(nBytes int) (string, error) { bytes := make([]byte, nBytes) - if _, err := rand.Read(bytes); err != nil { - return "", fmt.Errorf("%w getting entropy for device code", err) - } + rand.Read(bytes) return base64.RawURLEncoding.EncodeToString(bytes), nil } diff --git a/pkg/op/device_test.go b/pkg/op/device_test.go index 570b943..5fd9c9b 100644 --- a/pkg/op/device_test.go +++ b/pkg/op/device_test.go @@ -145,21 +145,11 @@ func runWithRandReader(r io.Reader, f func()) { } func TestNewDeviceCode(t *testing.T) { - t.Run("reader error", func(t *testing.T) { - runWithRandReader(errReader{}, func() { - _, err := op.NewDeviceCode(16) - require.Error(t, err) - }) - }) - - t.Run("different lengths, rand reader", func(t *testing.T) { - for i := 1; i <= 32; i++ { - got, err := op.NewDeviceCode(i) - require.NoError(t, err) - assert.Len(t, got, base64.RawURLEncoding.EncodedLen(i)) - } - }) - + for i := 1; i <= 32; i++ { + got, err := op.NewDeviceCode(i) + require.NoError(t, err) + assert.Len(t, got, base64.RawURLEncoding.EncodedLen(i)) + } } func TestNewUserCode(t *testing.T) { From c401ad6cb8b98caa70ab4b6c08f9d317b528d53c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 07:46:07 +0100 Subject: [PATCH 160/185] chore(deps): bump golang.org/x/oauth2 from 0.26.0 to 0.28.0 (#724) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.26.0 to 0.28.0. - [Commits](https://github.com/golang/oauth2/compare/v0.26.0...v0.28.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d92ef02..01fd47a 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/zitadel/logging v0.6.1 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 - golang.org/x/oauth2 v0.26.0 + golang.org/x/oauth2 v0.28.0 golang.org/x/text v0.22.0 ) diff --git a/go.sum b/go.sum index 03ecdfd..1d32f03 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= +golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From f3ee6470052ad846de95ce30af80820fa86cc98a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:02:56 +0200 Subject: [PATCH 161/185] chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 (#727) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.33.0 to 0.36.0. - [Commits](https://github.com/golang/net/compare/v0.33.0...v0.36.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 7 ++++--- go.sum | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 01fd47a..3e93574 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/zitadel/oidc/v3 go 1.23.7 +toolchain go1.24.1 require ( github.com/bmatcuk/doublestar/v4 v4.8.1 @@ -31,8 +32,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/sys v0.29.0 // indirect + golang.org/x/crypto v0.35.0 // indirect + golang.org/x/net v0.36.0 // indirect + golang.org/x/sys v0.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 1d32f03..013abc0 100644 --- a/go.sum +++ b/go.sum @@ -62,16 +62,16 @@ go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt3 go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= @@ -83,8 +83,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= From aeda5d7178ac859757f8ad925df67da819975126 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:05:10 +0000 Subject: [PATCH 162/185] chore(deps): bump golang.org/x/text from 0.22.0 to 0.23.0 (#723) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.22.0 to 0.23.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3e93574..ded75c1 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.28.0 - golang.org/x/text v0.22.0 + golang.org/x/text v0.23.0 ) require ( diff --git a/go.sum b/go.sum index 013abc0..f2dc9de 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From 30acdaf63a5305fcf1efe29c2f605b7566478ba5 Mon Sep 17 00:00:00 2001 From: Iraq Jaber Date: Sun, 23 Mar 2025 16:27:57 +0000 Subject: [PATCH 163/185] chore: run 'go mod tidy' --- go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/go.mod b/go.mod index ded75c1..3c2a555 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/zitadel/oidc/v3 go 1.23.7 + toolchain go1.24.1 require ( From c91db9e47b147ce8c5d8ba33939782b6177f78bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 12:11:07 +0200 Subject: [PATCH 164/185] chore(deps): bump github.com/zitadel/logging from 0.6.1 to 0.6.2 (#730) Bumps [github.com/zitadel/logging](https://github.com/zitadel/logging) from 0.6.1 to 0.6.2. - [Release notes](https://github.com/zitadel/logging/releases) - [Changelog](https://github.com/zitadel/logging/blob/main/.releaserc.js) - [Commits](https://github.com/zitadel/logging/compare/v0.6.1...v0.6.2) --- updated-dependencies: - dependency-name: github.com/zitadel/logging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 3c2a555..2dc816b 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/rs/cors v1.11.1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 - github.com/zitadel/logging v0.6.1 + github.com/zitadel/logging v0.6.2 github.com/zitadel/schema v1.3.0 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.28.0 diff --git a/go.sum b/go.sum index f2dc9de..6645565 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zitadel/logging v0.6.1 h1:Vyzk1rl9Kq9RCevcpX6ujUaTYFX43aa4LkvV1TvUk+Y= -github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= +github.com/zitadel/logging v0.6.2 h1:MW2kDDR0ieQynPZ0KIZPrh9ote2WkxfBif5QoARDQcU= +github.com/zitadel/logging v0.6.2/go.mod h1:z6VWLWUkJpnNVDSLzrPSQSQyttysKZ6bCRongw0ROK4= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= @@ -101,8 +101,8 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl 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/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 7096406e71f682c492da1a2d4b6a4a0b88ffd34a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 12:19:20 +0200 Subject: [PATCH 165/185] chore(deps): bump github.com/zitadel/schema from 1.3.0 to 1.3.1 (#731) Bumps [github.com/zitadel/schema](https://github.com/zitadel/schema) from 1.3.0 to 1.3.1. - [Release notes](https://github.com/zitadel/schema/releases) - [Changelog](https://github.com/zitadel/schema/blob/main/.releaserc.js) - [Commits](https://github.com/zitadel/schema/compare/v1.3.0...v1.3.1) --- updated-dependencies: - dependency-name: github.com/zitadel/schema dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2dc816b..d0d892a 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 github.com/zitadel/logging v0.6.2 - github.com/zitadel/schema v1.3.0 + github.com/zitadel/schema v1.3.1 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.28.0 golang.org/x/text v0.23.0 diff --git a/go.sum b/go.sum index 6645565..e174d34 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,8 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zitadel/logging v0.6.2 h1:MW2kDDR0ieQynPZ0KIZPrh9ote2WkxfBif5QoARDQcU= github.com/zitadel/logging v0.6.2/go.mod h1:z6VWLWUkJpnNVDSLzrPSQSQyttysKZ6bCRongw0ROK4= -github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= -github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= +github.com/zitadel/schema v1.3.1 h1:QT3kwiRIRXXLVAs6gCK/u044WmUVh6IlbLXUsn6yRQU= +github.com/zitadel/schema v1.3.1/go.mod h1:071u7D2LQacy1HAN+YnMd/mx1qVE2isb0Mjeqg46xnU= go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= From c51628ea27035796152a32631439625b55f0a7ea Mon Sep 17 00:00:00 2001 From: Ayato Date: Tue, 25 Mar 2025 01:00:04 +0900 Subject: [PATCH 166/185] feat(op): always verify code challenge when available (#721) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finally the RFC Best Current Practice for OAuth 2.0 Security has been approved. According to the RFC: > Authorization servers MUST support PKCE [RFC7636]. > > If a client sends a valid PKCE code_challenge parameter in the authorization request, the authorization server MUST enforce the correct usage of code_verifier at the token endpoint. Isn’t it time we strengthen PKCE support a bit more? This PR updates the logic so that PKCE is always verified, even when the Auth Method is not "none". --- example/client/app/app.go | 12 +++++++++ example/server/exampleop/templates/login.html | 4 +-- example/server/storage/oidc.go | 15 +++++++---- pkg/op/op_test.go | 1 + pkg/op/server_http_routes_test.go | 2 +- pkg/op/token_code.go | 26 ++++++++++++++----- 6 files changed, 45 insertions(+), 15 deletions(-) diff --git a/example/client/app/app.go b/example/client/app/app.go index 0b9b19d..5740591 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -7,6 +7,7 @@ import ( "log/slog" "net/http" "os" + "strconv" "strings" "sync/atomic" "time" @@ -34,6 +35,14 @@ func main() { scopes := strings.Split(os.Getenv("SCOPES"), " ") responseMode := os.Getenv("RESPONSE_MODE") + var pkce bool + if pkceEnv, ok := os.LookupEnv("PKCE"); ok { + var err error + pkce, err = strconv.ParseBool(pkceEnv) + if err != nil { + logrus.Fatalf("error parsing PKCE %s", err.Error()) + } + } redirectURI := fmt.Sprintf("http://localhost:%v%v", port, callbackPath) cookieHandler := httphelper.NewCookieHandler(key, key, httphelper.WithUnsecure()) @@ -64,6 +73,9 @@ func main() { if keyPath != "" { options = append(options, rp.WithJWTProfile(rp.SignerFromKeyPath(keyPath))) } + if pkce { + options = append(options, rp.WithPKCE(cookieHandler)) + } // One can add a logger to the context, // pre-defining log attributes as required. diff --git a/example/server/exampleop/templates/login.html b/example/server/exampleop/templates/login.html index b048211..d7f8f9a 100644 --- a/example/server/exampleop/templates/login.html +++ b/example/server/exampleop/templates/login.html @@ -25,5 +25,5 @@ -` -{{- end }} \ No newline at end of file + +{{- end }} diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index c04877f..3d5d86b 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -18,7 +18,7 @@ const ( // CustomClaim is an example for how to return custom claims with this library CustomClaim = "custom_claim" - // CustomScopeImpersonatePrefix is an example scope prefix for passing user id to impersonate using token exchage + // CustomScopeImpersonatePrefix is an example scope prefix for passing user id to impersonate using token exchange CustomScopeImpersonatePrefix = "custom_scope:impersonate:" ) @@ -143,6 +143,14 @@ func MaxAgeToInternal(maxAge *uint) *time.Duration { } func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthRequest { + var codeChallenge *OIDCCodeChallenge + if authReq.CodeChallenge != "" { + codeChallenge = &OIDCCodeChallenge{ + Challenge: authReq.CodeChallenge, + Method: string(authReq.CodeChallengeMethod), + } + } + return &AuthRequest{ CreationDate: time.Now(), ApplicationID: authReq.ClientID, @@ -157,10 +165,7 @@ func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthReques ResponseType: authReq.ResponseType, ResponseMode: authReq.ResponseMode, Nonce: authReq.Nonce, - CodeChallenge: &OIDCCodeChallenge{ - Challenge: authReq.CodeChallenge, - Method: string(authReq.CodeChallengeMethod), - }, + CodeChallenge: codeChallenge, } } diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index 9a4a624..c1520e2 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -102,6 +102,7 @@ func TestRoutes(t *testing.T) { authReq, err := storage.CreateAuthRequest(ctx, oidcAuthReq, "id1") require.NoError(t, err) storage.AuthRequestDone(authReq.GetID()) + storage.SaveAuthCode(ctx, authReq.GetID(), "123") accessToken, refreshToken, _, err := op.CreateAccessToken(ctx, authReq, op.AccessTokenTypeBearer, testProvider, client, "") require.NoError(t, err) diff --git a/pkg/op/server_http_routes_test.go b/pkg/op/server_http_routes_test.go index 1bfb32b..e0e4a97 100644 --- a/pkg/op/server_http_routes_test.go +++ b/pkg/op/server_http_routes_test.go @@ -130,7 +130,7 @@ func TestServerRoutes(t *testing.T) { "client_id": client.GetID(), "client_secret": "secret", "redirect_uri": "https://example.com", - "code": "123", + "code": "abc", }, wantCode: http.StatusBadRequest, json: `{"error":"invalid_grant", "error_description":"invalid code"}`, diff --git a/pkg/op/token_code.go b/pkg/op/token_code.go index 3612240..019aa63 100644 --- a/pkg/op/token_code.go +++ b/pkg/op/token_code.go @@ -74,6 +74,20 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, ctx, span := tracer.Start(ctx, "AuthorizeCodeClient") defer span.End() + request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) + if err != nil { + return nil, nil, err + } + + codeChallenge := request.GetCodeChallenge() + if codeChallenge != nil { + err = AuthorizeCodeChallenge(tokenReq.CodeVerifier, codeChallenge) + + if err != nil { + return nil, nil, err + } + } + if tokenReq.ClientAssertionType == oidc.ClientAssertionTypeJWTAssertion { jwtExchanger, ok := exchanger.(JWTAuthorizationGrantExchanger) if !ok || !exchanger.AuthMethodPrivateKeyJWTSupported() { @@ -83,9 +97,9 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, if err != nil { return nil, nil, err } - request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) return request, client, err } + client, err = exchanger.Storage().GetClientByClientID(ctx, tokenReq.ClientID) if err != nil { return nil, nil, oidc.ErrInvalidClient().WithParent(err) @@ -94,12 +108,10 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, return nil, nil, oidc.ErrInvalidClient().WithDescription("private_key_jwt not allowed for this client") } if client.AuthMethod() == oidc.AuthMethodNone { - request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) - if err != nil { - return nil, nil, err + if codeChallenge == nil { + return nil, nil, oidc.ErrInvalidRequest().WithDescription("PKCE required") } - err = AuthorizeCodeChallenge(tokenReq.CodeVerifier, request.GetCodeChallenge()) - return request, client, err + return request, client, nil } if client.AuthMethod() == oidc.AuthMethodPost && !exchanger.AuthMethodPostSupported() { return nil, nil, oidc.ErrInvalidClient().WithDescription("auth_method post not supported") @@ -108,7 +120,7 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, if err != nil { return nil, nil, err } - request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) + return request, client, err } From 92972fd30f02756cdf361c024342fbc8f2cb660c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 15:03:06 +0300 Subject: [PATCH 167/185] chore(deps): bump golang.org/x/oauth2 from 0.28.0 to 0.29.0 (#734) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.28.0 to 0.29.0. - [Commits](https://github.com/golang/oauth2/compare/v0.28.0...v0.29.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-version: 0.29.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d0d892a..ecfc3e8 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/zitadel/logging v0.6.2 github.com/zitadel/schema v1.3.1 go.opentelemetry.io/otel v1.29.0 - golang.org/x/oauth2 v0.28.0 + golang.org/x/oauth2 v0.29.0 golang.org/x/text v0.23.0 ) diff --git a/go.sum b/go.sum index e174d34..35d356f 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= -golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 7cc5fb656818b9da48d34252c186b3d715cf2af0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 12:05:26 +0000 Subject: [PATCH 168/185] chore(deps): bump golang.org/x/text from 0.23.0 to 0.24.0 (#733) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.23.0 to 0.24.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.23.0...v0.24.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-version: 0.24.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ecfc3e8..3ba70d1 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/zitadel/schema v1.3.1 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.29.0 - golang.org/x/text v0.23.0 + golang.org/x/text v0.24.0 ) require ( diff --git a/go.sum b/go.sum index 35d356f..0052890 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From cb3ec3ac5f9bcfb07ffb51c4230291408a3501de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:05:39 +0200 Subject: [PATCH 169/185] chore(deps): bump golang.org/x/net from 0.36.0 to 0.38.0 (#739) * chore(deps): bump golang.org/x/net from 0.36.0 to 0.38.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0. - [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.38.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] * update runner to ubuntu 24.04 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Livio Spring --- .github/workflows/release.yml | 4 ++-- go.mod | 6 +++--- go.sum | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 146f9f2..36ad346 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ on: jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -32,7 +32,7 @@ jobs: file: ./profile.cov name: codecov-go release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: [test] if: ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next' }} env: diff --git a/go.mod b/go.mod index 3ba70d1..f5ad96b 100644 --- a/go.mod +++ b/go.mod @@ -33,8 +33,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/net v0.36.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0052890..e0ac4f5 100644 --- a/go.sum +++ b/go.sum @@ -62,16 +62,16 @@ go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt3 go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= -golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= @@ -83,8 +83,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= From b917cdc2e3cc021815e28e30bde8c3ea688aa339 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:13:43 +0200 Subject: [PATCH 170/185] chore(deps): bump codecov/codecov-action from 5.4.0 to 5.4.2 (#737) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.0 to 5.4.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.4.0...v5.4.2) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: 5.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 36ad346..20cb6df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.4.0 + - uses: codecov/codecov-action@v5.4.2 with: file: ./profile.cov name: codecov-go From 5913c5a07482829532d831b168a82255cba0e8cc Mon Sep 17 00:00:00 2001 From: Masahito Osako <43847020+m11o@users.noreply.github.com> Date: Tue, 29 Apr 2025 23:17:28 +0900 Subject: [PATCH 171/185] feat: enhance authentication response handling (#728) - Introduced CodeResponseType struct to encapsulate response data. - Added handleFormPostResponse and handleRedirectResponse functions to manage different response modes. - Created BuildAuthResponseCodeResponsePayload and BuildAuthResponseCallbackURL functions for better modularity in response generation. --- pkg/op/auth_request.go | 82 ++++++--- pkg/op/auth_request_test.go | 355 ++++++++++++++++++++++++++++++++++++ 2 files changed, 410 insertions(+), 27 deletions(-) diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 82f1b58..2c013aa 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -62,6 +62,12 @@ type AuthorizeValidator interface { ValidateAuthRequest(context.Context, *oidc.AuthRequest, Storage, *IDTokenHintVerifier) (string, error) } +type CodeResponseType struct { + Code string `schema:"code"` + State string `schema:"state,omitempty"` + SessionState string `schema:"session_state,omitempty"` +} + func authorizeHandler(authorizer Authorizer) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { Authorize(w, r, authorizer) @@ -477,48 +483,70 @@ func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWri AuthResponseToken(w, r, authReq, authorizer, client) } -// AuthResponseCode creates the successful code authentication response +// AuthResponseCode handles the creation of a successful authentication response using an authorization code func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer) { ctx, span := tracer.Start(r.Context(), "AuthResponseCode") - r = r.WithContext(ctx) defer span.End() + r = r.WithContext(ctx) + + var err error + if authReq.GetResponseMode() == oidc.ResponseModeFormPost { + err = handleFormPostResponse(w, r, authReq, authorizer) + } else { + err = handleRedirectResponse(w, r, authReq, authorizer) + } - code, err := CreateAuthRequestCode(r.Context(), authReq, authorizer.Storage(), authorizer.Crypto()) if err != nil { AuthRequestError(w, r, authReq, err, authorizer) - return } - var sessionState string - authRequestSessionState, ok := authReq.(AuthRequestSessionState) - if ok { +} + +// handleFormPostResponse processes the authentication response using form post method +func handleFormPostResponse(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer) error { + codeResponse, err := BuildAuthResponseCodeResponsePayload(r.Context(), authReq, authorizer) + if err != nil { + return err + } + return AuthResponseFormPost(w, authReq.GetRedirectURI(), codeResponse, authorizer.Encoder()) +} + +// handleRedirectResponse processes the authentication response using the redirect method +func handleRedirectResponse(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer) error { + callbackURL, err := BuildAuthResponseCallbackURL(r.Context(), authReq, authorizer) + if err != nil { + return err + } + http.Redirect(w, r, callbackURL, http.StatusFound) + return nil +} + +// BuildAuthResponseCodeResponsePayload generates the authorization code response payload for the authentication request +func BuildAuthResponseCodeResponsePayload(ctx context.Context, authReq AuthRequest, authorizer Authorizer) (*CodeResponseType, error) { + code, err := CreateAuthRequestCode(ctx, authReq, authorizer.Storage(), authorizer.Crypto()) + if err != nil { + return nil, err + } + + sessionState := "" + if authRequestSessionState, ok := authReq.(AuthRequestSessionState); ok { sessionState = authRequestSessionState.GetSessionState() } - codeResponse := struct { - Code string `schema:"code"` - State string `schema:"state,omitempty"` - SessionState string `schema:"session_state,omitempty"` - }{ + + return &CodeResponseType{ Code: code, State: authReq.GetState(), SessionState: sessionState, - } + }, nil +} - if authReq.GetResponseMode() == oidc.ResponseModeFormPost { - err := AuthResponseFormPost(w, authReq.GetRedirectURI(), &codeResponse, authorizer.Encoder()) - if err != nil { - AuthRequestError(w, r, authReq, err, authorizer) - return - } - - return - } - - callback, err := AuthResponseURL(authReq.GetRedirectURI(), authReq.GetResponseType(), authReq.GetResponseMode(), &codeResponse, authorizer.Encoder()) +// BuildAuthResponseCallbackURL generates the callback URL for a successful authorization code response +func BuildAuthResponseCallbackURL(ctx context.Context, authReq AuthRequest, authorizer Authorizer) (string, error) { + codeResponse, err := BuildAuthResponseCodeResponsePayload(ctx, authReq, authorizer) if err != nil { - AuthRequestError(w, r, authReq, err, authorizer) - return + return "", err } - http.Redirect(w, r, callback, http.StatusFound) + + return AuthResponseURL(authReq.GetRedirectURI(), authReq.GetResponseType(), authReq.GetResponseMode(), codeResponse, authorizer.Encoder()) } // AuthResponseToken creates the successful token(s) authentication response diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 4878f5e..f0c4ef1 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -1225,6 +1225,133 @@ func Test_parseAuthorizeCallbackRequest(t *testing.T) { } } +func TestBuildAuthResponseCodeResponsePayload(t *testing.T) { + type args struct { + authReq op.AuthRequest + authorizer func(*testing.T) op.Authorizer + } + type res struct { + wantCode string + wantState string + wantSessionState string + wantErr bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "create code error", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{ + returnErr: io.ErrClosedPipe, + }) + return authorizer + }, + }, + res: res{ + wantErr: true, + }, + }, + { + name: "success with state", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + TransferState: "state1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + return authorizer + }, + }, + res: res{ + wantCode: "id1", + wantState: "state1", + }, + }, + { + name: "success without state", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + TransferState: "", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + return authorizer + }, + }, + res: res{ + wantCode: "id1", + wantState: "", + }, + }, + { + name: "success with session_state", + args: args{ + authReq: &storage.AuthRequestWithSessionState{ + AuthRequest: &storage.AuthRequest{ + ID: "id1", + TransferState: "state1", + }, + SessionState: "session_state1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + return authorizer + }, + }, + res: res{ + wantCode: "id1", + wantState: "state1", + wantSessionState: "session_state1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := op.BuildAuthResponseCodeResponsePayload(context.Background(), tt.args.authReq, tt.args.authorizer(t)) + if tt.res.wantErr { + assert.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tt.res.wantCode, got.Code) + assert.Equal(t, tt.res.wantState, got.State) + assert.Equal(t, tt.res.wantSessionState, got.SessionState) + }) + } +} + func TestValidateAuthReqIDTokenHint(t *testing.T) { token, _ := tu.ValidIDToken() tests := []struct { @@ -1255,3 +1382,231 @@ func TestValidateAuthReqIDTokenHint(t *testing.T) { }) } } + +func TestBuildAuthResponseCallbackURL(t *testing.T) { + type args struct { + authReq op.AuthRequest + authorizer func(*testing.T) op.Authorizer + } + type res struct { + wantURL string + wantErr bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "error when generating code response", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{ + returnErr: io.ErrClosedPipe, + }) + return authorizer + }, + }, + res: res{ + wantErr: true, + }, + }, + { + name: "error when generating callback URL", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "://invalid-url", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantErr: true, + }, + }, + { + name: "success with state", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "https://example.com/callback", + TransferState: "state1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantURL: "https://example.com/callback?code=id1&state=state1", + wantErr: false, + }, + }, + { + name: "success without state", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "https://example.com/callback", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantURL: "https://example.com/callback?code=id1", + wantErr: false, + }, + }, + { + name: "success with session_state", + args: args{ + authReq: &storage.AuthRequestWithSessionState{ + AuthRequest: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "https://example.com/callback", + TransferState: "state1", + }, + SessionState: "session_state1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantURL: "https://example.com/callback?code=id1&session_state=session_state1&state=state1", + wantErr: false, + }, + }, + { + name: "success with existing query parameters", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "https://example.com/callback?param=value", + TransferState: "state1", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantURL: "https://example.com/callback?param=value&code=id1&state=state1", + wantErr: false, + }, + }, + { + name: "success with fragment response mode", + args: args{ + authReq: &storage.AuthRequest{ + ID: "id1", + CallbackURI: "https://example.com/callback", + TransferState: "state1", + ResponseMode: "fragment", + }, + authorizer: func(t *testing.T) op.Authorizer { + ctrl := gomock.NewController(t) + storage := mock.NewMockStorage(ctrl) + storage.EXPECT().SaveAuthCode(gomock.Any(), "id1", "id1") + + authorizer := mock.NewMockAuthorizer(ctrl) + authorizer.EXPECT().Storage().Return(storage) + authorizer.EXPECT().Crypto().Return(&mockCrypto{}) + authorizer.EXPECT().Encoder().Return(schema.NewEncoder()) + return authorizer + }, + }, + res: res{ + wantURL: "https://example.com/callback#code=id1&state=state1", + wantErr: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := op.BuildAuthResponseCallbackURL(context.Background(), tt.args.authReq, tt.args.authorizer(t)) + if tt.res.wantErr { + assert.Error(t, err) + return + } + require.NoError(t, err) + + if tt.res.wantURL != "" { + // Parse the URLs to compare components instead of direct string comparison + expectedURL, err := url.Parse(tt.res.wantURL) + require.NoError(t, err) + actualURL, err := url.Parse(got) + require.NoError(t, err) + + // Compare the base parts (scheme, host, path) + assert.Equal(t, expectedURL.Scheme, actualURL.Scheme) + assert.Equal(t, expectedURL.Host, actualURL.Host) + assert.Equal(t, expectedURL.Path, actualURL.Path) + + // Compare the fragment if any + assert.Equal(t, expectedURL.Fragment, actualURL.Fragment) + + // For query parameters, compare them independently of order + expectedQuery := expectedURL.Query() + actualQuery := actualURL.Query() + + assert.Equal(t, len(expectedQuery), len(actualQuery), "Query parameter count does not match") + + for key, expectedValues := range expectedQuery { + actualValues, exists := actualQuery[key] + assert.True(t, exists, "Expected query parameter %s not found", key) + assert.ElementsMatch(t, expectedValues, actualValues, "Values for parameter %s don't match", key) + } + } + }) + } +} From 4f0ed79c0a49c9de7341300c0d1e45e5c1e38796 Mon Sep 17 00:00:00 2001 From: Ayato Date: Tue, 29 Apr 2025 23:33:31 +0900 Subject: [PATCH 172/185] fix(op): Add mitigation for PKCE Downgrade Attack (#741) * fix(op): Add mitigation for PKCE downgrade attack * chore(op): add test for PKCE verification --- pkg/op/token_code.go | 9 ++--- pkg/op/token_request.go | 12 +++++- pkg/op/token_request_test.go | 75 ++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 pkg/op/token_request_test.go diff --git a/pkg/op/token_code.go b/pkg/op/token_code.go index 019aa63..fb636b4 100644 --- a/pkg/op/token_code.go +++ b/pkg/op/token_code.go @@ -80,12 +80,9 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, } codeChallenge := request.GetCodeChallenge() - if codeChallenge != nil { - err = AuthorizeCodeChallenge(tokenReq.CodeVerifier, codeChallenge) - - if err != nil { - return nil, nil, err - } + err = AuthorizeCodeChallenge(tokenReq.CodeVerifier, codeChallenge) + if err != nil { + return nil, nil, err } if tokenReq.ClientAssertionType == oidc.ClientAssertionTypeJWTAssertion { diff --git a/pkg/op/token_request.go b/pkg/op/token_request.go index 85e2270..66e4c83 100644 --- a/pkg/op/token_request.go +++ b/pkg/op/token_request.go @@ -132,11 +132,19 @@ func AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string, // AuthorizeCodeChallenge authorizes a client by validating the code_verifier against the previously sent // code_challenge of the auth request (PKCE) func AuthorizeCodeChallenge(codeVerifier string, challenge *oidc.CodeChallenge) error { + if challenge == nil { + if codeVerifier != "" { + return oidc.ErrInvalidRequest().WithDescription("code_verifier unexpectedly provided") + } + + return nil + } + if codeVerifier == "" { - return oidc.ErrInvalidRequest().WithDescription("code_challenge required") + return oidc.ErrInvalidRequest().WithDescription("code_verifier required") } if !oidc.VerifyCodeChallenge(challenge, codeVerifier) { - return oidc.ErrInvalidGrant().WithDescription("invalid code challenge") + return oidc.ErrInvalidGrant().WithDescription("invalid code_verifier") } return nil } diff --git a/pkg/op/token_request_test.go b/pkg/op/token_request_test.go new file mode 100644 index 0000000..21cf20b --- /dev/null +++ b/pkg/op/token_request_test.go @@ -0,0 +1,75 @@ +package op_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" +) + +func TestAuthorizeCodeChallenge(t *testing.T) { + tests := []struct { + name string + codeVerifier string + codeChallenge *oidc.CodeChallenge + want func(t *testing.T, err error) + }{ + { + name: "missing both code_verifier and code_challenge", + codeVerifier: "", + codeChallenge: nil, + want: func(t *testing.T, err error) { + assert.Nil(t, err) + }, + }, + { + name: "valid code_verifier", + codeVerifier: "Hello World!", + codeChallenge: &oidc.CodeChallenge{ + Challenge: "f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", + Method: oidc.CodeChallengeMethodS256, + }, + want: func(t *testing.T, err error) { + assert.Nil(t, err) + }, + }, + { + name: "invalid code_verifier", + codeVerifier: "Hi World!", + codeChallenge: &oidc.CodeChallenge{ + Challenge: "f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", + Method: oidc.CodeChallengeMethodS256, + }, + want: func(t *testing.T, err error) { + assert.ErrorContains(t, err, "invalid code_verifier") + }, + }, + { + name: "code_verifier provided without code_challenge", + codeVerifier: "code_verifier", + codeChallenge: nil, + want: func(t *testing.T, err error) { + assert.ErrorContains(t, err, "code_verifier unexpectedly provided") + }, + }, + { + name: "empty code_verifier", + codeVerifier: "", + codeChallenge: &oidc.CodeChallenge{ + Challenge: "f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", + Method: oidc.CodeChallengeMethodS256, + }, + want: func(t *testing.T, err error) { + assert.ErrorContains(t, err, "code_verifier required") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := op.AuthorizeCodeChallenge(tt.codeVerifier, tt.codeChallenge) + + tt.want(t, err) + }) + } +} From 4ed4d257ab4b4c3b1b2ffbdb7e41ffa88e3173ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 08:00:26 +0200 Subject: [PATCH 173/185] chore(deps): bump golang.org/x/oauth2 from 0.29.0 to 0.30.0 (#743) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.29.0 to 0.30.0. - [Commits](https://github.com/golang/oauth2/compare/v0.29.0...v0.30.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-version: 0.30.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f5ad96b..efb6b22 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/zitadel/logging v0.6.2 github.com/zitadel/schema v1.3.1 go.opentelemetry.io/otel v1.29.0 - golang.org/x/oauth2 v0.29.0 + golang.org/x/oauth2 v0.30.0 golang.org/x/text v0.24.0 ) diff --git a/go.sum b/go.sum index e0ac4f5..6507dbc 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 668fb0d37a2ae6b2b29706b3531c32681d00134f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 08:04:53 +0200 Subject: [PATCH 174/185] chore(deps): bump golang.org/x/text from 0.24.0 to 0.25.0 (#742) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.24.0 to 0.25.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.24.0...v0.25.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-version: 0.25.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index efb6b22..a15fd33 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/zitadel/schema v1.3.1 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.30.0 - golang.org/x/text v0.24.0 + golang.org/x/text v0.25.0 ) require ( diff --git a/go.sum b/go.sum index 6507dbc..2f9e525 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From 7d57aaa99983368527b0fc93f72ab5542b2eefd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 15:22:02 +0300 Subject: [PATCH 175/185] chore(deps): bump codecov/codecov-action from 5.4.2 to 5.4.3 (#751) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.2 to 5.4.3. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.4.2...v5.4.3) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: 5.4.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 20cb6df..00063e4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.4.2 + - uses: codecov/codecov-action@v5.4.3 with: file: ./profile.cov name: codecov-go From f94bd541d7b78276261f7c453e69a9de71c1a6cd Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Thu, 5 Jun 2025 13:19:51 +0200 Subject: [PATCH 176/185] feat: update end session request to pass all params according to specification (#754) * feat: update end session request to pass all params according to specification * register encoder --- pkg/oidc/session.go | 12 +++++++----- pkg/oidc/types.go | 11 +++++++++++ pkg/op/session.go | 2 ++ pkg/op/storage.go | 3 +++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/pkg/oidc/session.go b/pkg/oidc/session.go index b470d1e..39f9f08 100644 --- a/pkg/oidc/session.go +++ b/pkg/oidc/session.go @@ -1,10 +1,12 @@ package oidc // EndSessionRequest for the RP-Initiated Logout according to: -//https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout +// https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout type EndSessionRequest struct { - IdTokenHint string `schema:"id_token_hint"` - ClientID string `schema:"client_id"` - PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"` - State string `schema:"state"` + IdTokenHint string `schema:"id_token_hint"` + LogoutHint string `schema:"logout_hint"` + ClientID string `schema:"client_id"` + PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"` + State string `schema:"state"` + UILocales Locales `schema:"ui_locales"` } diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 9b307bc..33ad2d5 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -115,6 +115,14 @@ func ParseLocales(locales []string) Locales { return out } +func (l Locales) String() string { + tags := make([]string, len(l)) + for i, tag := range l { + tags[i] = tag.String() + } + return strings.Join(tags, " ") +} + // UnmarshalText implements the [encoding.TextUnmarshaler] interface. // It decodes an unquoted space seperated string into Locales. // Undefined language tags in the input are ignored and ommited from @@ -231,6 +239,9 @@ func NewEncoder() *schema.Encoder { e.RegisterEncoder(SpaceDelimitedArray{}, func(value reflect.Value) string { return value.Interface().(SpaceDelimitedArray).String() }) + e.RegisterEncoder(Locales{}, func(value reflect.Value) string { + return value.Interface().(Locales).String() + }) return e } diff --git a/pkg/op/session.go b/pkg/op/session.go index 8ac530d..eb67b3c 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -73,6 +73,8 @@ func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, session := &EndSessionRequest{ RedirectURI: ender.DefaultLogoutRedirectURI(), + LogoutHint: req.LogoutHint, + UILocales: req.UILocales, } if req.IdTokenHint != "" { claims, err := VerifyIDTokenHint[*oidc.IDTokenClaims](ctx, req.IdTokenHint, ender.IDTokenHintVerifier(ctx)) diff --git a/pkg/op/storage.go b/pkg/op/storage.go index a579810..35d7040 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -6,6 +6,7 @@ import ( "time" jose "github.com/go-jose/go-jose/v4" + "golang.org/x/text/language" "github.com/zitadel/oidc/v3/pkg/oidc" ) @@ -170,6 +171,8 @@ type EndSessionRequest struct { ClientID string IDTokenHintClaims *oidc.IDTokenClaims RedirectURI string + LogoutHint string + UILocales []language.Tag } var ErrDuplicateUserCode = errors.New("user code already exists") From e1415ef2f35cd1204fd8c75a4cd54c9e92cf732b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 09:50:55 +0200 Subject: [PATCH 177/185] chore(deps): bump golang.org/x/text from 0.25.0 to 0.26.0 (#755) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.25.0 to 0.26.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.25.0...v0.26.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-version: 0.26.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a15fd33..33db99e 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/zitadel/schema v1.3.1 go.opentelemetry.io/otel v1.29.0 golang.org/x/oauth2 v0.30.0 - golang.org/x/text v0.25.0 + golang.org/x/text v0.26.0 ) require ( diff --git a/go.sum b/go.sum index 2f9e525..4835505 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,8 @@ golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From e127c66db27199e97afbd32ad60f92943c9e0959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabienne=20B=C3=BChler?= Date: Tue, 17 Jun 2025 11:14:09 +0200 Subject: [PATCH 178/185] chore: update issue templates --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 92465f9..d024341 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -2,6 +2,7 @@ name: Bug Report description: "Create a bug report to help us improve ZITADEL. Click [here](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#product-management) to see how we process your issue." title: "[Bug]: " labels: ["bug"] +type: Bug body: - type: markdown attributes: From 187878de630e1fc464b8fd9f611806c94d0f30ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabienne=20B=C3=BChler?= Date: Tue, 17 Jun 2025 11:15:26 +0200 Subject: [PATCH 179/185] update docs issue template, add type --- .github/ISSUE_TEMPLATE/docs.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/docs.yaml b/.github/ISSUE_TEMPLATE/docs.yaml index 04c1c0c..d3f82b9 100644 --- a/.github/ISSUE_TEMPLATE/docs.yaml +++ b/.github/ISSUE_TEMPLATE/docs.yaml @@ -1,6 +1,7 @@ name: 📄 Documentation description: Create an issue for missing or wrong documentation. labels: ["docs"] +type: task body: - type: markdown attributes: From 5618487a883698d04b3d9177871c53d549b0f688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabienne=20B=C3=BChler?= Date: Tue, 17 Jun 2025 11:16:34 +0200 Subject: [PATCH 180/185] Update and rename improvement.yaml to enhancement.yaml --- .../ISSUE_TEMPLATE/{improvement.yaml => enhancement.yaml} | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename .github/ISSUE_TEMPLATE/{improvement.yaml => enhancement.yaml} (92%) diff --git a/.github/ISSUE_TEMPLATE/improvement.yaml b/.github/ISSUE_TEMPLATE/enhancement.yaml similarity index 92% rename from .github/ISSUE_TEMPLATE/improvement.yaml rename to .github/ISSUE_TEMPLATE/enhancement.yaml index 2e2ddf4..ef2103e 100644 --- a/.github/ISSUE_TEMPLATE/improvement.yaml +++ b/.github/ISSUE_TEMPLATE/enhancement.yaml @@ -1,11 +1,12 @@ name: 🛠️ Improvement description: "Create an new issue for an improvment in ZITADEL" -labels: ["improvement"] +labels: ["enhancement"] +type: enhancement body: - type: markdown attributes: value: | - Thanks for taking the time to fill out this improvement request + Thanks for taking the time to fill out this proposal / feature reqeust - type: checkboxes id: preflight attributes: From 8e1e5174fd3c6b7c350ba0e0fddf21146fdbc691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabienne=20B=C3=BChler?= Date: Tue, 17 Jun 2025 11:17:14 +0200 Subject: [PATCH 181/185] Delete .github/ISSUE_TEMPLATE/proposal.yaml --- .github/ISSUE_TEMPLATE/proposal.yaml | 44 ---------------------------- 1 file changed, 44 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/proposal.yaml diff --git a/.github/ISSUE_TEMPLATE/proposal.yaml b/.github/ISSUE_TEMPLATE/proposal.yaml deleted file mode 100644 index af7acd5..0000000 --- a/.github/ISSUE_TEMPLATE/proposal.yaml +++ /dev/null @@ -1,44 +0,0 @@ -name: 💡 Proposal / Feature request -description: "Create an issue for a feature request/proposal." -labels: ["enhancement"] -body: - - type: markdown - attributes: - value: | - Thanks for taking the time to fill out this proposal / feature reqeust - - type: checkboxes - id: preflight - attributes: - label: Preflight Checklist - options: - - label: - I could not find a solution in the existing issues, docs, nor discussions - required: true - - label: - I have joined the [ZITADEL chat](https://zitadel.com/chat) - - type: textarea - id: problem - attributes: - label: Describe your problem - description: Please describe your problem this proposal / feature is supposed to solve. - placeholder: Describe the problem you have. - validations: - required: true - - type: textarea - id: solution - attributes: - label: Describe your ideal solution - description: Which solution do you propose? - placeholder: As a [type of user], I want [some goal] so that [some reason]. - validations: - required: true - - type: input - id: version - attributes: - label: Version - description: Which version of the OIDC Library are you using. - - type: textarea - id: additional - attributes: - label: Additional Context - description: Please add any other infos that could be useful. From 154fbe642027fb8845bb9d8f35fd0403f8dd0711 Mon Sep 17 00:00:00 2001 From: "ORZ (Paul Orzel)" Date: Fri, 20 Jun 2025 08:44:27 +0200 Subject: [PATCH 182/185] Revert "feat(op): always verify code challenge when available (#721)" Breaks OIDC for some not yet updated applications, that we use. This reverts commit c51628ea27035796152a32631439625b55f0a7ea. --- example/client/app/app.go | 12 ---------- example/server/exampleop/templates/login.html | 4 ++-- example/server/storage/oidc.go | 15 ++++-------- pkg/op/op_test.go | 1 - pkg/op/server_http_routes_test.go | 2 +- pkg/op/token_code.go | 23 ++++++------------- 6 files changed, 15 insertions(+), 42 deletions(-) diff --git a/example/client/app/app.go b/example/client/app/app.go index 5740591..0b9b19d 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -7,7 +7,6 @@ import ( "log/slog" "net/http" "os" - "strconv" "strings" "sync/atomic" "time" @@ -35,14 +34,6 @@ func main() { scopes := strings.Split(os.Getenv("SCOPES"), " ") responseMode := os.Getenv("RESPONSE_MODE") - var pkce bool - if pkceEnv, ok := os.LookupEnv("PKCE"); ok { - var err error - pkce, err = strconv.ParseBool(pkceEnv) - if err != nil { - logrus.Fatalf("error parsing PKCE %s", err.Error()) - } - } redirectURI := fmt.Sprintf("http://localhost:%v%v", port, callbackPath) cookieHandler := httphelper.NewCookieHandler(key, key, httphelper.WithUnsecure()) @@ -73,9 +64,6 @@ func main() { if keyPath != "" { options = append(options, rp.WithJWTProfile(rp.SignerFromKeyPath(keyPath))) } - if pkce { - options = append(options, rp.WithPKCE(cookieHandler)) - } // One can add a logger to the context, // pre-defining log attributes as required. diff --git a/example/server/exampleop/templates/login.html b/example/server/exampleop/templates/login.html index d7f8f9a..b048211 100644 --- a/example/server/exampleop/templates/login.html +++ b/example/server/exampleop/templates/login.html @@ -25,5 +25,5 @@ - -{{- end }} +` +{{- end }} \ No newline at end of file diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index 3d5d86b..c04877f 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -18,7 +18,7 @@ const ( // CustomClaim is an example for how to return custom claims with this library CustomClaim = "custom_claim" - // CustomScopeImpersonatePrefix is an example scope prefix for passing user id to impersonate using token exchange + // CustomScopeImpersonatePrefix is an example scope prefix for passing user id to impersonate using token exchage CustomScopeImpersonatePrefix = "custom_scope:impersonate:" ) @@ -143,14 +143,6 @@ func MaxAgeToInternal(maxAge *uint) *time.Duration { } func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthRequest { - var codeChallenge *OIDCCodeChallenge - if authReq.CodeChallenge != "" { - codeChallenge = &OIDCCodeChallenge{ - Challenge: authReq.CodeChallenge, - Method: string(authReq.CodeChallengeMethod), - } - } - return &AuthRequest{ CreationDate: time.Now(), ApplicationID: authReq.ClientID, @@ -165,7 +157,10 @@ func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthReques ResponseType: authReq.ResponseType, ResponseMode: authReq.ResponseMode, Nonce: authReq.Nonce, - CodeChallenge: codeChallenge, + CodeChallenge: &OIDCCodeChallenge{ + Challenge: authReq.CodeChallenge, + Method: string(authReq.CodeChallengeMethod), + }, } } diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index c1520e2..9a4a624 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -102,7 +102,6 @@ func TestRoutes(t *testing.T) { authReq, err := storage.CreateAuthRequest(ctx, oidcAuthReq, "id1") require.NoError(t, err) storage.AuthRequestDone(authReq.GetID()) - storage.SaveAuthCode(ctx, authReq.GetID(), "123") accessToken, refreshToken, _, err := op.CreateAccessToken(ctx, authReq, op.AccessTokenTypeBearer, testProvider, client, "") require.NoError(t, err) diff --git a/pkg/op/server_http_routes_test.go b/pkg/op/server_http_routes_test.go index e0e4a97..1bfb32b 100644 --- a/pkg/op/server_http_routes_test.go +++ b/pkg/op/server_http_routes_test.go @@ -130,7 +130,7 @@ func TestServerRoutes(t *testing.T) { "client_id": client.GetID(), "client_secret": "secret", "redirect_uri": "https://example.com", - "code": "abc", + "code": "123", }, wantCode: http.StatusBadRequest, json: `{"error":"invalid_grant", "error_description":"invalid code"}`, diff --git a/pkg/op/token_code.go b/pkg/op/token_code.go index fb636b4..3612240 100644 --- a/pkg/op/token_code.go +++ b/pkg/op/token_code.go @@ -74,17 +74,6 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, ctx, span := tracer.Start(ctx, "AuthorizeCodeClient") defer span.End() - request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) - if err != nil { - return nil, nil, err - } - - codeChallenge := request.GetCodeChallenge() - err = AuthorizeCodeChallenge(tokenReq.CodeVerifier, codeChallenge) - if err != nil { - return nil, nil, err - } - if tokenReq.ClientAssertionType == oidc.ClientAssertionTypeJWTAssertion { jwtExchanger, ok := exchanger.(JWTAuthorizationGrantExchanger) if !ok || !exchanger.AuthMethodPrivateKeyJWTSupported() { @@ -94,9 +83,9 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, if err != nil { return nil, nil, err } + request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) return request, client, err } - client, err = exchanger.Storage().GetClientByClientID(ctx, tokenReq.ClientID) if err != nil { return nil, nil, oidc.ErrInvalidClient().WithParent(err) @@ -105,10 +94,12 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, return nil, nil, oidc.ErrInvalidClient().WithDescription("private_key_jwt not allowed for this client") } if client.AuthMethod() == oidc.AuthMethodNone { - if codeChallenge == nil { - return nil, nil, oidc.ErrInvalidRequest().WithDescription("PKCE required") + request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) + if err != nil { + return nil, nil, err } - return request, client, nil + err = AuthorizeCodeChallenge(tokenReq.CodeVerifier, request.GetCodeChallenge()) + return request, client, err } if client.AuthMethod() == oidc.AuthMethodPost && !exchanger.AuthMethodPostSupported() { return nil, nil, oidc.ErrInvalidClient().WithDescription("auth_method post not supported") @@ -117,7 +108,7 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, if err != nil { return nil, nil, err } - + request, err = AuthRequestByCode(ctx, exchanger.Storage(), tokenReq.Code) return request, client, err } From 53c4d07b450b2e4fe587d3a8a4ff8d03c4bc19ca Mon Sep 17 00:00:00 2001 From: "ORZ (Paul Orzel)" Date: Fri, 20 Jun 2025 08:56:29 +0200 Subject: [PATCH 183/185] remove actions --- {.github => .forgejo.bak}/ISSUE_TEMPLATE/bug_report.yaml | 0 {.github => .forgejo.bak}/ISSUE_TEMPLATE/config.yml | 0 {.github => .forgejo.bak}/ISSUE_TEMPLATE/docs.yaml | 0 {.github => .forgejo.bak}/ISSUE_TEMPLATE/enhancement.yaml | 0 {.github => .forgejo.bak}/dependabot.yml | 0 {.github => .forgejo.bak}/pull_request_template.md | 0 {.github => .forgejo.bak}/workflows/codeql-analysis.yml | 0 {.github => .forgejo.bak}/workflows/issue.yml | 0 {.github => .forgejo.bak}/workflows/release.yml | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename {.github => .forgejo.bak}/ISSUE_TEMPLATE/bug_report.yaml (100%) rename {.github => .forgejo.bak}/ISSUE_TEMPLATE/config.yml (100%) rename {.github => .forgejo.bak}/ISSUE_TEMPLATE/docs.yaml (100%) rename {.github => .forgejo.bak}/ISSUE_TEMPLATE/enhancement.yaml (100%) rename {.github => .forgejo.bak}/dependabot.yml (100%) rename {.github => .forgejo.bak}/pull_request_template.md (100%) rename {.github => .forgejo.bak}/workflows/codeql-analysis.yml (100%) rename {.github => .forgejo.bak}/workflows/issue.yml (100%) rename {.github => .forgejo.bak}/workflows/release.yml (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.forgejo.bak/ISSUE_TEMPLATE/bug_report.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.yaml rename to .forgejo.bak/ISSUE_TEMPLATE/bug_report.yaml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.forgejo.bak/ISSUE_TEMPLATE/config.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/config.yml rename to .forgejo.bak/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/docs.yaml b/.forgejo.bak/ISSUE_TEMPLATE/docs.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/docs.yaml rename to .forgejo.bak/ISSUE_TEMPLATE/docs.yaml diff --git a/.github/ISSUE_TEMPLATE/enhancement.yaml b/.forgejo.bak/ISSUE_TEMPLATE/enhancement.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/enhancement.yaml rename to .forgejo.bak/ISSUE_TEMPLATE/enhancement.yaml diff --git a/.github/dependabot.yml b/.forgejo.bak/dependabot.yml similarity index 100% rename from .github/dependabot.yml rename to .forgejo.bak/dependabot.yml diff --git a/.github/pull_request_template.md b/.forgejo.bak/pull_request_template.md similarity index 100% rename from .github/pull_request_template.md rename to .forgejo.bak/pull_request_template.md diff --git a/.github/workflows/codeql-analysis.yml b/.forgejo.bak/workflows/codeql-analysis.yml similarity index 100% rename from .github/workflows/codeql-analysis.yml rename to .forgejo.bak/workflows/codeql-analysis.yml diff --git a/.github/workflows/issue.yml b/.forgejo.bak/workflows/issue.yml similarity index 100% rename from .github/workflows/issue.yml rename to .forgejo.bak/workflows/issue.yml diff --git a/.github/workflows/release.yml b/.forgejo.bak/workflows/release.yml similarity index 100% rename from .github/workflows/release.yml rename to .forgejo.bak/workflows/release.yml From 29d69ca2e0eabe4c9e19c37bc48a0f3788ee661f Mon Sep 17 00:00:00 2001 From: "ORZ (Paul Orzel)" Date: Fri, 20 Jun 2025 09:39:40 +0200 Subject: [PATCH 184/185] add function to marshal aud into a string if the array has a len of 1, to comply with rfc --- pkg/oidc/types.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 33ad2d5..5d063b1 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -35,6 +35,17 @@ func (a *Audience) UnmarshalJSON(text []byte) error { return nil } +func (a *Audience) MarshalJSON() ([]byte, error) { + len := len(*a) + if len > 1 { + return json.Marshal(*a) + } else if len == 1 { + return json.Marshal((*a)[0]) + } + + return nil, errors.New("aud is empty") +} + type Display string func (d *Display) UnmarshalText(text []byte) error { From 653b807f5db15b4872bb8db1aca80ca004a6127d Mon Sep 17 00:00:00 2001 From: "ORZ (Paul Orzel)" Date: Fri, 20 Jun 2025 09:45:28 +0200 Subject: [PATCH 185/185] replace github url --- example/client/api/api.go | 4 ++-- example/client/app/app.go | 6 ++--- example/client/device/device.go | 4 ++-- example/client/github/github.go | 8 +++---- example/client/service/service.go | 2 +- example/server/dynamic/login.go | 2 +- example/server/dynamic/op.go | 4 ++-- example/server/exampleop/device.go | 2 +- example/server/exampleop/login.go | 2 +- example/server/exampleop/op.go | 2 +- example/server/main.go | 6 ++--- example/server/storage/client.go | 4 ++-- example/server/storage/oidc.go | 4 ++-- example/server/storage/storage.go | 4 ++-- example/server/storage/storage_dynamic.go | 4 ++-- go.mod | 2 +- internal/testutil/gen/gen.go | 4 ++-- internal/testutil/token.go | 2 +- pkg/client/client.go | 6 ++--- pkg/client/client_test.go | 2 +- pkg/client/integration_test.go | 16 ++++++------- pkg/client/jwt_profile.go | 4 ++-- pkg/client/profile/jwt_profile.go | 4 ++-- pkg/client/rp/cli/cli.go | 6 ++--- pkg/client/rp/delegation.go | 2 +- pkg/client/rp/device.go | 4 ++-- pkg/client/rp/jwks.go | 6 ++--- pkg/client/rp/relying_party.go | 6 ++--- pkg/client/rp/relying_party_test.go | 4 ++-- pkg/client/rp/tockenexchange.go | 2 +- pkg/client/rp/userinfo_example_test.go | 4 ++-- pkg/client/rp/verifier.go | 4 ++-- pkg/client/rp/verifier_test.go | 4 ++-- pkg/client/rp/verifier_tokens_example_test.go | 6 ++--- pkg/client/rs/introspect_example_test.go | 4 ++-- pkg/client/rs/resource_server.go | 6 ++--- pkg/client/rs/resource_server_test.go | 2 +- pkg/client/tokenexchange/tokenexchange.go | 6 ++--- pkg/crypto/key_test.go | 2 +- pkg/http/http.go | 2 +- pkg/oidc/code_challenge.go | 2 +- pkg/oidc/token.go | 2 +- pkg/oidc/verifier_parse_test.go | 4 ++-- pkg/op/auth_request.go | 4 ++-- pkg/op/auth_request_test.go | 12 +++++----- pkg/op/client.go | 4 ++-- pkg/op/client_test.go | 8 +++---- pkg/op/crypto.go | 2 +- pkg/op/device.go | 4 ++-- pkg/op/device_test.go | 6 ++--- pkg/op/discovery.go | 4 ++-- pkg/op/discovery_test.go | 6 ++--- pkg/op/endpoint_test.go | 2 +- pkg/op/error.go | 4 ++-- pkg/op/error_test.go | 2 +- pkg/op/keys.go | 2 +- pkg/op/keys_test.go | 6 ++--- pkg/op/mock/authorizer.mock.go | 6 ++--- pkg/op/mock/authorizer.mock.impl.go | 4 ++-- pkg/op/mock/client.go | 4 ++-- pkg/op/mock/client.mock.go | 6 ++--- pkg/op/mock/configuration.mock.go | 4 ++-- pkg/op/mock/discovery.mock.go | 2 +- pkg/op/mock/generate.go | 16 ++++++------- pkg/op/mock/glob.go | 4 ++-- pkg/op/mock/glob.mock.go | 6 ++--- pkg/op/mock/key.mock.go | 4 ++-- pkg/op/mock/signer.mock.go | 2 +- pkg/op/mock/storage.mock.go | 6 ++--- pkg/op/mock/storage.mock.impl.go | 4 ++-- pkg/op/op.go | 4 ++-- pkg/op/op_test.go | 6 ++--- pkg/op/probes.go | 2 +- pkg/op/server.go | 4 ++-- pkg/op/server_http.go | 4 ++-- pkg/op/server_http_routes_test.go | 6 ++--- pkg/op/server_http_test.go | 4 ++-- pkg/op/server_legacy.go | 2 +- pkg/op/session.go | 4 ++-- pkg/op/storage.go | 2 +- pkg/op/token.go | 4 ++-- pkg/op/token_client_credentials.go | 4 ++-- pkg/op/token_code.go | 4 ++-- pkg/op/token_exchange.go | 4 ++-- pkg/op/token_intospection.go | 4 ++-- pkg/op/token_jwt_profile.go | 4 ++-- pkg/op/token_refresh.go | 4 ++-- pkg/op/token_request.go | 4 ++-- pkg/op/token_request_test.go | 24 +++++++++---------- pkg/op/token_revocation.go | 4 ++-- pkg/op/userinfo.go | 4 ++-- pkg/op/verifier_access_token.go | 2 +- pkg/op/verifier_access_token_example_test.go | 6 ++--- pkg/op/verifier_access_token_test.go | 4 ++-- pkg/op/verifier_id_token_hint.go | 2 +- pkg/op/verifier_id_token_hint_test.go | 4 ++-- pkg/op/verifier_jwt_profile.go | 2 +- pkg/op/verifier_jwt_profile_test.go | 6 ++--- 98 files changed, 219 insertions(+), 219 deletions(-) diff --git a/example/client/api/api.go b/example/client/api/api.go index 2e61c21..69f9466 100644 --- a/example/client/api/api.go +++ b/example/client/api/api.go @@ -13,8 +13,8 @@ import ( "github.com/go-chi/chi/v5" "github.com/sirupsen/logrus" - "github.com/zitadel/oidc/v3/pkg/client/rs" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rs" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) const ( diff --git a/example/client/app/app.go b/example/client/app/app.go index 0b9b19d..90b1969 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -14,10 +14,10 @@ import ( "github.com/google/uuid" "github.com/sirupsen/logrus" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v3/pkg/client/rp" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" ) var ( diff --git a/example/client/device/device.go b/example/client/device/device.go index 78ed2c8..33bc570 100644 --- a/example/client/device/device.go +++ b/example/client/device/device.go @@ -45,8 +45,8 @@ import ( "github.com/sirupsen/logrus" - "github.com/zitadel/oidc/v3/pkg/client/rp" - httphelper "github.com/zitadel/oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" ) var ( diff --git a/example/client/github/github.go b/example/client/github/github.go index 7d069d4..f6c536b 100644 --- a/example/client/github/github.go +++ b/example/client/github/github.go @@ -10,10 +10,10 @@ import ( "golang.org/x/oauth2" githubOAuth "golang.org/x/oauth2/github" - "github.com/zitadel/oidc/v3/pkg/client/rp" - "github.com/zitadel/oidc/v3/pkg/client/rp/cli" - "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp/cli" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) var ( diff --git a/example/client/service/service.go b/example/client/service/service.go index 865a4e0..a88ab2f 100644 --- a/example/client/service/service.go +++ b/example/client/service/service.go @@ -13,7 +13,7 @@ import ( "github.com/sirupsen/logrus" "golang.org/x/oauth2" - "github.com/zitadel/oidc/v3/pkg/client/profile" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/profile" ) var client = http.DefaultClient diff --git a/example/server/dynamic/login.go b/example/server/dynamic/login.go index 685b444..05f0e34 100644 --- a/example/server/dynamic/login.go +++ b/example/server/dynamic/login.go @@ -8,7 +8,7 @@ import ( "github.com/go-chi/chi/v5" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) const ( diff --git a/example/server/dynamic/op.go b/example/server/dynamic/op.go index 432a575..2c00e41 100644 --- a/example/server/dynamic/op.go +++ b/example/server/dynamic/op.go @@ -10,8 +10,8 @@ import ( "github.com/go-chi/chi/v5" "golang.org/x/text/language" - "github.com/zitadel/oidc/v3/example/server/storage" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) const ( diff --git a/example/server/exampleop/device.go b/example/server/exampleop/device.go index 2f9be52..99505e4 100644 --- a/example/server/exampleop/device.go +++ b/example/server/exampleop/device.go @@ -8,10 +8,10 @@ import ( "net/http" "net/url" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/go-chi/chi/v5" "github.com/gorilla/securecookie" "github.com/sirupsen/logrus" - "github.com/zitadel/oidc/v3/pkg/op" ) type deviceAuthenticate interface { diff --git a/example/server/exampleop/login.go b/example/server/exampleop/login.go index 4d2b478..77a6189 100644 --- a/example/server/exampleop/login.go +++ b/example/server/exampleop/login.go @@ -5,8 +5,8 @@ import ( "fmt" "net/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/go-chi/chi/v5" - "github.com/zitadel/oidc/v3/pkg/op" ) type login struct { diff --git a/example/server/exampleop/op.go b/example/server/exampleop/op.go index 8f55b0a..e12c755 100644 --- a/example/server/exampleop/op.go +++ b/example/server/exampleop/op.go @@ -12,7 +12,7 @@ import ( "github.com/zitadel/logging" "golang.org/x/text/language" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) const ( diff --git a/example/server/main.go b/example/server/main.go index 6d345e1..5bdbb05 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -6,9 +6,9 @@ import ( "net/http" "os" - "github.com/zitadel/oidc/v3/example/server/config" - "github.com/zitadel/oidc/v3/example/server/exampleop" - "github.com/zitadel/oidc/v3/example/server/storage" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/config" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/exampleop" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" ) func getUserStore(cfg *config.Config) (storage.UserStore, error) { diff --git a/example/server/storage/client.go b/example/server/storage/client.go index 010b9ce..2b836c0 100644 --- a/example/server/storage/client.go +++ b/example/server/storage/client.go @@ -3,8 +3,8 @@ package storage import ( "time" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) var ( diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index c04877f..9c7f544 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -6,8 +6,8 @@ import ( "golang.org/x/text/language" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) const ( diff --git a/example/server/storage/storage.go b/example/server/storage/storage.go index fee34c5..d4315c6 100644 --- a/example/server/storage/storage.go +++ b/example/server/storage/storage.go @@ -14,8 +14,8 @@ import ( jose "github.com/go-jose/go-jose/v4" "github.com/google/uuid" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) // serviceKey1 is a public key which will be used for the JWT Profile Authorization Grant diff --git a/example/server/storage/storage_dynamic.go b/example/server/storage/storage_dynamic.go index d112d71..765d29a 100644 --- a/example/server/storage/storage_dynamic.go +++ b/example/server/storage/storage_dynamic.go @@ -6,8 +6,8 @@ import ( jose "github.com/go-jose/go-jose/v4" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) type multiStorage struct { diff --git a/go.mod b/go.mod index 33db99e..a0f42c4 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/zitadel/oidc/v3 +module git.christmann.info/LARA/zitadel-oidc/v3 go 1.23.7 diff --git a/internal/testutil/gen/gen.go b/internal/testutil/gen/gen.go index e4a5718..3e44b7d 100644 --- a/internal/testutil/gen/gen.go +++ b/internal/testutil/gen/gen.go @@ -8,8 +8,8 @@ import ( "fmt" "os" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) var custom = map[string]any{ diff --git a/internal/testutil/token.go b/internal/testutil/token.go index 7ad8893..72d08c5 100644 --- a/internal/testutil/token.go +++ b/internal/testutil/token.go @@ -8,9 +8,9 @@ import ( "errors" "time" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" jose "github.com/go-jose/go-jose/v4" "github.com/muhlemmer/gu" - "github.com/zitadel/oidc/v3/pkg/oidc" ) // KeySet implements oidc.Keys diff --git a/pkg/client/client.go b/pkg/client/client.go index 56417b5..2e1f536 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -15,9 +15,9 @@ import ( "go.opentelemetry.io/otel" "golang.org/x/oauth2" - "github.com/zitadel/oidc/v3/pkg/crypto" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) var ( diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 1046941..9e21e8e 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -5,9 +5,9 @@ import ( "net/http" "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestDiscover(t *testing.T) { diff --git a/pkg/client/integration_test.go b/pkg/client/integration_test.go index 98a9d3a..86a9ab7 100644 --- a/pkg/client/integration_test.go +++ b/pkg/client/integration_test.go @@ -23,14 +23,14 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/oauth2" - "github.com/zitadel/oidc/v3/example/server/exampleop" - "github.com/zitadel/oidc/v3/example/server/storage" - "github.com/zitadel/oidc/v3/pkg/client/rp" - "github.com/zitadel/oidc/v3/pkg/client/rs" - "github.com/zitadel/oidc/v3/pkg/client/tokenexchange" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/exampleop" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rs" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/tokenexchange" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) var Logger = slog.New( diff --git a/pkg/client/jwt_profile.go b/pkg/client/jwt_profile.go index 0a5d9ec..98a54fd 100644 --- a/pkg/client/jwt_profile.go +++ b/pkg/client/jwt_profile.go @@ -6,8 +6,8 @@ import ( "golang.org/x/oauth2" - "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) // JWTProfileExchange handles the oauth2 jwt profile exchange diff --git a/pkg/client/profile/jwt_profile.go b/pkg/client/profile/jwt_profile.go index 060f390..fb351f0 100644 --- a/pkg/client/profile/jwt_profile.go +++ b/pkg/client/profile/jwt_profile.go @@ -8,8 +8,8 @@ import ( jose "github.com/go-jose/go-jose/v4" "golang.org/x/oauth2" - "github.com/zitadel/oidc/v3/pkg/client" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type TokenSource interface { diff --git a/pkg/client/rp/cli/cli.go b/pkg/client/rp/cli/cli.go index eeb9011..10edaa7 100644 --- a/pkg/client/rp/cli/cli.go +++ b/pkg/client/rp/cli/cli.go @@ -4,9 +4,9 @@ import ( "context" "net/http" - "github.com/zitadel/oidc/v3/pkg/client/rp" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) const ( diff --git a/pkg/client/rp/delegation.go b/pkg/client/rp/delegation.go index 23ecffd..fb4fc63 100644 --- a/pkg/client/rp/delegation.go +++ b/pkg/client/rp/delegation.go @@ -1,7 +1,7 @@ package rp import ( - "github.com/zitadel/oidc/v3/pkg/oidc/grants/tokenexchange" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc/grants/tokenexchange" ) // DelegationTokenRequest is an implementation of TokenExchangeRequest diff --git a/pkg/client/rp/device.go b/pkg/client/rp/device.go index c2d1f8a..1fadd56 100644 --- a/pkg/client/rp/device.go +++ b/pkg/client/rp/device.go @@ -5,8 +5,8 @@ import ( "fmt" "time" - "github.com/zitadel/oidc/v3/pkg/client" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) func newDeviceClientCredentialsRequest(scopes []string, rp RelyingParty) (*oidc.ClientCredentialsRequest, error) { diff --git a/pkg/client/rp/jwks.go b/pkg/client/rp/jwks.go index c44a267..0ccbad2 100644 --- a/pkg/client/rp/jwks.go +++ b/pkg/client/rp/jwks.go @@ -9,9 +9,9 @@ import ( jose "github.com/go-jose/go-jose/v4" - "github.com/zitadel/oidc/v3/pkg/client" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) func NewRemoteKeySet(client *http.Client, jwksURL string, opts ...func(*remoteKeySet)) oidc.KeySet { diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index e6fa078..c2759a2 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -14,10 +14,10 @@ import ( "golang.org/x/oauth2" "golang.org/x/oauth2/clientcredentials" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v3/pkg/client" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" ) const ( diff --git a/pkg/client/rp/relying_party_test.go b/pkg/client/rp/relying_party_test.go index 4c5a1b3..b3bb6ee 100644 --- a/pkg/client/rp/relying_party_test.go +++ b/pkg/client/rp/relying_party_test.go @@ -5,10 +5,10 @@ import ( "testing" "time" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" ) diff --git a/pkg/client/rp/tockenexchange.go b/pkg/client/rp/tockenexchange.go index c8ca048..aa2cf99 100644 --- a/pkg/client/rp/tockenexchange.go +++ b/pkg/client/rp/tockenexchange.go @@ -5,7 +5,7 @@ import ( "golang.org/x/oauth2" - "github.com/zitadel/oidc/v3/pkg/oidc/grants/tokenexchange" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc/grants/tokenexchange" ) // TokenExchangeRP extends the `RelyingParty` interface for the *draft* oauth2 `Token Exchange` diff --git a/pkg/client/rp/userinfo_example_test.go b/pkg/client/rp/userinfo_example_test.go index 2cc5222..78e014e 100644 --- a/pkg/client/rp/userinfo_example_test.go +++ b/pkg/client/rp/userinfo_example_test.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - "github.com/zitadel/oidc/v3/pkg/client/rp" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type UserInfo struct { diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index ca59454..0088b81 100644 --- a/pkg/client/rp/verifier.go +++ b/pkg/client/rp/verifier.go @@ -6,8 +6,8 @@ import ( jose "github.com/go-jose/go-jose/v4" - "github.com/zitadel/oidc/v3/pkg/client" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) // VerifyTokens implement the Token Response Validation as defined in OIDC specification diff --git a/pkg/client/rp/verifier_test.go b/pkg/client/rp/verifier_test.go index 24d35af..38f5a4a 100644 --- a/pkg/client/rp/verifier_test.go +++ b/pkg/client/rp/verifier_test.go @@ -5,11 +5,11 @@ import ( "testing" "time" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" jose "github.com/go-jose/go-jose/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestVerifyTokens(t *testing.T) { diff --git a/pkg/client/rp/verifier_tokens_example_test.go b/pkg/client/rp/verifier_tokens_example_test.go index 892eb23..7ae68d6 100644 --- a/pkg/client/rp/verifier_tokens_example_test.go +++ b/pkg/client/rp/verifier_tokens_example_test.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/client/rp" - "github.com/zitadel/oidc/v3/pkg/oidc" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) // MyCustomClaims extends the TokenClaims base, diff --git a/pkg/client/rs/introspect_example_test.go b/pkg/client/rs/introspect_example_test.go index eac8be2..1f67d11 100644 --- a/pkg/client/rs/introspect_example_test.go +++ b/pkg/client/rs/introspect_example_test.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - "github.com/zitadel/oidc/v3/pkg/client/rs" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rs" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type IntrospectionResponse struct { diff --git a/pkg/client/rs/resource_server.go b/pkg/client/rs/resource_server.go index 962af7e..993796e 100644 --- a/pkg/client/rs/resource_server.go +++ b/pkg/client/rs/resource_server.go @@ -6,9 +6,9 @@ import ( "net/http" "time" - "github.com/zitadel/oidc/v3/pkg/client" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type ResourceServer interface { diff --git a/pkg/client/rs/resource_server_test.go b/pkg/client/rs/resource_server_test.go index 7a5ced9..afd7441 100644 --- a/pkg/client/rs/resource_server_test.go +++ b/pkg/client/rs/resource_server_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestNewResourceServer(t *testing.T) { diff --git a/pkg/client/tokenexchange/tokenexchange.go b/pkg/client/tokenexchange/tokenexchange.go index 61975a4..9cc1328 100644 --- a/pkg/client/tokenexchange/tokenexchange.go +++ b/pkg/client/tokenexchange/tokenexchange.go @@ -6,10 +6,10 @@ import ( "net/http" "time" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/go-jose/go-jose/v4" - "github.com/zitadel/oidc/v3/pkg/client" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" ) type TokenExchanger interface { diff --git a/pkg/crypto/key_test.go b/pkg/crypto/key_test.go index 8ed5cb5..a6fa493 100644 --- a/pkg/crypto/key_test.go +++ b/pkg/crypto/key_test.go @@ -10,7 +10,7 @@ import ( "github.com/go-jose/go-jose/v4" "github.com/stretchr/testify/assert" - zcrypto "github.com/zitadel/oidc/v3/pkg/crypto" + zcrypto "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" ) func TestBytesToPrivateKey(t *testing.T) { diff --git a/pkg/http/http.go b/pkg/http/http.go index 33c5f15..aa0ff6f 100644 --- a/pkg/http/http.go +++ b/pkg/http/http.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) var DefaultHTTPClient = &http.Client{ diff --git a/pkg/oidc/code_challenge.go b/pkg/oidc/code_challenge.go index 3296362..0c593df 100644 --- a/pkg/oidc/code_challenge.go +++ b/pkg/oidc/code_challenge.go @@ -3,7 +3,7 @@ package oidc import ( "crypto/sha256" - "github.com/zitadel/oidc/v3/pkg/crypto" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" ) const ( diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index d2b6f6d..4b43dcb 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -10,7 +10,7 @@ import ( "github.com/muhlemmer/gu" - "github.com/zitadel/oidc/v3/pkg/crypto" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" ) const ( diff --git a/pkg/oidc/verifier_parse_test.go b/pkg/oidc/verifier_parse_test.go index 105650f..9cf5c1e 100644 --- a/pkg/oidc/verifier_parse_test.go +++ b/pkg/oidc/verifier_parse_test.go @@ -5,10 +5,10 @@ import ( "encoding/json" "testing" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestParseToken(t *testing.T) { diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 2c013aa..b1434cc 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -15,9 +15,9 @@ import ( "strings" "time" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/bmatcuk/doublestar/v4" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" ) type AuthRequest interface { diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index f0c4ef1..d1ea965 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -11,15 +11,15 @@ import ( "reflect" "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op/mock" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/example/server/storage" - tu "github.com/zitadel/oidc/v3/internal/testutil" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" - "github.com/zitadel/oidc/v3/pkg/op/mock" "github.com/zitadel/schema" ) diff --git a/pkg/op/client.go b/pkg/op/client.go index 913944c..a4f44d3 100644 --- a/pkg/op/client.go +++ b/pkg/op/client.go @@ -7,8 +7,8 @@ import ( "net/url" "time" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) //go:generate go get github.com/dmarkham/enumer diff --git a/pkg/op/client_test.go b/pkg/op/client_test.go index b772ba5..b416630 100644 --- a/pkg/op/client_test.go +++ b/pkg/op/client_test.go @@ -10,13 +10,13 @@ import ( "strings" "testing" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op/mock" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" - "github.com/zitadel/oidc/v3/pkg/op/mock" "github.com/zitadel/schema" ) diff --git a/pkg/op/crypto.go b/pkg/op/crypto.go index 6ab1e0a..01aaad3 100644 --- a/pkg/op/crypto.go +++ b/pkg/op/crypto.go @@ -1,7 +1,7 @@ package op import ( - "github.com/zitadel/oidc/v3/pkg/crypto" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" ) type Crypto interface { diff --git a/pkg/op/device.go b/pkg/op/device.go index b7290cd..866cbc4 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -13,8 +13,8 @@ import ( "strings" "time" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type DeviceAuthorizationConfig struct { diff --git a/pkg/op/device_test.go b/pkg/op/device_test.go index 5fd9c9b..a7b5c4e 100644 --- a/pkg/op/device_test.go +++ b/pkg/op/device_test.go @@ -13,12 +13,12 @@ import ( "testing" "time" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/example/server/storage" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" ) func Test_deviceAuthorizationHandler(t *testing.T) { diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index 7aa7cf7..9b3ddb6 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -6,8 +6,8 @@ import ( jose "github.com/go-jose/go-jose/v4" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type DiscoverStorage interface { diff --git a/pkg/op/discovery_test.go b/pkg/op/discovery_test.go index 61afb62..63f1b98 100644 --- a/pkg/op/discovery_test.go +++ b/pkg/op/discovery_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" - "github.com/zitadel/oidc/v3/pkg/op/mock" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op/mock" ) func TestDiscover(t *testing.T) { diff --git a/pkg/op/endpoint_test.go b/pkg/op/endpoint_test.go index bf112ef..5b98c6e 100644 --- a/pkg/op/endpoint_test.go +++ b/pkg/op/endpoint_test.go @@ -3,8 +3,8 @@ package op_test import ( "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/pkg/op" ) func TestEndpoint_Path(t *testing.T) { diff --git a/pkg/op/error.go b/pkg/op/error.go index d57da83..272f85e 100644 --- a/pkg/op/error.go +++ b/pkg/op/error.go @@ -7,8 +7,8 @@ import ( "log/slog" "net/http" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type ErrAuthRequest interface { diff --git a/pkg/op/error_test.go b/pkg/op/error_test.go index 107f9d0..9271cf1 100644 --- a/pkg/op/error_test.go +++ b/pkg/op/error_test.go @@ -11,9 +11,9 @@ import ( "strings" "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/schema" ) diff --git a/pkg/op/keys.go b/pkg/op/keys.go index c96c456..97e400b 100644 --- a/pkg/op/keys.go +++ b/pkg/op/keys.go @@ -6,7 +6,7 @@ import ( jose "github.com/go-jose/go-jose/v4" - httphelper "github.com/zitadel/oidc/v3/pkg/http" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" ) type KeyProvider interface { diff --git a/pkg/op/keys_test.go b/pkg/op/keys_test.go index 3662739..9c80878 100644 --- a/pkg/op/keys_test.go +++ b/pkg/op/keys_test.go @@ -11,9 +11,9 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" - "github.com/zitadel/oidc/v3/pkg/op/mock" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op/mock" ) func TestKeys(t *testing.T) { diff --git a/pkg/op/mock/authorizer.mock.go b/pkg/op/mock/authorizer.mock.go index c7703f1..56b28e0 100644 --- a/pkg/op/mock/authorizer.mock.go +++ b/pkg/op/mock/authorizer.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: Authorizer) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Authorizer) // Package mock is a generated GoMock package. package mock @@ -9,9 +9,9 @@ import ( slog "log/slog" reflect "reflect" + http "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" gomock "github.com/golang/mock/gomock" - http "github.com/zitadel/oidc/v3/pkg/http" - op "github.com/zitadel/oidc/v3/pkg/op" ) // MockAuthorizer is a mock of Authorizer interface. diff --git a/pkg/op/mock/authorizer.mock.impl.go b/pkg/op/mock/authorizer.mock.impl.go index 59e8fa3..73c4154 100644 --- a/pkg/op/mock/authorizer.mock.impl.go +++ b/pkg/op/mock/authorizer.mock.impl.go @@ -8,8 +8,8 @@ import ( "github.com/golang/mock/gomock" "github.com/zitadel/schema" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) func NewAuthorizer(t *testing.T) op.Authorizer { diff --git a/pkg/op/mock/client.go b/pkg/op/mock/client.go index f01e3ec..e2a5e85 100644 --- a/pkg/op/mock/client.go +++ b/pkg/op/mock/client.go @@ -5,8 +5,8 @@ import ( "github.com/golang/mock/gomock" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) func NewClient(t *testing.T) op.Client { diff --git a/pkg/op/mock/client.mock.go b/pkg/op/mock/client.mock.go index 9be0807..93eca67 100644 --- a/pkg/op/mock/client.mock.go +++ b/pkg/op/mock/client.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: Client) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Client) // Package mock is a generated GoMock package. package mock @@ -8,9 +8,9 @@ import ( reflect "reflect" time "time" + oidc "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" gomock "github.com/golang/mock/gomock" - oidc "github.com/zitadel/oidc/v3/pkg/oidc" - op "github.com/zitadel/oidc/v3/pkg/op" ) // MockClient is a mock of Client interface. diff --git a/pkg/op/mock/configuration.mock.go b/pkg/op/mock/configuration.mock.go index 0ef9d92..bf51035 100644 --- a/pkg/op/mock/configuration.mock.go +++ b/pkg/op/mock/configuration.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: Configuration) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Configuration) // Package mock is a generated GoMock package. package mock @@ -8,8 +8,8 @@ import ( http "net/http" reflect "reflect" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" gomock "github.com/golang/mock/gomock" - op "github.com/zitadel/oidc/v3/pkg/op" language "golang.org/x/text/language" ) diff --git a/pkg/op/mock/discovery.mock.go b/pkg/op/mock/discovery.mock.go index a27f8ef..c85f91b 100644 --- a/pkg/op/mock/discovery.mock.go +++ b/pkg/op/mock/discovery.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: DiscoverStorage) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: DiscoverStorage) // Package mock is a generated GoMock package. package mock diff --git a/pkg/op/mock/generate.go b/pkg/op/mock/generate.go index e5cab3e..3d58ab7 100644 --- a/pkg/op/mock/generate.go +++ b/pkg/op/mock/generate.go @@ -1,11 +1,11 @@ package mock //go:generate go install github.com/golang/mock/mockgen@v1.6.0 -//go:generate mockgen -package mock -destination ./storage.mock.go github.com/zitadel/oidc/v3/pkg/op Storage -//go:generate mockgen -package mock -destination ./authorizer.mock.go github.com/zitadel/oidc/v3/pkg/op Authorizer -//go:generate mockgen -package mock -destination ./client.mock.go github.com/zitadel/oidc/v3/pkg/op Client -//go:generate mockgen -package mock -destination ./glob.mock.go github.com/zitadel/oidc/v3/pkg/op HasRedirectGlobs -//go:generate mockgen -package mock -destination ./configuration.mock.go github.com/zitadel/oidc/v3/pkg/op Configuration -//go:generate mockgen -package mock -destination ./discovery.mock.go github.com/zitadel/oidc/v3/pkg/op DiscoverStorage -//go:generate mockgen -package mock -destination ./signer.mock.go github.com/zitadel/oidc/v3/pkg/op SigningKey,Key -//go:generate mockgen -package mock -destination ./key.mock.go github.com/zitadel/oidc/v3/pkg/op KeyProvider +//go:generate mockgen -package mock -destination ./storage.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op Storage +//go:generate mockgen -package mock -destination ./authorizer.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op Authorizer +//go:generate mockgen -package mock -destination ./client.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op Client +//go:generate mockgen -package mock -destination ./glob.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op HasRedirectGlobs +//go:generate mockgen -package mock -destination ./configuration.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op Configuration +//go:generate mockgen -package mock -destination ./discovery.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op DiscoverStorage +//go:generate mockgen -package mock -destination ./signer.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op SigningKey,Key +//go:generate mockgen -package mock -destination ./key.mock.go git.christmann.info/LARA/zitadel-oidc/v3/pkg/op KeyProvider diff --git a/pkg/op/mock/glob.go b/pkg/op/mock/glob.go index cade476..8149c8f 100644 --- a/pkg/op/mock/glob.go +++ b/pkg/op/mock/glob.go @@ -3,9 +3,9 @@ package mock import ( "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" gomock "github.com/golang/mock/gomock" - "github.com/zitadel/oidc/v3/pkg/oidc" - op "github.com/zitadel/oidc/v3/pkg/op" ) func NewHasRedirectGlobs(t *testing.T) op.HasRedirectGlobs { diff --git a/pkg/op/mock/glob.mock.go b/pkg/op/mock/glob.mock.go index cf9996e..ebdc333 100644 --- a/pkg/op/mock/glob.mock.go +++ b/pkg/op/mock/glob.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: HasRedirectGlobs) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: HasRedirectGlobs) // Package mock is a generated GoMock package. package mock @@ -8,9 +8,9 @@ import ( reflect "reflect" time "time" + oidc "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" gomock "github.com/golang/mock/gomock" - oidc "github.com/zitadel/oidc/v3/pkg/oidc" - op "github.com/zitadel/oidc/v3/pkg/op" ) // MockHasRedirectGlobs is a mock of HasRedirectGlobs interface. diff --git a/pkg/op/mock/key.mock.go b/pkg/op/mock/key.mock.go index 122e852..d9ee857 100644 --- a/pkg/op/mock/key.mock.go +++ b/pkg/op/mock/key.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: KeyProvider) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: KeyProvider) // Package mock is a generated GoMock package. package mock @@ -8,8 +8,8 @@ import ( context "context" reflect "reflect" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" gomock "github.com/golang/mock/gomock" - op "github.com/zitadel/oidc/v3/pkg/op" ) // MockKeyProvider is a mock of KeyProvider interface. diff --git a/pkg/op/mock/signer.mock.go b/pkg/op/mock/signer.mock.go index e1bab91..751ce60 100644 --- a/pkg/op/mock/signer.mock.go +++ b/pkg/op/mock/signer.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: SigningKey,Key) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: SigningKey,Key) // Package mock is a generated GoMock package. package mock diff --git a/pkg/op/mock/storage.mock.go b/pkg/op/mock/storage.mock.go index 02a7c5c..0df9830 100644 --- a/pkg/op/mock/storage.mock.go +++ b/pkg/op/mock/storage.mock.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/zitadel/oidc/v3/pkg/op (interfaces: Storage) +// Source: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Storage) // Package mock is a generated GoMock package. package mock @@ -9,10 +9,10 @@ import ( reflect "reflect" time "time" + oidc "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + op "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" jose "github.com/go-jose/go-jose/v4" gomock "github.com/golang/mock/gomock" - oidc "github.com/zitadel/oidc/v3/pkg/oidc" - op "github.com/zitadel/oidc/v3/pkg/op" ) // MockStorage is a mock of Storage interface. diff --git a/pkg/op/mock/storage.mock.impl.go b/pkg/op/mock/storage.mock.impl.go index 002da7e..96e08a9 100644 --- a/pkg/op/mock/storage.mock.impl.go +++ b/pkg/op/mock/storage.mock.impl.go @@ -8,8 +8,8 @@ import ( "github.com/golang/mock/gomock" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) func NewStorage(t *testing.T) op.Storage { diff --git a/pkg/op/op.go b/pkg/op/op.go index 58ae838..76c2c89 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -14,8 +14,8 @@ import ( "go.opentelemetry.io/otel" "golang.org/x/text/language" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) const ( diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index 9a4a624..e1ac0bd 100644 --- a/pkg/op/op_test.go +++ b/pkg/op/op_test.go @@ -11,12 +11,12 @@ import ( "testing" "time" + "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/example/server/storage" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" "golang.org/x/text/language" ) diff --git a/pkg/op/probes.go b/pkg/op/probes.go index cb3853d..fa713da 100644 --- a/pkg/op/probes.go +++ b/pkg/op/probes.go @@ -5,7 +5,7 @@ import ( "errors" "net/http" - httphelper "github.com/zitadel/oidc/v3/pkg/http" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" ) type ProbesFn func(context.Context) error diff --git a/pkg/op/server.go b/pkg/op/server.go index b500e43..d45b734 100644 --- a/pkg/op/server.go +++ b/pkg/op/server.go @@ -5,9 +5,9 @@ import ( "net/http" "net/url" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/muhlemmer/gu" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" ) // Server describes the interface that needs to be implemented to serve diff --git a/pkg/op/server_http.go b/pkg/op/server_http.go index 725dd64..d71a354 100644 --- a/pkg/op/server_http.go +++ b/pkg/op/server_http.go @@ -6,11 +6,11 @@ import ( "net/http" "net/url" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/go-chi/chi/v5" "github.com/rs/cors" "github.com/zitadel/logging" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/schema" ) diff --git a/pkg/op/server_http_routes_test.go b/pkg/op/server_http_routes_test.go index 1bfb32b..02200ee 100644 --- a/pkg/op/server_http_routes_test.go +++ b/pkg/op/server_http_routes_test.go @@ -14,9 +14,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v3/pkg/client" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) func jwtProfile() (string, error) { diff --git a/pkg/op/server_http_test.go b/pkg/op/server_http_test.go index 9ff07bc..75d02ca 100644 --- a/pkg/op/server_http_test.go +++ b/pkg/op/server_http_test.go @@ -14,11 +14,11 @@ import ( "testing" "time" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/schema" ) diff --git a/pkg/op/server_legacy.go b/pkg/op/server_legacy.go index 126fde1..06e4e93 100644 --- a/pkg/op/server_legacy.go +++ b/pkg/op/server_legacy.go @@ -6,8 +6,8 @@ import ( "net/http" "time" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/go-chi/chi/v5" - "github.com/zitadel/oidc/v3/pkg/oidc" ) // ExtendedLegacyServer allows embedding [LegacyServer] in a struct, diff --git a/pkg/op/session.go b/pkg/op/session.go index eb67b3c..ac663c9 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -8,8 +8,8 @@ import ( "net/url" "path" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type SessionEnder interface { diff --git a/pkg/op/storage.go b/pkg/op/storage.go index 35d7040..2dbd124 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -8,7 +8,7 @@ import ( jose "github.com/go-jose/go-jose/v4" "golang.org/x/text/language" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type AuthStorage interface { diff --git a/pkg/op/token.go b/pkg/op/token.go index 1df9cc2..2e25d05 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -5,8 +5,8 @@ import ( "slices" "time" - "github.com/zitadel/oidc/v3/pkg/crypto" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type TokenCreator interface { diff --git a/pkg/op/token_client_credentials.go b/pkg/op/token_client_credentials.go index 63dcc79..ddb2fbf 100644 --- a/pkg/op/token_client_credentials.go +++ b/pkg/op/token_client_credentials.go @@ -5,8 +5,8 @@ import ( "net/http" "net/url" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) // ClientCredentialsExchange handles the OAuth 2.0 client_credentials grant, including diff --git a/pkg/op/token_code.go b/pkg/op/token_code.go index 3612240..155aa43 100644 --- a/pkg/op/token_code.go +++ b/pkg/op/token_code.go @@ -4,8 +4,8 @@ import ( "context" "net/http" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) // CodeExchange handles the OAuth 2.0 authorization_code grant, including diff --git a/pkg/op/token_exchange.go b/pkg/op/token_exchange.go index fcb4468..00af485 100644 --- a/pkg/op/token_exchange.go +++ b/pkg/op/token_exchange.go @@ -7,8 +7,8 @@ import ( "strings" "time" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type TokenExchangeRequest interface { diff --git a/pkg/op/token_intospection.go b/pkg/op/token_intospection.go index 29234e1..bb6a5a0 100644 --- a/pkg/op/token_intospection.go +++ b/pkg/op/token_intospection.go @@ -5,8 +5,8 @@ import ( "errors" "net/http" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type Introspector interface { diff --git a/pkg/op/token_jwt_profile.go b/pkg/op/token_jwt_profile.go index d1a7ff5..defb937 100644 --- a/pkg/op/token_jwt_profile.go +++ b/pkg/op/token_jwt_profile.go @@ -5,8 +5,8 @@ import ( "net/http" "time" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type JWTAuthorizationGrantExchanger interface { diff --git a/pkg/op/token_refresh.go b/pkg/op/token_refresh.go index 7c8c1c0..a87e883 100644 --- a/pkg/op/token_refresh.go +++ b/pkg/op/token_refresh.go @@ -7,8 +7,8 @@ import ( "slices" "time" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type RefreshTokenRequest interface { diff --git a/pkg/op/token_request.go b/pkg/op/token_request.go index 66e4c83..3f5af7a 100644 --- a/pkg/op/token_request.go +++ b/pkg/op/token_request.go @@ -6,8 +6,8 @@ import ( "net/http" "net/url" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type Exchanger interface { diff --git a/pkg/op/token_request_test.go b/pkg/op/token_request_test.go index 21cf20b..d226af6 100644 --- a/pkg/op/token_request_test.go +++ b/pkg/op/token_request_test.go @@ -3,22 +3,22 @@ package op_test import ( "testing" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/stretchr/testify/assert" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" ) func TestAuthorizeCodeChallenge(t *testing.T) { tests := []struct { - name string - codeVerifier string - codeChallenge *oidc.CodeChallenge - want func(t *testing.T, err error) + name string + codeVerifier string + codeChallenge *oidc.CodeChallenge + want func(t *testing.T, err error) }{ { - name: "missing both code_verifier and code_challenge", - codeVerifier: "", - codeChallenge: nil, + name: "missing both code_verifier and code_challenge", + codeVerifier: "", + codeChallenge: nil, want: func(t *testing.T, err error) { assert.Nil(t, err) }, @@ -46,9 +46,9 @@ func TestAuthorizeCodeChallenge(t *testing.T) { }, }, { - name: "code_verifier provided without code_challenge", - codeVerifier: "code_verifier", - codeChallenge: nil, + name: "code_verifier provided without code_challenge", + codeVerifier: "code_verifier", + codeChallenge: nil, want: func(t *testing.T, err error) { assert.ErrorContains(t, err, "code_verifier unexpectedly provided") }, diff --git a/pkg/op/token_revocation.go b/pkg/op/token_revocation.go index a86a481..049ee15 100644 --- a/pkg/op/token_revocation.go +++ b/pkg/op/token_revocation.go @@ -7,8 +7,8 @@ import ( "net/url" "strings" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type Revoker interface { diff --git a/pkg/op/userinfo.go b/pkg/op/userinfo.go index 839b139..ff75e72 100644 --- a/pkg/op/userinfo.go +++ b/pkg/op/userinfo.go @@ -6,8 +6,8 @@ import ( "net/http" "strings" - httphelper "github.com/zitadel/oidc/v3/pkg/http" - "github.com/zitadel/oidc/v3/pkg/oidc" + httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type UserinfoProvider interface { diff --git a/pkg/op/verifier_access_token.go b/pkg/op/verifier_access_token.go index 6ac29f2..585ca54 100644 --- a/pkg/op/verifier_access_token.go +++ b/pkg/op/verifier_access_token.go @@ -3,7 +3,7 @@ package op import ( "context" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type AccessTokenVerifier oidc.Verifier diff --git a/pkg/op/verifier_access_token_example_test.go b/pkg/op/verifier_access_token_example_test.go index 397a2d3..b97a7fd 100644 --- a/pkg/op/verifier_access_token_example_test.go +++ b/pkg/op/verifier_access_token_example_test.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" ) // MyCustomClaims extends the TokenClaims base, diff --git a/pkg/op/verifier_access_token_test.go b/pkg/op/verifier_access_token_test.go index 66e32ce..5845f9f 100644 --- a/pkg/op/verifier_access_token_test.go +++ b/pkg/op/verifier_access_token_test.go @@ -5,10 +5,10 @@ import ( "testing" "time" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestNewAccessTokenVerifier(t *testing.T) { diff --git a/pkg/op/verifier_id_token_hint.go b/pkg/op/verifier_id_token_hint.go index 331c64c..02610aa 100644 --- a/pkg/op/verifier_id_token_hint.go +++ b/pkg/op/verifier_id_token_hint.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) type IDTokenHintVerifier oidc.Verifier diff --git a/pkg/op/verifier_id_token_hint_test.go b/pkg/op/verifier_id_token_hint_test.go index 597e291..347e33c 100644 --- a/pkg/op/verifier_id_token_hint_test.go +++ b/pkg/op/verifier_id_token_hint_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" ) func TestNewIDTokenHintVerifier(t *testing.T) { diff --git a/pkg/op/verifier_jwt_profile.go b/pkg/op/verifier_jwt_profile.go index 06a7d34..85bfb14 100644 --- a/pkg/op/verifier_jwt_profile.go +++ b/pkg/op/verifier_jwt_profile.go @@ -8,7 +8,7 @@ import ( jose "github.com/go-jose/go-jose/v4" - "github.com/zitadel/oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" ) // JWTProfileVerfiier extends oidc.Verifier with diff --git a/pkg/op/verifier_jwt_profile_test.go b/pkg/op/verifier_jwt_profile_test.go index d96cbb4..2068678 100644 --- a/pkg/op/verifier_jwt_profile_test.go +++ b/pkg/op/verifier_jwt_profile_test.go @@ -5,11 +5,11 @@ import ( "testing" "time" + tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - tu "github.com/zitadel/oidc/v3/internal/testutil" - "github.com/zitadel/oidc/v3/pkg/oidc" - "github.com/zitadel/oidc/v3/pkg/op" ) func TestNewJWTProfileVerifier(t *testing.T) {