Merge branch 'main' into feat/issue#574
This commit is contained in:
commit
9e700d2f38
37 changed files with 146 additions and 106 deletions
|
@ -10,7 +10,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/zitadel/logging"
|
||||
"github.com/zitadel/oidc/v3/pkg/crypto"
|
||||
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||
|
@ -97,7 +97,12 @@ func CallEndSessionEndpoint(ctx context.Context, request any, authFn any, caller
|
|||
ctx, span := Tracer.Start(ctx, "CallEndSessionEndpoint")
|
||||
defer span.End()
|
||||
|
||||
req, err := httphelper.FormRequest(ctx, caller.GetEndSessionEndpoint(), request, Encoder, authFn)
|
||||
endpoint := caller.GetEndSessionEndpoint()
|
||||
if endpoint == "" {
|
||||
return nil, fmt.Errorf("end session %w", ErrEndpointNotSet)
|
||||
}
|
||||
|
||||
req, err := httphelper.FormRequest(ctx, endpoint, request, Encoder, authFn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -143,7 +148,12 @@ func CallRevokeEndpoint(ctx context.Context, request any, authFn any, caller Rev
|
|||
ctx, span := Tracer.Start(ctx, "CallRevokeEndpoint")
|
||||
defer span.End()
|
||||
|
||||
req, err := httphelper.FormRequest(ctx, caller.GetRevokeEndpoint(), request, Encoder, authFn)
|
||||
endpoint := caller.GetRevokeEndpoint()
|
||||
if endpoint == "" {
|
||||
return fmt.Errorf("revoke %w", ErrEndpointNotSet)
|
||||
}
|
||||
|
||||
req, err := httphelper.FormRequest(ctx, endpoint, request, Encoder, authFn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -218,7 +228,12 @@ func CallDeviceAuthorizationEndpoint(ctx context.Context, request *oidc.ClientCr
|
|||
ctx, span := Tracer.Start(ctx, "CallDeviceAuthorizationEndpoint")
|
||||
defer span.End()
|
||||
|
||||
req, err := httphelper.FormRequest(ctx, caller.GetDeviceAuthorizationEndpoint(), request, Encoder, authFn)
|
||||
endpoint := caller.GetDeviceAuthorizationEndpoint()
|
||||
if endpoint == "" {
|
||||
return nil, fmt.Errorf("device authorization %w", ErrEndpointNotSet)
|
||||
}
|
||||
|
||||
req, err := httphelper.FormRequest(ctx, endpoint, request, Encoder, authFn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
5
pkg/client/errors.go
Normal file
5
pkg/client/errors.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package client
|
||||
|
||||
import "errors"
|
||||
|
||||
var ErrEndpointNotSet = errors.New("endpoint not set")
|
|
@ -5,7 +5,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/zitadel/oidc/v3/pkg/client"
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"net/http"
|
||||
"sync"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
"github.com/zitadel/oidc/v3/pkg/client"
|
||||
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/clientcredentials"
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
"github.com/zitadel/oidc/v3/pkg/client"
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
tu "github.com/zitadel/oidc/v3/internal/testutil"
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/zitadel/oidc/v3/pkg/client"
|
||||
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"fmt"
|
||||
"hash"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
var ErrUnsupportedAlgorithm = errors.New("unsupported signing algorithm")
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
func Sign(object any, signer jose.Signer) (string, error) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package oidc
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// DeviceAuthorizationRequest implements
|
||||
// https://www.rfc-editor.org/rfc/rfc8628#section-3.1,
|
||||
// 3.1 Device Authorization Request.
|
||||
|
@ -20,6 +22,26 @@ type DeviceAuthorizationResponse struct {
|
|||
Interval int `json:"interval,omitempty"`
|
||||
}
|
||||
|
||||
func (resp *DeviceAuthorizationResponse) UnmarshalJSON(data []byte) error {
|
||||
type Alias DeviceAuthorizationResponse
|
||||
aux := &struct {
|
||||
// workaround misspelling of verification_uri
|
||||
// https://stackoverflow.com/q/76696956/5690223
|
||||
// https://developers.google.com/identity/protocols/oauth2/limited-input-device?hl=fr#success-response
|
||||
VerificationURL string `json:"verification_url"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(resp),
|
||||
}
|
||||
if err := json.Unmarshal(data, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.VerificationURI == "" {
|
||||
resp.VerificationURI = aux.VerificationURL
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeviceAccessTokenRequest implements
|
||||
// https://www.rfc-editor.org/rfc/rfc8628#section-3.4,
|
||||
// Device Access Token Request.
|
||||
|
|
30
pkg/oidc/device_authorization_test.go
Normal file
30
pkg/oidc/device_authorization_test.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package oidc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDeviceAuthorizationResponse_UnmarshalJSON(t *testing.T) {
|
||||
jsonStr := `{
|
||||
"device_code": "deviceCode",
|
||||
"user_code": "userCode",
|
||||
"verification_url": "http://example.com/verify",
|
||||
"expires_in": 3600,
|
||||
"interval": 5
|
||||
}`
|
||||
|
||||
expected := &DeviceAuthorizationResponse{
|
||||
DeviceCode: "deviceCode",
|
||||
UserCode: "userCode",
|
||||
VerificationURI: "http://example.com/verify",
|
||||
ExpiresIn: 3600,
|
||||
Interval: 5,
|
||||
}
|
||||
|
||||
var resp DeviceAuthorizationResponse
|
||||
err := resp.UnmarshalJSON([]byte(jsonStr))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, &resp)
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
"crypto/rsa"
|
||||
"errors"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
func TestFindKey(t *testing.T) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"slices"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/zitadel/schema"
|
||||
"golang.org/x/text/language"
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
str "github.com/zitadel/oidc/v3/pkg/strings"
|
||||
)
|
||||
|
@ -148,8 +148,13 @@ func CheckAuthorizedParty(claims Claims, clientID string) error {
|
|||
}
|
||||
|
||||
func CheckSignature(ctx context.Context, token string, payload []byte, claims ClaimsSignature, supportedSigAlgs []string, set KeySet) error {
|
||||
jws, err := jose.ParseSigned(token)
|
||||
jws, err := jose.ParseSigned(token, toJoseSignatureAlgorithms(supportedSigAlgs))
|
||||
if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "go-jose/go-jose: unexpected signature algorithm") {
|
||||
// TODO(v4): we should wrap errors instead of returning static ones.
|
||||
// This is a workaround so we keep returning the same error for now.
|
||||
return ErrSignatureUnsupportedAlg
|
||||
}
|
||||
return ErrParse
|
||||
}
|
||||
if len(jws.Signatures) == 0 {
|
||||
|
@ -159,12 +164,6 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl
|
|||
return ErrSignatureMultiple
|
||||
}
|
||||
sig := jws.Signatures[0]
|
||||
if len(supportedSigAlgs) == 0 {
|
||||
supportedSigAlgs = []string{"RS256"}
|
||||
}
|
||||
if !str.Contains(supportedSigAlgs, sig.Header.Algorithm) {
|
||||
return fmt.Errorf("%w: id token signed with unsupported algorithm, expected %q got %q", ErrSignatureUnsupportedAlg, supportedSigAlgs, sig.Header.Algorithm)
|
||||
}
|
||||
|
||||
signedPayload, err := set.VerifySignature(ctx, jws)
|
||||
if err != nil {
|
||||
|
@ -180,6 +179,18 @@ func CheckSignature(ctx context.Context, token string, payload []byte, claims Cl
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO(v4): Use the new jose.SignatureAlgorithm type directly, instead of string.
|
||||
func toJoseSignatureAlgorithms(algorithms []string) []jose.SignatureAlgorithm {
|
||||
out := make([]jose.SignatureAlgorithm, len(algorithms))
|
||||
for i := range algorithms {
|
||||
out[i] = jose.SignatureAlgorithm(algorithms[i])
|
||||
}
|
||||
if len(out) == 0 {
|
||||
out = append(out, jose.RS256)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func CheckExpiration(claims Claims, offset time.Duration) error {
|
||||
expiration := claims.GetExpiration()
|
||||
if !time.Now().Add(offset).Before(expiration) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"net/http"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"net/http"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/zitadel/schema"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ package mock
|
|||
import (
|
||||
reflect "reflect"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
oidc "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
op "github.com/zitadel/oidc/v3/pkg/op"
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
"github.com/rs/cors"
|
||||
"github.com/zitadel/schema"
|
||||
"go.opentelemetry.io/otel"
|
||||
|
|
|
@ -3,7 +3,7 @@ package op
|
|||
import (
|
||||
"errors"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
)
|
||||
|
||||
var ErrSignerCreationFailed = errors.New("signer creation failed")
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
jose "github.com/go-jose/go-jose/v3"
|
||||
jose "github.com/go-jose/go-jose/v4"
|
||||
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue