mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-05-13 03:11:59 +00:00
Merge pull request #3077 from vmware/remove-github-pkg-errors
Remove direct dependency on github.com/pkg/errors and bump deps
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.26.2@sha256:b54cbf583d390341599d7bcbc062425c081105cc5ef6d170ced98ef9d047c716
|
||||
ARG BUILD_IMAGE=golang:1.26.3@sha256:8f7c3ac0e4e60fd71e5b66c3e6596079a6dcae1e7e8ebe3143c69de60325b0d1
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:e3f945647ffb95b5839c07038d64f9811adf17308b9121d8a2b87b6a22a80a39
|
||||
|
||||
# Prepare to cross-compile by always running the build stage in the build platform, not the target platform.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
#! Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
#! SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#@ load("@ytt:data", "data")
|
||||
@@ -142,7 +142,7 @@ rules:
|
||||
resources: [ apiservices ]
|
||||
verbs: [ get, list, patch, update, watch ]
|
||||
- apiGroups: [ admissionregistration.k8s.io ]
|
||||
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations, validatingadmissionpolicies, validatingadmissionpolicybindings ]
|
||||
resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations, validatingadmissionpolicies, validatingadmissionpolicybindings, mutatingadmissionpolicies, mutatingadmissionpolicybindings ]
|
||||
verbs: [ get, list, watch ]
|
||||
- apiGroups: [ flowcontrol.apiserver.k8s.io ]
|
||||
resources: [ flowschemas, prioritylevelconfigurations ]
|
||||
|
||||
6
go.mod
6
go.mod
@@ -30,7 +30,6 @@ require (
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||
github.com/ory/fosite v0.49.1-0.20250703093431-a5f0b09bf31c
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sclevine/spec v1.4.0
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/pflag v1.0.10
|
||||
@@ -55,13 +54,13 @@ require (
|
||||
k8s.io/kube-aggregator v0.36.0
|
||||
k8s.io/kube-openapi v0.0.0-20260505163821-33341827b392
|
||||
k8s.io/streaming v0.36.0
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5
|
||||
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2
|
||||
sigs.k8s.io/yaml v1.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.1.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.1.1 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
@@ -127,6 +126,7 @@ require (
|
||||
github.com/ory/go-convenience v0.1.0 // indirect
|
||||
github.com/ory/x v0.0.677 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/pquerna/cachecontrol v0.1.0 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
|
||||
8
go.sum
8
go.sum
@@ -38,8 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-ntlmssp v0.1.0 h1:DjFo6YtWzNqNvQdrwEyr/e4nhU3vRiwenz5QX7sFz+A=
|
||||
github.com/Azure/go-ntlmssp v0.1.0/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk=
|
||||
github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw=
|
||||
github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
|
||||
@@ -1112,8 +1112,8 @@ k8s.io/kube-openapi v0.0.0-20260505163821-33341827b392 h1:B7Ylb1OUptHKVX/3kpvXB0
|
||||
k8s.io/kube-openapi v0.0.0-20260505163821-33341827b392/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY=
|
||||
k8s.io/streaming v0.36.0 h1:agnTxU+NFulUrtYzXUGKO3ndEa8jKwht1Kwn9nu9x+4=
|
||||
k8s.io/streaming v0.36.0/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s=
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM=
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc=
|
||||
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# See https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md
|
||||
# and https://kupczynski.info/posts/fips-golang/ for details.
|
||||
|
||||
ARG BUILD_IMAGE=golang:1.26.2@sha256:b54cbf583d390341599d7bcbc062425c081105cc5ef6d170ced98ef9d047c716
|
||||
ARG BUILD_IMAGE=golang:1.26.3@sha256:8f7c3ac0e4e60fd71e5b66c3e6596079a6dcae1e7e8ebe3143c69de60325b0d1
|
||||
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:e3f945647ffb95b5839c07038d64f9811adf17308b9121d8a2b87b6a22a80a39
|
||||
|
||||
# This is not currently using --platform to prepare to cross-compile because we use gcc below to build
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -euo pipefail
|
||||
@@ -46,16 +46,10 @@ function main() {
|
||||
./hack/module.sh lint
|
||||
;;
|
||||
'unittest' | 'unittests' | 'units' | 'unit')
|
||||
# Temporarily avoid using the race detector for the impersonator package due to https://github.com/kubernetes/kubernetes/issues/128548
|
||||
KUBE_CACHE_MUTATION_DETECTOR=${kube_cache_mutation_detector} \
|
||||
KUBE_PANIC_WATCH_DECODE_ERROR=${kube_panic_watch_decode_error} \
|
||||
CGO_ENABLED=0 \
|
||||
go test -short -race $(go list ./... | grep -v internal/concierge/impersonator)
|
||||
# TODO: change this back to using the race detector everywhere
|
||||
KUBE_CACHE_MUTATION_DETECTOR=${kube_cache_mutation_detector} \
|
||||
KUBE_PANIC_WATCH_DECODE_ERROR=${kube_panic_watch_decode_error} \
|
||||
CGO_ENABLED=0 \
|
||||
go test -short ./internal/concierge/impersonator
|
||||
go test -short -race ./...
|
||||
;;
|
||||
'generate')
|
||||
go generate ./internal/mocks/...
|
||||
|
||||
@@ -2,4 +2,4 @@ module go.pinniped.dev/update-go-mod
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require golang.org/x/mod v0.34.0
|
||||
require golang.org/x/mod v0.35.0
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
|
||||
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
package admissionpluginconfig
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
mutatingadmissionpolicy "k8s.io/apiserver/pkg/admission/plugin/policy/mutating"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package tlsconfigutil
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
@@ -201,7 +200,7 @@ func readCABundleFromK8sSecret(namespace string, name string, key string, secret
|
||||
|
||||
s, err := secretInformer.Lister().Secrets(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to get secret %q", namespacedName)
|
||||
return "", fmt.Errorf("failed to get secret %q: %w", namespacedName, err)
|
||||
}
|
||||
|
||||
// For Secrets to be used as a certificate authority data source, the secret should be of type
|
||||
@@ -225,7 +224,7 @@ func readCABundleFromK8sConfigMap(namespace string, name string, key string, con
|
||||
|
||||
c, err := configMapInformer.Lister().ConfigMaps(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to get configmap %q", namespacedName)
|
||||
return "", fmt.Errorf("failed to get configmap %q: %w", namespacedName, err)
|
||||
}
|
||||
|
||||
val, exists := c.Data[key]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package token provides a handler for the OIDC token endpoint.
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
errorsx "github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apiserver/pkg/warning"
|
||||
@@ -165,19 +164,19 @@ func upstreamRefresh(
|
||||
|
||||
customSessionData := session.Custom
|
||||
if customSessionData == nil {
|
||||
return errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
providerName := customSessionData.ProviderName
|
||||
providerType := customSessionData.ProviderType
|
||||
providerUID := customSessionData.ProviderUID
|
||||
if providerUID == "" || providerName == "" {
|
||||
return errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
skipGroups := !slices.Contains(accessRequest.GetGrantedScopes(), oidcapi.ScopeGroups)
|
||||
|
||||
if session.IDTokenClaims().AuthTime.IsZero() {
|
||||
return errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
err := validateSessionHasUsername(session)
|
||||
@@ -201,7 +200,7 @@ func upstreamRefresh(
|
||||
|
||||
cloneOfIDPSpecificSessionData := idp.CloneIDPSpecificSessionDataFromSession(session.Custom)
|
||||
if cloneOfIDPSpecificSessionData == nil {
|
||||
return errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
oldUntransformedUsername := session.Custom.UpstreamUsername
|
||||
@@ -299,21 +298,21 @@ func findProviderByNameAndType(
|
||||
for _, p := range idpLister.GetIdentityProviders() {
|
||||
if p.GetSessionProviderType() == providerType && p.GetProvider().GetResourceName() == providerResourceName {
|
||||
if p.GetProvider().GetResourceUID() != mustHaveResourceUID {
|
||||
return nil, errorsx.WithStack(errUpstreamRefreshError().WithHint(
|
||||
"Provider from upstream session data has changed its resource UID since authentication."))
|
||||
return nil, errUpstreamRefreshError().WithHint(
|
||||
"Provider from upstream session data has changed its resource UID since authentication.")
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
return nil, errorsx.WithStack(errUpstreamRefreshError().
|
||||
return nil, errUpstreamRefreshError().
|
||||
WithHint("Provider from upstream session data was not found.").
|
||||
WithDebugf("provider name: %q, provider type: %q", providerResourceName, providerType))
|
||||
WithDebugf("provider name: %q, provider type: %q", providerResourceName, providerType)
|
||||
}
|
||||
|
||||
func validateSessionHasUsername(session *psession.PinnipedSession) error {
|
||||
downstreamUsername := session.Custom.Username
|
||||
if len(downstreamUsername) == 0 {
|
||||
return errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -348,22 +347,22 @@ func applyIdentityTransformationsDuringRefresh(
|
||||
func validateAndGetDownstreamGroupsFromSession(session *psession.PinnipedSession) ([]string, error) {
|
||||
extra := session.Fosite.Claims.Extra
|
||||
if extra == nil {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return nil, errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
downstreamGroupsInterface := extra[oidcapi.IDTokenClaimGroups]
|
||||
if downstreamGroupsInterface == nil {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return nil, errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
downstreamGroupsInterfaceList, ok := downstreamGroupsInterface.([]any)
|
||||
if !ok {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return nil, errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
downstreamGroups := make([]string, 0, len(downstreamGroupsInterfaceList))
|
||||
for _, downstreamGroupInterface := range downstreamGroupsInterfaceList {
|
||||
downstreamGroup, ok := downstreamGroupInterface.(string)
|
||||
if !ok || len(downstreamGroup) == 0 {
|
||||
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
|
||||
return nil, errMissingUpstreamSessionInternalError()
|
||||
}
|
||||
downstreamGroups = append(downstreamGroups, downstreamGroup)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -30,7 +31,6 @@ import (
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
fositepkce "github.com/ory/fosite/handler/pkce"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package tokenexchange
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/ory/fosite"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
||||
"go.pinniped.dev/internal/psession"
|
||||
@@ -48,44 +47,44 @@ var _ fosite.TokenEndpointHandler = (*tokenExchangeHandler)(nil)
|
||||
func (t *tokenExchangeHandler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error {
|
||||
// Skip this request if it's for a different grant type.
|
||||
if !t.CanHandleTokenEndpointRequest(ctx, requester) {
|
||||
return errors.WithStack(fosite.ErrUnknownRequest)
|
||||
return fosite.ErrUnknownRequest
|
||||
}
|
||||
|
||||
// Validate the basic RFC8693 parameters we support.
|
||||
params, err := t.validateParams(requester.GetRequestForm())
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate the incoming access token and lookup the information about the original authorize request from storage.
|
||||
originalRequester, err := t.validateAccessToken(ctx, requester, params.subjectAccessToken)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Check that the currently authenticated client and the client which was originally used to get the access token are the same.
|
||||
if originalRequester.GetClient().GetID() != requester.GetClient().GetID() {
|
||||
// This error message is copied from the similar check in fosite's flow_authorize_code_token.go.
|
||||
return errors.WithStack(fosite.ErrInvalidGrant.WithHint("The OAuth 2.0 Client ID from this request does not match the one from the authorize request."))
|
||||
return fosite.ErrInvalidGrant.WithHint("The OAuth 2.0 Client ID from this request does not match the one from the authorize request.")
|
||||
}
|
||||
|
||||
// Check that the client is allowed to perform this grant type.
|
||||
if !requester.GetClient().GetGrantTypes().Has(oidcapi.GrantTypeTokenExchange) {
|
||||
// This error message is trying to be similar to the analogous one in fosite's flow_authorize_code_token.go.
|
||||
return errors.WithStack(fosite.ErrUnauthorizedClient.WithHintf(`The OAuth 2.0 Client is not allowed to use token exchange grant "%s".`, oidcapi.GrantTypeTokenExchange))
|
||||
return fosite.ErrUnauthorizedClient.WithHintf(`The OAuth 2.0 Client is not allowed to use token exchange grant "%s".`, oidcapi.GrantTypeTokenExchange)
|
||||
}
|
||||
|
||||
// Require that the incoming access token has the pinniped:request-audience and OpenID scopes.
|
||||
if !originalRequester.GetGrantedScopes().Has(oidcapi.ScopeRequestAudience) {
|
||||
return errors.WithStack(fosite.ErrAccessDenied.WithHintf("Missing the %q scope.", oidcapi.ScopeRequestAudience))
|
||||
return fosite.ErrAccessDenied.WithHintf("Missing the %q scope.", oidcapi.ScopeRequestAudience)
|
||||
}
|
||||
if !originalRequester.GetGrantedScopes().Has(oidcapi.ScopeOpenID) {
|
||||
return errors.WithStack(fosite.ErrAccessDenied.WithHintf("Missing the %q scope.", oidcapi.ScopeOpenID))
|
||||
return fosite.ErrAccessDenied.WithHintf("Missing the %q scope.", oidcapi.ScopeOpenID)
|
||||
}
|
||||
|
||||
// Check that the stored session meets the minimum requirements for token exchange.
|
||||
if err := t.validateSession(originalRequester); err != nil {
|
||||
return errors.WithStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy the original session ID from storage.
|
||||
@@ -102,7 +101,7 @@ func (t *tokenExchangeHandler) HandleTokenEndpointRequest(ctx context.Context, r
|
||||
func (t *tokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) error {
|
||||
// Skip this request if it's for a different grant type.
|
||||
if !t.CanHandleTokenEndpointRequest(ctx, requester) {
|
||||
return errors.WithStack(fosite.ErrUnknownRequest)
|
||||
return fosite.ErrUnknownRequest
|
||||
}
|
||||
|
||||
// Get the requested audience parameter again, which was already validated by HandleTokenEndpointRequest() above.
|
||||
@@ -111,7 +110,7 @@ func (t *tokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context
|
||||
// Use the original authorize request information, along with the requested audience, to mint a new JWT.
|
||||
responseToken, err := t.mintJWT(ctx, requester, requestedNewAudience)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Format the response parameters according to RFC8693.
|
||||
@@ -212,7 +211,7 @@ func (t *tokenExchangeHandler) validateAccessToken(ctx context.Context, requeste
|
||||
}
|
||||
// Validate the access token using its stored session data, which includes its expiration time.
|
||||
if err := t.accessTokenStrategy.ValidateAccessToken(ctx, originalRequester, accessToken); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
return nil, err
|
||||
}
|
||||
return originalRequester, nil
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package oidc contains common OIDC functionality needed by FederationDomains to implement
|
||||
@@ -8,7 +8,6 @@ package oidc
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
@@ -16,7 +15,6 @@ import (
|
||||
"github.com/felixge/httpsnoop"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
errorsx "github.com/pkg/errors"
|
||||
|
||||
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
|
||||
"go.pinniped.dev/internal/federationdomain/clientregistry"
|
||||
@@ -402,18 +400,7 @@ func validateCSRFValue(state *UpstreamStateParamData, csrfCookieValue csrftoken.
|
||||
// WriteAuthorizeError writes an authorization error as it should be returned by the authorization endpoint and other
|
||||
// similar endpoints that are the end of the downstream authcode flow. Errors responses are written in the usual fosite style.
|
||||
func WriteAuthorizeError(r *http.Request, w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, authorizeRequester fosite.AuthorizeRequester, err error, isBrowserless bool) {
|
||||
if plog.Enabled(plog.LevelTrace) {
|
||||
// When trace level logging is enabled, include the stack trace in the log message.
|
||||
keysAndValues := FositeErrorForLog(err)
|
||||
errWithStack := errorsx.WithStack(err)
|
||||
keysAndValues = append(keysAndValues, "errWithStack")
|
||||
// klog always prints error values using %s, which does not include stack traces,
|
||||
// so convert the error to a string which includes the stack trace here.
|
||||
keysAndValues = append(keysAndValues, fmt.Sprintf("%+v", errWithStack))
|
||||
plog.Trace("authorize response error", keysAndValues...)
|
||||
} else {
|
||||
plog.Info("authorize response error", FositeErrorForLog(err)...)
|
||||
}
|
||||
plog.Info("authorize response error", FositeErrorForLog(err)...)
|
||||
if isBrowserless {
|
||||
w = rewriteStatusSeeOtherToStatusFoundForBrowserless(w)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2024-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package resolvedldap
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
errorsx "github.com/pkg/errors"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||
"go.pinniped.dev/internal/authenticators"
|
||||
@@ -193,7 +192,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) UpstreamRefresh(
|
||||
sessionData, ok := identity.IDPSpecificSessionData.(*psession.LDAPSessionData)
|
||||
if !ok {
|
||||
// This shouldn't really happen.
|
||||
return nil, errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return nil, resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
dn = sessionData.UserDN
|
||||
additionalAttributes = sessionData.ExtraRefreshAttributes
|
||||
@@ -201,7 +200,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) UpstreamRefresh(
|
||||
sessionData, ok := identity.IDPSpecificSessionData.(*psession.ActiveDirectorySessionData)
|
||||
if !ok {
|
||||
// This shouldn't really happen.
|
||||
return nil, errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return nil, resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
dn = sessionData.UserDN
|
||||
additionalAttributes = sessionData.ExtraRefreshAttributes
|
||||
@@ -215,7 +214,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) UpstreamRefresh(
|
||||
}
|
||||
|
||||
if dn == "" {
|
||||
return nil, errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return nil, resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
plog.Debug("attempting upstream refresh request",
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
errorsx "github.com/pkg/errors"
|
||||
"golang.org/x/oauth2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -228,7 +227,7 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) UpstreamRefresh(
|
||||
sessionData, ok := identity.IDPSpecificSessionData.(*psession.OIDCSessionData)
|
||||
if !ok {
|
||||
// This shouldn't really happen.
|
||||
return nil, errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return nil, resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
accessTokenStored := sessionData.UpstreamAccessToken != ""
|
||||
@@ -237,7 +236,7 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) UpstreamRefresh(
|
||||
//nolint:staticcheck // De Morgan's doesn't make this more readable
|
||||
exactlyOneTokenStored := (accessTokenStored || refreshTokenStored) && !(accessTokenStored && refreshTokenStored)
|
||||
if !exactlyOneTokenStored {
|
||||
return nil, errorsx.WithStack(resolvedprovider.ErrMissingUpstreamSessionInternalError())
|
||||
return nil, resolvedprovider.ErrMissingUpstreamSessionInternalError()
|
||||
}
|
||||
|
||||
plog.Debug("attempting upstream refresh request",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package strategy
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/compose"
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
errorsx "github.com/pkg/errors"
|
||||
|
||||
"go.pinniped.dev/internal/federationdomain/storage"
|
||||
)
|
||||
@@ -72,8 +71,7 @@ func (s *DynamicOauth2HMACStrategy) GenerateAccessToken(
|
||||
if err == nil {
|
||||
if !strings.HasPrefix(token, oryAccessTokenPrefix) {
|
||||
// This would only happen if fosite changed how it generates tokens. Defensive programming here.
|
||||
return "", "", errorsx.WithStack(fosite.ErrInvalidTokenFormat.
|
||||
WithDebugf("Generated token does not have expected prefix"))
|
||||
return "", "", fosite.ErrInvalidTokenFormat.WithDebugf("Generated token does not have expected prefix")
|
||||
}
|
||||
token = replacePrefix(token, oryAccessTokenPrefix, pinAccessTokenPrefix)
|
||||
}
|
||||
@@ -86,8 +84,7 @@ func (s *DynamicOauth2HMACStrategy) ValidateAccessToken(
|
||||
token string,
|
||||
) error {
|
||||
if !strings.HasPrefix(token, pinAccessTokenPrefix) {
|
||||
return errorsx.WithStack(fosite.ErrInvalidTokenFormat.
|
||||
WithDebugf("Access token did not have prefix %q", pinAccessTokenPrefix))
|
||||
return fosite.ErrInvalidTokenFormat.WithDebugf("Access token did not have prefix %q", pinAccessTokenPrefix)
|
||||
}
|
||||
return s.delegate().ValidateAccessToken(ctx, requester, replacePrefix(token, pinAccessTokenPrefix, oryAccessTokenPrefix))
|
||||
}
|
||||
@@ -104,8 +101,7 @@ func (s *DynamicOauth2HMACStrategy) GenerateRefreshToken(
|
||||
if err == nil {
|
||||
if !strings.HasPrefix(token, oryRefreshTokenPrefix) {
|
||||
// This would only happen if fosite changed how it generates tokens. Defensive programming here.
|
||||
return "", "", errorsx.WithStack(fosite.ErrInvalidTokenFormat.
|
||||
WithDebugf("Generated token does not have expected prefix"))
|
||||
return "", "", fosite.ErrInvalidTokenFormat.WithDebugf("Generated token does not have expected prefix")
|
||||
}
|
||||
token = replacePrefix(token, oryRefreshTokenPrefix, pinRefreshTokenPrefix)
|
||||
}
|
||||
@@ -118,8 +114,7 @@ func (s *DynamicOauth2HMACStrategy) ValidateRefreshToken(
|
||||
token string,
|
||||
) error {
|
||||
if !strings.HasPrefix(token, pinRefreshTokenPrefix) {
|
||||
return errorsx.WithStack(fosite.ErrInvalidTokenFormat.
|
||||
WithDebugf("Refresh token did not have prefix %q", pinRefreshTokenPrefix))
|
||||
return fosite.ErrInvalidTokenFormat.WithDebugf("Refresh token did not have prefix %q", pinRefreshTokenPrefix)
|
||||
}
|
||||
return s.delegate().ValidateRefreshToken(ctx, requester, replacePrefix(token, pinRefreshTokenPrefix, oryRefreshTokenPrefix))
|
||||
}
|
||||
@@ -136,8 +131,7 @@ func (s *DynamicOauth2HMACStrategy) GenerateAuthorizeCode(
|
||||
if err == nil {
|
||||
if !strings.HasPrefix(authcode, oryAuthcodePrefix) {
|
||||
// This would only happen if fosite changed how it generates tokens. Defensive programming here.
|
||||
return "", "", errorsx.WithStack(fosite.ErrInvalidTokenFormat.
|
||||
WithDebugf("Generated token does not have expected prefix"))
|
||||
return "", "", fosite.ErrInvalidTokenFormat.WithDebugf("Generated token does not have expected prefix")
|
||||
}
|
||||
authcode = replacePrefix(authcode, oryAuthcodePrefix, pinAuthcodePrefix)
|
||||
}
|
||||
@@ -150,8 +144,7 @@ func (s *DynamicOauth2HMACStrategy) ValidateAuthorizeCode(
|
||||
token string,
|
||||
) error {
|
||||
if !strings.HasPrefix(token, pinAuthcodePrefix) {
|
||||
return errorsx.WithStack(fosite.ErrInvalidTokenFormat.
|
||||
WithDebugf("Authorization code did not have prefix %q", pinAuthcodePrefix))
|
||||
return fosite.ErrInvalidTokenFormat.WithDebugf("Authorization code did not have prefix %q", pinAuthcodePrefix)
|
||||
}
|
||||
return s.delegate().ValidateAuthorizeCode(ctx, requester, replacePrefix(token, pinAuthcodePrefix, oryAuthcodePrefix))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package accesstoken
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"crypto/ed25519"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
@@ -21,7 +22,6 @@ import (
|
||||
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package openidconnect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pkce
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/pkce"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -5,6 +5,7 @@ package refreshtoken
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
fositejwt "github.com/ory/fosite/token/jwt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2023-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package tokenclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
@@ -122,7 +123,7 @@ func (tc TokenClient) fetchToken(ctx context.Context) (token string, ttl time.Du
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return "", 0, errors.Wrap(err, "error creating token")
|
||||
return "", 0, fmt.Errorf("error creating token: %w", err)
|
||||
}
|
||||
|
||||
if tokenResponse == nil {
|
||||
|
||||
@@ -589,11 +589,8 @@ func TestImpersonationProxy(t *testing.T) { //nolint:gocyclo // yeah, it's compl
|
||||
_, err = nestedImpersonationClient.Kubernetes.CoreV1().Secrets(env.ConciergeNamespace).Get(ctx, impersonationProxyTLSSecretName(env), metav1.GetOptions{})
|
||||
// this user is not allowed to impersonate other users
|
||||
require.True(t, apierrors.IsForbidden(err), err)
|
||||
require.EqualError(t, err, fmt.Sprintf(
|
||||
`secrets "%s" is forbidden: `+
|
||||
`User "%s" cannot impersonate-on:user-info:get resource "secrets" in API group "" in the namespace "%s": `+
|
||||
`decision made by impersonation-proxy.concierge.pinniped.dev`,
|
||||
impersonationProxyTLSSecretName(env), env.TestUser.ExpectedUsername, env.ConciergeNamespace))
|
||||
require.Contains(t, err.Error(), fmt.Sprintf(`is forbidden: User "%s" cannot impersonate`, env.TestUser.ExpectedUsername))
|
||||
require.Contains(t, err.Error(), `decision made by impersonation-proxy.concierge.pinniped.dev`)
|
||||
|
||||
// impersonate the GC service account instead which can read anything (the binding to edit allows this)
|
||||
nestedImpersonationClientAsSA, credentialsAsSA := newImpersonationProxyClient(t, impersonationProxyURL, impersonationProxyCACertPEM,
|
||||
|
||||
Reference in New Issue
Block a user