diff --git a/.forgejo.bak/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml similarity index 99% rename from .forgejo.bak/ISSUE_TEMPLATE/bug_report.yaml rename to .github/ISSUE_TEMPLATE/bug_report.yaml index d024341..92465f9 100644 --- a/.forgejo.bak/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -2,7 +2,6 @@ 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: diff --git a/.forgejo.bak/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from .forgejo.bak/ISSUE_TEMPLATE/config.yml rename to .github/ISSUE_TEMPLATE/config.yml diff --git a/.forgejo.bak/ISSUE_TEMPLATE/docs.yaml b/.github/ISSUE_TEMPLATE/docs.yaml similarity index 98% rename from .forgejo.bak/ISSUE_TEMPLATE/docs.yaml rename to .github/ISSUE_TEMPLATE/docs.yaml index d3f82b9..04c1c0c 100644 --- a/.forgejo.bak/ISSUE_TEMPLATE/docs.yaml +++ b/.github/ISSUE_TEMPLATE/docs.yaml @@ -1,7 +1,6 @@ name: 📄 Documentation description: Create an issue for missing or wrong documentation. labels: ["docs"] -type: task body: - type: markdown attributes: diff --git a/.forgejo.bak/ISSUE_TEMPLATE/enhancement.yaml b/.github/ISSUE_TEMPLATE/improvement.yaml similarity index 92% rename from .forgejo.bak/ISSUE_TEMPLATE/enhancement.yaml rename to .github/ISSUE_TEMPLATE/improvement.yaml index ef2103e..2e2ddf4 100644 --- a/.forgejo.bak/ISSUE_TEMPLATE/enhancement.yaml +++ b/.github/ISSUE_TEMPLATE/improvement.yaml @@ -1,12 +1,11 @@ name: 🛠️ Improvement description: "Create an new issue for an improvment in ZITADEL" -labels: ["enhancement"] -type: enhancement +labels: ["improvement"] body: - type: markdown attributes: value: | - Thanks for taking the time to fill out this proposal / feature reqeust + Thanks for taking the time to fill out this improvement request - type: checkboxes id: preflight attributes: diff --git a/.github/ISSUE_TEMPLATE/proposal.yaml b/.github/ISSUE_TEMPLATE/proposal.yaml new file mode 100644 index 0000000..af7acd5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/proposal.yaml @@ -0,0 +1,44 @@ +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. diff --git a/.forgejo.bak/dependabot.yml b/.github/dependabot.yml similarity index 100% rename from .forgejo.bak/dependabot.yml rename to .github/dependabot.yml diff --git a/.forgejo.bak/pull_request_template.md b/.github/pull_request_template.md similarity index 100% rename from .forgejo.bak/pull_request_template.md rename to .github/pull_request_template.md diff --git a/.forgejo.bak/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml similarity index 100% rename from .forgejo.bak/workflows/codeql-analysis.yml rename to .github/workflows/codeql-analysis.yml diff --git a/.forgejo.bak/workflows/issue.yml b/.github/workflows/issue.yml similarity index 100% rename from .forgejo.bak/workflows/issue.yml rename to .github/workflows/issue.yml diff --git a/.forgejo.bak/workflows/release.yml b/.github/workflows/release.yml similarity index 89% rename from .forgejo.bak/workflows/release.yml rename to .github/workflows/release.yml index 00063e4..66d68b6 100644 --- a/.forgejo.bak/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,11 +14,11 @@ on: jobs: test: - runs-on: ubuntu-24.04 + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - go: ['1.23', '1.24'] + go: ['1.21', '1.22'] name: Go ${{ matrix.go }} test steps: - uses: actions/checkout@v4 @@ -27,12 +27,12 @@ jobs: with: go-version: ${{ matrix.go }} - run: go test -race -v -coverprofile=profile.cov -coverpkg=./pkg/... ./pkg/... - - uses: codecov/codecov-action@v5.4.3 + - uses: codecov/codecov-action@v4.6.0 with: file: ./profile.cov name: codecov-go release: - runs-on: ubuntu-24.04 + runs-on: ubuntu-20.04 needs: [test] if: ${{ github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next' }} env: diff --git a/README.md b/README.md index bc346f5..b102815 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ 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
@@ -38,6 +37,7 @@ 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,13 +60,10 @@ 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 ``` @@ -78,36 +75,35 @@ 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] | @@ -121,18 +117,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]: 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" +[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" ## Contributors @@ -156,9 +152,9 @@ Versions that also build are marked with :warning:. | Version | Supported | | ------- | ------------------ | -| <1.23 | :x: | -| 1.23 | :white_check_mark: | -| 1.24 | :white_check_mark: | +| <1.21 | :x: | +| 1.21 | :white_check_mark: | +| 1.22 | :white_check_mark: | ## Why another library @@ -189,4 +185,5 @@ 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 diff --git a/example/client/api/api.go b/example/client/api/api.go index 69f9466..2e61c21 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rs" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rs" + "github.com/zitadel/oidc/v3/pkg/oidc" ) const ( diff --git a/example/client/app/app.go b/example/client/app/app.go index 90b1969..0b9b19d 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 33bc570..78ed2c8 100644 --- a/example/client/device/device.go +++ b/example/client/device/device.go @@ -45,8 +45,8 @@ import ( "github.com/sirupsen/logrus" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/client/rp" + httphelper "github.com/zitadel/oidc/v3/pkg/http" ) var ( diff --git a/example/client/github/github.go b/example/client/github/github.go index f6c536b..7d069d4 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" - "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" + "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" ) var ( diff --git a/example/client/service/service.go b/example/client/service/service.go index a88ab2f..865a4e0 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/profile" + "github.com/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 05f0e34..685b444 100644 --- a/example/server/dynamic/login.go +++ b/example/server/dynamic/login.go @@ -8,7 +8,7 @@ import ( "github.com/go-chi/chi/v5" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op" ) const ( diff --git a/example/server/dynamic/op.go b/example/server/dynamic/op.go index 2c00e41..432a575 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" - "git.christmann.info/LARA/zitadel-oidc/v3/example/server/storage" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/example/server/storage" + "github.com/zitadel/oidc/v3/pkg/op" ) const ( diff --git a/example/server/exampleop/device.go b/example/server/exampleop/device.go index 99505e4..2f9be52 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 77a6189..4d2b478 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 e12c755..8f55b0a 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op" ) const ( diff --git a/example/server/main.go b/example/server/main.go index 5bdbb05..36816d6 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -6,9 +6,9 @@ import ( "net/http" "os" - "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" + "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) { @@ -32,8 +32,8 @@ func main() { storage.RegisterClients( storage.NativeClient("native", cfg.RedirectURI...), - storage.WebClient("web", "secret", cfg.RedirectURI...), - storage.WebClient("api", "secret", cfg.RedirectURI...), + storage.WebClient("web", "secret"), + storage.WebClient("api", "secret"), ) // the OpenIDProvider interface needs a Storage interface handling various checks and state manipulations diff --git a/example/server/storage/client.go b/example/server/storage/client.go index 2b836c0..010b9ce 100644 --- a/example/server/storage/client.go +++ b/example/server/storage/client.go @@ -3,8 +3,8 @@ package storage import ( "time" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" ) var ( diff --git a/example/server/storage/oidc.go b/example/server/storage/oidc.go index 9c7f544..22c0295 100644 --- a/example/server/storage/oidc.go +++ b/example/server/storage/oidc.go @@ -6,8 +6,8 @@ import ( "golang.org/x/text/language" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" ) const ( @@ -164,15 +164,6 @@ 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/example/server/storage/storage.go b/example/server/storage/storage.go index d4315c6..d8b7a5d 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" ) // serviceKey1 is a public key which will be used for the JWT Profile Authorization Grant @@ -151,9 +151,6 @@ 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") @@ -298,19 +295,15 @@ 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 - - newRefreshToken = uuid.NewString() - - accessToken, err := s.accessToken(applicationID, newRefreshToken, request.GetSubject(), request.GetAudience(), request.GetScopes()) + refreshToken, refreshTokenID, err := s.renewRefreshToken(currentRefreshToken) if err != nil { return "", "", time.Time{}, err } - - if err := s.renewRefreshToken(currentRefreshToken, newRefreshToken, accessToken.ID); err != nil { + accessToken, err := s.accessToken(applicationID, refreshTokenID, request.GetSubject(), request.GetAudience(), request.GetScopes()) + if err != nil { return "", "", time.Time{}, err } - - return accessToken.ID, newRefreshToken, accessToken.Expiration, nil + return accessToken.ID, refreshToken, accessToken.Expiration, nil } func (s *Storage) exchangeRefreshToken(ctx context.Context, request op.TokenExchangeRequest) (accessTokenID string, newRefreshToken string, expiration time.Time, err error) { @@ -392,9 +385,14 @@ 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") } - delete(s.refreshTokens, refreshToken.ID) // if it is a refresh token, you will have to remove the access token as well - delete(s.tokens, refreshToken.AccessToken) + delete(s.refreshTokens, refreshToken.ID) + for _, accessToken := range s.tokens { + if accessToken.RefreshTokenID == refreshToken.ID { + delete(s.tokens, accessToken.ID) + return nil + } + } return nil } @@ -490,9 +488,6 @@ 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) } @@ -599,41 +594,33 @@ 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, newRefreshToken, newAccessToken string) error { +func (s *Storage) renewRefreshToken(currentRefreshToken string) (string, 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 + // deletes the refresh token and all access tokens which were issued based on this 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") + for _, token := range s.tokens { + if token.RefreshTokenID == currentRefreshToken { + delete(s.tokens, token.ID) + break + } } - // creates a new refresh token based on the current one - refreshToken.Token = newRefreshToken - refreshToken.ID = newRefreshToken - refreshToken.Expiration = time.Now().Add(5 * time.Hour) - refreshToken.AccessToken = newAccessToken - s.refreshTokens[newRefreshToken] = refreshToken - return nil + token := uuid.NewString() + refreshToken.Token = token + refreshToken.ID = token + s.refreshTokens[token] = refreshToken + return token, refreshToken.ID, nil } // accessToken will store an access_token in-memory based on the provided information diff --git a/example/server/storage/storage_dynamic.go b/example/server/storage/storage_dynamic.go index 765d29a..d112d71 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" ) type multiStorage struct { diff --git a/example/server/storage/token.go b/example/server/storage/token.go index beab38c..ad907e3 100644 --- a/example/server/storage/token.go +++ b/example/server/storage/token.go @@ -22,5 +22,4 @@ type RefreshToken struct { ApplicationID string Expiration time.Time Scopes []string - AccessToken string // Token.ID } diff --git a/go.mod b/go.mod index a0f42c4..f50972a 100644 --- a/go.mod +++ b/go.mod @@ -1,28 +1,26 @@ -module git.christmann.info/LARA/zitadel-oidc/v3 +module github.com/zitadel/oidc/v3 -go 1.23.7 - -toolchain go1.24.1 +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.5 + 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 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.8 + 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.1 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.1 + github.com/stretchr/testify v1.9.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.30.0 - golang.org/x/text v0.26.0 + golang.org/x/oauth2 v0.23.0 + golang.org/x/text v0.19.0 ) require ( @@ -33,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.36.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sys v0.31.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 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4835505..91de9bf 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,12 @@ -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/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= -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.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= -github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +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.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= @@ -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.8 h1:mmSITBz9JxVtu8eqbN+zmmwX7Ij2RidQxhcwRVI4wqA= -github.com/jeremija/gosubmit v0.2.8/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= +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= @@ -47,13 +47,13 @@ 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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.2 h1:MW2kDDR0ieQynPZ0KIZPrh9ote2WkxfBif5QoARDQcU= -github.com/zitadel/logging v0.6.2/go.mod h1:z6VWLWUkJpnNVDSLzrPSQSQyttysKZ6bCRongw0ROK4= -github.com/zitadel/schema v1.3.1 h1:QT3kwiRIRXXLVAs6gCK/u044WmUVh6IlbLXUsn6yRQU= -github.com/zitadel/schema v1.3.1/go.mod h1:071u7D2LQacy1HAN+YnMd/mx1qVE2isb0Mjeqg46xnU= +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= 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= @@ -62,19 +62,19 @@ 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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +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= 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.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +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= @@ -83,13 +83,13 @@ 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.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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= -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/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= @@ -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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +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/internal/testutil/gen/gen.go b/internal/testutil/gen/gen.go index 3e44b7d..e4a5718 100644 --- a/internal/testutil/gen/gen.go +++ b/internal/testutil/gen/gen.go @@ -8,8 +8,8 @@ import ( "fmt" "os" - tu "git.christmann.info/LARA/zitadel-oidc/v3/internal/testutil" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + tu "github.com/zitadel/oidc/v3/internal/testutil" + "github.com/zitadel/oidc/v3/pkg/oidc" ) var custom = map[string]any{ diff --git a/internal/testutil/token.go b/internal/testutil/token.go index 72d08c5..7ad8893 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 2e1f536..56417b5 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -15,9 +15,9 @@ import ( "go.opentelemetry.io/otel" "golang.org/x/oauth2" - "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" + "github.com/zitadel/oidc/v3/pkg/crypto" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) var ( diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 9e21e8e..1046941 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 86a9ab7..98a9d3a 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" - "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" + "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" ) var Logger = slog.New( diff --git a/pkg/client/jwt_profile.go b/pkg/client/jwt_profile.go index 98a54fd..0a5d9ec 100644 --- a/pkg/client/jwt_profile.go +++ b/pkg/client/jwt_profile.go @@ -6,8 +6,8 @@ import ( "golang.org/x/oauth2" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) // JWTProfileExchange handles the oauth2 jwt profile exchange diff --git a/pkg/client/key.go b/pkg/client/key.go index 7f38311..0c01dd2 100644 --- a/pkg/client/key.go +++ b/pkg/client/key.go @@ -2,7 +2,7 @@ package client import ( "encoding/json" - "os" + "io/ioutil" ) const ( @@ -24,7 +24,7 @@ type KeyFile struct { } func ConfigFromKeyFile(path string) (*KeyFile, error) { - data, err := os.ReadFile(path) + data, err := ioutil.ReadFile(path) if err != nil { return nil, err } diff --git a/pkg/client/profile/jwt_profile.go b/pkg/client/profile/jwt_profile.go index fb351f0..060f390 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client" + "github.com/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 10edaa7..eeb9011 100644 --- a/pkg/client/rp/cli/cli.go +++ b/pkg/client/rp/cli/cli.go @@ -4,9 +4,9 @@ import ( "context" "net/http" - "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/oidc/v3/pkg/client/rp" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) const ( diff --git a/pkg/client/rp/delegation.go b/pkg/client/rp/delegation.go index fb4fc63..23ecffd 100644 --- a/pkg/client/rp/delegation.go +++ b/pkg/client/rp/delegation.go @@ -1,7 +1,7 @@ package rp import ( - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc/grants/tokenexchange" + "github.com/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 1fadd56..c2d1f8a 100644 --- a/pkg/client/rp/device.go +++ b/pkg/client/rp/device.go @@ -5,8 +5,8 @@ import ( "fmt" "time" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client" + "github.com/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 0ccbad2..c44a267 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" - "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/oidc/v3/pkg/client" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/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 c2759a2..e6fa078 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 b3bb6ee..4c5a1b3 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 aa2cf99..c8ca048 100644 --- a/pkg/client/rp/tockenexchange.go +++ b/pkg/client/rp/tockenexchange.go @@ -5,7 +5,7 @@ import ( "golang.org/x/oauth2" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc/grants/tokenexchange" + "github.com/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 78e014e..2cc5222 100644 --- a/pkg/client/rp/userinfo_example_test.go +++ b/pkg/client/rp/userinfo_example_test.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rp" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type UserInfo struct { diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index 0088b81..ca59454 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "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 diff --git a/pkg/client/rp/verifier_test.go b/pkg/client/rp/verifier_test.go index 38f5a4a..24d35af 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 7ae68d6..892eb23 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 "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" + tu "github.com/zitadel/oidc/v3/internal/testutil" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/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 1f67d11..eac8be2 100644 --- a/pkg/client/rs/introspect_example_test.go +++ b/pkg/client/rs/introspect_example_test.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/client/rs" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rs" + "github.com/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 993796e..962af7e 100644 --- a/pkg/client/rs/resource_server.go +++ b/pkg/client/rs/resource_server.go @@ -6,9 +6,9 @@ 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/zitadel/oidc/v3/pkg/client" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/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 afd7441..7a5ced9 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 9cc1328..61975a4 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 a6fa493..8ed5cb5 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" + zcrypto "github.com/zitadel/oidc/v3/pkg/crypto" ) func TestBytesToPrivateKey(t *testing.T) { diff --git a/pkg/http/http.go b/pkg/http/http.go index aa0ff6f..33c5f15 100644 --- a/pkg/http/http.go +++ b/pkg/http/http.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" ) var DefaultHTTPClient = &http.Client{ diff --git a/pkg/oidc/code_challenge.go b/pkg/oidc/code_challenge.go index 0c593df..3296362 100644 --- a/pkg/oidc/code_challenge.go +++ b/pkg/oidc/code_challenge.go @@ -3,7 +3,7 @@ package oidc import ( "crypto/sha256" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" + "github.com/zitadel/oidc/v3/pkg/crypto" ) const ( diff --git a/pkg/oidc/error.go b/pkg/oidc/error.go index d93cf44..1100f73 100644 --- a/pkg/oidc/error.go +++ b/pkg/oidc/error.go @@ -133,7 +133,6 @@ 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:"-"` } @@ -143,13 +142,11 @@ 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() @@ -179,8 +176,7 @@ 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.SessionState == t.SessionState || t.SessionState == "") + (e.State == t.State || t.State == "") } func (e *Error) WithParent(err error) *Error { @@ -246,9 +242,6 @@ 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/oidc/session.go b/pkg/oidc/session.go index 39f9f08..b470d1e 100644 --- a/pkg/oidc/session.go +++ b/pkg/oidc/session.go @@ -1,12 +1,10 @@ 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"` - 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"` + IdTokenHint string `schema:"id_token_hint"` + ClientID string `schema:"client_id"` + PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"` + State string `schema:"state"` } diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index 4b43dcb..e57d91e 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -10,7 +10,7 @@ import ( "github.com/muhlemmer/gu" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" + "github.com/zitadel/oidc/v3/pkg/crypto" ) const ( @@ -230,13 +230,12 @@ 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"` - Scope SpaceDelimitedArray `json:"scope,omitempty" schema:"scope,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"` } type JWTProfileAssertionClaims struct { diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 5d063b1..e7292e6 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -35,17 +35,6 @@ 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 { @@ -93,9 +82,6 @@ func (l *Locale) MarshalJSON() ([]byte, error) { // 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 { - if len(data) == 0 || string(data) == "\"\"" { - return nil - } err := json.Unmarshal(data, &l.tag) if err == nil { return nil @@ -126,14 +112,6 @@ 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 @@ -250,9 +228,6 @@ 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/oidc/types_test.go b/pkg/oidc/types_test.go index 53a9779..df93a73 100644 --- a/pkg/oidc/types_test.go +++ b/pkg/oidc/types_test.go @@ -217,30 +217,6 @@ 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"}`, @@ -261,17 +237,16 @@ func TestLocale_UnmarshalJSON(t *testing.T) { wantErr: true, }, } + for _, tt := range tests { - 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) - }) + 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) } } diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index d5e0213..f580da6 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -7,11 +7,12 @@ 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 { @@ -83,7 +84,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 !slices.Contains(possibleValues, acr) { + if !str.Contains(possibleValues, acr) { return fmt.Errorf("expected one of: %v, got: %q", possibleValues, acr) } return nil @@ -122,7 +123,7 @@ func CheckIssuer(claims Claims, issuer string) error { } func CheckAudience(claims Claims, clientID string) error { - if !slices.Contains(claims.GetAudience(), clientID) { + if !str.Contains(claims.GetAudience(), clientID) { return fmt.Errorf("%w: Audience must contain client_id %q", ErrAudience, clientID) } diff --git a/pkg/oidc/verifier_parse_test.go b/pkg/oidc/verifier_parse_test.go index 9cf5c1e..105650f 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 b1434cc..52fda2e 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -15,9 +15,10 @@ 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" + str "github.com/zitadel/oidc/v3/pkg/strings" ) type AuthRequest interface { @@ -38,13 +39,6 @@ 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 @@ -62,12 +56,6 @@ 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) @@ -116,8 +104,8 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { } return ValidateAuthRequestClient(ctx, authReq, client, verifier) } - if validator, ok := authorizer.(AuthorizeValidator); ok { - validation = validator.ValidateAuthRequest + if validater, ok := authorizer.(AuthorizeValidator); ok { + validation = validater.ValidateAuthRequest } userID, err := validation(ctx, authReq, authorizer.Storage(), authorizer.IDTokenHintVerifier(ctx)) if err != nil { @@ -168,7 +156,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 !slices.Contains(requestObject.Audience, issuer) { + if !str.Contains(requestObject.Audience, issuer) { return oidc.ErrInvalidRequest().WithDescription("issuer missing in audience") } keySet := &jwtProfileKeySet{storage: storage, clientID: requestObject.Issuer} @@ -182,7 +170,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 slices.Contains(authReq.Scopes, oidc.ScopeOpenID) && len(requestObject.Scopes) > 0 { + if str.Contains(authReq.Scopes, oidc.ScopeOpenID) && len(requestObject.Scopes) > 0 { authReq.Scopes = requestObject.Scopes } if requestObject.RedirectURI != "" { @@ -300,7 +288,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 slices.Contains(client.RedirectURIs(), uri) { + if str.Contains(client.RedirectURIs(), uri) { return nil } if globClient, ok := client.(HasRedirectGlobs); ok { @@ -325,12 +313,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 client.ApplicationType() == ApplicationTypeNative { - return validateAuthReqRedirectURINative(client, uri) - } if strings.HasPrefix(uri, "https://") { return checkURIAgainstRedirects(client, uri) } + if client.ApplicationType() == ApplicationTypeNative { + return validateAuthReqRedirectURINative(client, uri) + } if err := checkURIAgainstRedirects(client, uri); err != nil { return err } @@ -351,15 +339,12 @@ 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://") || strings.HasPrefix(uri, "https://")) + isCustomSchema := !strings.HasPrefix(uri, "http://") if err := checkURIAgainstRedirects(client, uri); err == nil { if client.DevMode() { return nil } - if !isLoopback && strings.HasPrefix(uri, "https://") { - return nil - } - // The RedirectURIs are only valid for native clients when localhost or non-"http://" and "https://" + // The RedirectURIs are only valid for native clients when localhost or non-"http://" if isLoopback || isCustomSchema { return nil } @@ -389,11 +374,11 @@ func HTTPLoopbackOrLocalhost(rawURL string) (*url.URL, bool) { if err != nil { return nil, false } - if parsedURL.Scheme == "http" || parsedURL.Scheme == "https" { - hostName := parsedURL.Hostname() - return parsedURL, hostName == "localhost" || net.ParseIP(hostName).IsLoopback() + if parsedURL.Scheme != "http" { + return nil, false } - return nil, false + hostName := parsedURL.Hostname() + return parsedURL, hostName == "localhost" || net.ParseIP(hostName).IsLoopback() } // ValidateAuthReqResponseType validates the passed response_type to the registered response types @@ -483,70 +468,41 @@ func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWri AuthResponseToken(w, r, authReq, authorizer, client) } -// AuthResponseCode handles the creation of a successful authentication response using an authorization code +// 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") - defer span.End() r = r.WithContext(ctx) + defer span.End() - 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 + } + codeResponse := struct { + Code string `schema:"code"` + State string `schema:"state,omitempty"` + }{ + Code: code, + State: authReq.GetState(), } -} -// 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 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 { - return err + AuthRequestError(w, r, authReq, err, authorizer) + return } - 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() - } - - return &CodeResponseType{ - Code: code, - State: authReq.GetState(), - SessionState: sessionState, - }, nil -} - -// 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 { - return "", err - } - - return AuthResponseURL(authReq.GetRedirectURI(), authReq.GetResponseType(), authReq.GetResponseMode(), codeResponse, authorizer.Encoder()) + http.Redirect(w, r, callback, http.StatusFound) } // 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 d1ea965..6b4af17 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" ) @@ -433,24 +433,6 @@ 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{ @@ -1090,34 +1072,6 @@ 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{ @@ -1225,133 +1179,6 @@ 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 { @@ -1382,231 +1209,3 @@ 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) - } - } - }) - } -} diff --git a/pkg/op/client.go b/pkg/op/client.go index a4f44d3..913944c 100644 --- a/pkg/op/client.go +++ b/pkg/op/client.go @@ -7,8 +7,8 @@ import ( "net/url" "time" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/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 b416630..b772ba5 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/config.go b/pkg/op/config.go index b271765..2fcede0 100644 --- a/pkg/op/config.go +++ b/pkg/op/config.go @@ -30,7 +30,6 @@ type Configuration interface { EndSessionEndpoint() *Endpoint KeysEndpoint() *Endpoint DeviceAuthorizationEndpoint() *Endpoint - CheckSessionIframe() *Endpoint AuthMethodPostSupported() bool CodeMethodS256Supported() bool diff --git a/pkg/op/crypto.go b/pkg/op/crypto.go index 01aaad3..6ab1e0a 100644 --- a/pkg/op/crypto.go +++ b/pkg/op/crypto.go @@ -1,7 +1,7 @@ package op import ( - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" + "github.com/zitadel/oidc/v3/pkg/crypto" ) type Crypto interface { diff --git a/pkg/op/device.go b/pkg/op/device.go index 866cbc4..11638b0 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + 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 { @@ -91,7 +91,10 @@ func createDeviceAuthorization(ctx context.Context, req *oidc.DeviceAuthorizatio } config := o.DeviceAuthorization() - deviceCode, _ := NewDeviceCode(RecommendedDeviceCodeBytes) + deviceCode, err := NewDeviceCode(RecommendedDeviceCodeBytes) + if err != nil { + return nil, NewStatusError(err, http.StatusInternalServerError) + } userCode, err := NewUserCode([]rune(config.UserCode.CharSet), config.UserCode.CharAmount, config.UserCode.DashInterval) if err != nil { return nil, NewStatusError(err, http.StatusInternalServerError) @@ -160,14 +163,11 @@ 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) - rand.Read(bytes) + if _, err := rand.Read(bytes); err != nil { + return "", fmt.Errorf("%w getting entropy for device code", err) + } return base64.RawURLEncoding.EncodeToString(bytes), nil } @@ -276,7 +276,7 @@ func (r *DeviceAuthorizationState) GetAMR() []string { } func (r *DeviceAuthorizationState) GetAudience() []string { - if !slices.Contains(r.Audience, r.ClientID) { + if !strs.Contains(r.Audience, r.ClientID) { r.Audience = append(r.Audience, r.ClientID) } return r.Audience @@ -344,11 +344,10 @@ 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 - if idTokenRequest, ok := tokenRequest.(IDTokenRequest); ok && slices.Contains(tokenRequest.GetScopes(), oidc.ScopeOpenID) { + 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 diff --git a/pkg/op/device_test.go b/pkg/op/device_test.go index a7b5c4e..570b943 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) { @@ -145,11 +145,21 @@ func runWithRandReader(r io.Reader, f func()) { } func TestNewDeviceCode(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)) - } + 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)) + } + }) + } func TestNewUserCode(t *testing.T) { diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index 9b3ddb6..5a79a09 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type DiscoverStorage interface { @@ -45,7 +45,6 @@ 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), @@ -101,11 +100,7 @@ func createDiscoveryConfigV2(ctx context.Context, config Configuration, storage } func Scopes(c Configuration) []string { - provider, ok := c.(*Provider) - if ok && provider.config.SupportedScopes != nil { - return provider.config.SupportedScopes - } - return DefaultSupportedScopes + return DefaultSupportedScopes // TODO: config } func ResponseTypes(c Configuration) []string { @@ -140,7 +135,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 63f1b98..cb4cfba 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" - "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/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op/mock" ) func TestDiscover(t *testing.T) { @@ -81,11 +81,6 @@ 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/endpoint_test.go b/pkg/op/endpoint_test.go index 5b98c6e..bf112ef 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 272f85e..44b1798 100644 --- a/pkg/op/error.go +++ b/pkg/op/error.go @@ -7,8 +7,8 @@ import ( "log/slog" "net/http" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type ErrAuthRequest interface { @@ -46,12 +46,6 @@ 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() @@ -98,12 +92,6 @@ 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/error_test.go b/pkg/op/error_test.go index 9271cf1..107f9d0 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 97e400b..c96c456 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + httphelper "github.com/zitadel/oidc/v3/pkg/http" ) type KeyProvider interface { diff --git a/pkg/op/keys_test.go b/pkg/op/keys_test.go index 9c80878..3662739 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" - "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/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" + "github.com/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 56b28e0..c7703f1 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Authorizer) +// Source: github.com/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 73c4154..59e8fa3 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/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 e2a5e85..f01e3ec 100644 --- a/pkg/op/mock/client.go +++ b/pkg/op/mock/client.go @@ -5,8 +5,8 @@ import ( "github.com/golang/mock/gomock" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/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 93eca67..9be0807 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Client) +// Source: github.com/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 bf51035..137c09d 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Configuration) +// Source: github.com/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" ) @@ -106,20 +106,6 @@ 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/mock/discovery.mock.go b/pkg/op/mock/discovery.mock.go index c85f91b..a27f8ef 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: DiscoverStorage) +// Source: github.com/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 3d58ab7..e5cab3e 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 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 +//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 diff --git a/pkg/op/mock/glob.go b/pkg/op/mock/glob.go index 8149c8f..cade476 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 ebdc333..cf9996e 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: HasRedirectGlobs) +// Source: github.com/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 d9ee857..122e852 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: KeyProvider) +// Source: github.com/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 751ce60..e1bab91 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: SigningKey,Key) +// Source: github.com/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 0df9830..02a7c5c 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: git.christmann.info/LARA/zitadel-oidc/v3/pkg/op (interfaces: Storage) +// Source: github.com/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 96e08a9..002da7e 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/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 76c2c89..2248098 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) const ( @@ -167,7 +167,6 @@ type Config struct { RequestObjectSupported bool SupportedUILocales []language.Tag SupportedClaims []string - SupportedScopes []string DeviceAuthorization DeviceAuthorizationConfig BackChannelLogoutSupported bool BackChannelLogoutSessionSupported bool @@ -339,10 +338,6 @@ 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 } diff --git a/pkg/op/op_test.go b/pkg/op/op_test.go index e1ac0bd..83032d4 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" ) @@ -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,"scope":"openid offline_access"}`}, + contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299}`}, }, { // This call will fail. A successful test is already diff --git a/pkg/op/probes.go b/pkg/op/probes.go index fa713da..cb3853d 100644 --- a/pkg/op/probes.go +++ b/pkg/op/probes.go @@ -5,7 +5,7 @@ import ( "errors" "net/http" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" + httphelper "github.com/zitadel/oidc/v3/pkg/http" ) type ProbesFn func(context.Context) error diff --git a/pkg/op/server.go b/pkg/op/server.go index d45b734..b500e43 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 d71a354..725dd64 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 02200ee..2c83ad3 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" - "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" + "github.com/zitadel/oidc/v3/pkg/client" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" ) func jwtProfile() (string, error) { @@ -145,7 +145,7 @@ func TestServerRoutes(t *testing.T) { "assertion": jwtProfileToken, }, wantCode: http.StatusOK, - contains: []string{`{"access_token":`, `"token_type":"Bearer","expires_in":299,"scope":"openid"}`}, + contains: []string{`{"access_token":`, `"token_type":"Bearer","expires_in":299}`}, }, { 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,"scope":"openid offline_access"}`}, + contains: []string{`{"access_token":"`, `","token_type":"Bearer","expires_in":299}`}, }, { // This call will fail. A successful test is already diff --git a/pkg/op/server_http_test.go b/pkg/op/server_http_test.go index 75d02ca..9ff07bc 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 06e4e93..126fde1 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 ac663c9..8ac530d 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -8,8 +8,8 @@ import ( "net/url" "path" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type SessionEnder interface { @@ -73,8 +73,6 @@ 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 2dbd124..8488b28 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -6,9 +6,8 @@ import ( "time" jose "github.com/go-jose/go-jose/v4" - "golang.org/x/text/language" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type AuthStorage interface { @@ -145,12 +144,6 @@ 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 @@ -171,8 +164,6 @@ type EndSessionRequest struct { ClientID string IDTokenHintClaims *oidc.IDTokenClaims RedirectURI string - LogoutHint string - UILocales []language.Tag } var ErrDuplicateUserCode = errors.New("user code already exists") diff --git a/pkg/op/token.go b/pkg/op/token.go index 2e25d05..b45789b 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -2,11 +2,11 @@ package op import ( "context" - "slices" "time" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/crypto" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/crypto" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/strings" ) type TokenCreator interface { @@ -65,7 +65,6 @@ func CreateTokenResponse(ctx context.Context, request IDTokenRequest, client Cli TokenType: oidc.BearerToken, ExpiresIn: exp, State: state, - Scope: request.GetScopes(), }, nil } @@ -83,13 +82,13 @@ func createTokens(ctx context.Context, tokenRequest TokenRequest, storage Storag func needsRefreshToken(tokenRequest TokenRequest, client AccessTokenClient) bool { switch req := tokenRequest.(type) { case AuthRequest: - return slices.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && req.GetResponseType() == oidc.ResponseTypeCode && ValidateGrantType(client, oidc.GrantTypeRefreshToken) + return strings.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 slices.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && ValidateGrantType(client, oidc.GrantTypeRefreshToken) + return strings.Contains(req.GetScopes(), oidc.ScopeOfflineAccess) && ValidateGrantType(client, oidc.GrantTypeRefreshToken) default: return false } @@ -147,11 +146,7 @@ func CreateJWT(ctx context.Context, issuer string, tokenRequest TokenRequest, ex tokenExchangeRequest, ) } else { - 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)) - } + privateClaims, err = storage.GetPrivateClaimsFromScopes(ctx, tokenRequest.GetSubject(), client.GetID(), removeUserinfoScopes(restrictedScopes)) } if err != nil { diff --git a/pkg/op/token_client_credentials.go b/pkg/op/token_client_credentials.go index ddb2fbf..7f1debe 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) // ClientCredentialsExchange handles the OAuth 2.0 client_credentials grant, including @@ -120,6 +120,5 @@ 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_code.go b/pkg/op/token_code.go index 155aa43..3612240 100644 --- a/pkg/op/token_code.go +++ b/pkg/op/token_code.go @@ -4,8 +4,8 @@ import ( "context" "net/http" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/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 00af485..fcb4468 100644 --- a/pkg/op/token_exchange.go +++ b/pkg/op/token_exchange.go @@ -7,8 +7,8 @@ import ( "strings" "time" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type TokenExchangeRequest interface { diff --git a/pkg/op/token_intospection.go b/pkg/op/token_intospection.go index bb6a5a0..29234e1 100644 --- a/pkg/op/token_intospection.go +++ b/pkg/op/token_intospection.go @@ -5,8 +5,8 @@ import ( "errors" "net/http" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/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 defb937..96ce1ed 100644 --- a/pkg/op/token_jwt_profile.go +++ b/pkg/op/token_jwt_profile.go @@ -5,8 +5,8 @@ import ( "net/http" "time" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type JWTAuthorizationGrantExchanger interface { @@ -89,7 +89,6 @@ func CreateJWTTokenResponse(ctx context.Context, tokenRequest TokenRequest, crea AccessToken: accessToken, TokenType: oidc.BearerToken, ExpiresIn: uint64(validity.Seconds()), - Scope: tokenRequest.GetScopes(), }, nil } diff --git a/pkg/op/token_refresh.go b/pkg/op/token_refresh.go index a87e883..92ef476 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 "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + 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 !slices.Contains(authRequest.GetScopes(), scope) { + if !strings.Contains(authRequest.GetScopes(), scope) { return oidc.ErrInvalidScope() } } diff --git a/pkg/op/token_request.go b/pkg/op/token_request.go index 3f5af7a..85e2270 100644 --- a/pkg/op/token_request.go +++ b/pkg/op/token_request.go @@ -6,8 +6,8 @@ import ( "net/http" "net/url" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type Exchanger interface { @@ -132,19 +132,11 @@ 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_verifier required") + return oidc.ErrInvalidRequest().WithDescription("code_challenge required") } if !oidc.VerifyCodeChallenge(challenge, codeVerifier) { - return oidc.ErrInvalidGrant().WithDescription("invalid code_verifier") + return oidc.ErrInvalidGrant().WithDescription("invalid code challenge") } return nil } diff --git a/pkg/op/token_request_test.go b/pkg/op/token_request_test.go deleted file mode 100644 index d226af6..0000000 --- a/pkg/op/token_request_test.go +++ /dev/null @@ -1,75 +0,0 @@ -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" -) - -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) - }) - } -} diff --git a/pkg/op/token_revocation.go b/pkg/op/token_revocation.go index 049ee15..a86a481 100644 --- a/pkg/op/token_revocation.go +++ b/pkg/op/token_revocation.go @@ -7,8 +7,8 @@ import ( "net/url" "strings" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" ) type Revoker interface { diff --git a/pkg/op/userinfo.go b/pkg/op/userinfo.go index ff75e72..839b139 100644 --- a/pkg/op/userinfo.go +++ b/pkg/op/userinfo.go @@ -6,8 +6,8 @@ import ( "net/http" "strings" - httphelper "git.christmann.info/LARA/zitadel-oidc/v3/pkg/http" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/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 585ca54..6ac29f2 100644 --- a/pkg/op/verifier_access_token.go +++ b/pkg/op/verifier_access_token.go @@ -3,7 +3,7 @@ package op import ( "context" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/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 b97a7fd..397a2d3 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 "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" + tu "github.com/zitadel/oidc/v3/internal/testutil" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/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 5845f9f..66e32ce 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 02610aa..331c64c 100644 --- a/pkg/op/verifier_id_token_hint.go +++ b/pkg/op/verifier_id_token_hint.go @@ -4,7 +4,7 @@ import ( "context" "errors" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/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 347e33c..597e291 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 85bfb14..06a7d34 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" - "git.christmann.info/LARA/zitadel-oidc/v3/pkg/oidc" + "github.com/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 2068678..d96cbb4 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) { diff --git a/pkg/strings/strings.go b/pkg/strings/strings.go index b8f43a1..af48cf3 100644 --- a/pkg/strings/strings.go +++ b/pkg/strings/strings.go @@ -1,9 +1,10 @@ package strings -import "slices" - -// Deprecated: Use standard library [slices.Contains] instead. func Contains(list []string, needle string) bool { - // TODO(v4): remove package. - return slices.Contains(list, needle) + for _, item := range list { + if item == needle { + return true + } + } + return false }