Enable 'makezero' and 'prealloc' linters, and require 'any' instead of 'interface{}'

Enforce importas:

- go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1
- go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1
This commit is contained in:
Joshua Casey
2024-05-21 09:31:15 -05:00
parent bbe10004b4
commit f5116cddb4
98 changed files with 1889 additions and 1869 deletions
+19
View File
@@ -49,6 +49,9 @@ linters:
# - canonicalheader Can't do this one since it alerts on valid headers such as X-XSS-Protection
- spancheck
- importas
- makezero
- prealloc
- gofmt
issues:
exclude-dirs:
@@ -116,6 +119,22 @@ linters-settings:
alias: authenticationv1alpha1
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/clientsecret/v1alpha1
alias: clientsecretv1alpha1
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1
alias: supervisorconfigv1alpha1
- pkg: go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1
alias: idpv1alpha1
# Pinniped internal
- pkg: go.pinniped.dev/internal/concierge/scheme
alias: conciergescheme
gofmt:
# Simplify code: gofmt with `-s` option.
# Default: true
simplify: false
# Apply the rewrite rules to the source before reformatting.
# https://pkg.go.dev/cmd/gofmt
# Default: []
rewrite-rules:
- pattern: 'interface{}'
replacement: 'any'
- pattern: 'a[b:len(a)]'
replacement: 'a[b:]'
@@ -94,7 +94,7 @@ func TestEntrypoint(t *testing.T) {
var logBuf bytes.Buffer
testLog := log.New(&logBuf, "", 0)
exited := "exiting via fatal"
fail = func(format string, v ...interface{}) {
fail = func(format string, v ...any) {
testLog.Printf(format, v...)
panic(exited)
}
+1 -1
View File
@@ -42,7 +42,7 @@ func TestEntrypoint(t *testing.T) {
var logBuf bytes.Buffer
testLog := log.New(&logBuf, "", 0)
exited := "exiting via fatal"
fail = func(err error, keysAndValues ...interface{}) {
fail = func(err error, keysAndValues ...any) {
testLog.Print(err)
if len(keysAndValues) > 0 {
testLog.Print(keysAndValues...)
+6 -6
View File
@@ -1,4 +1,4 @@
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package celtransformer is an implementation of upstream-to-downstream identity transformations
@@ -228,8 +228,8 @@ func (c *baseCompiledTransformation) evalProgram(ctx context.Context, username s
// Evaluation is thread-safe and side effect free. Many inputs can be sent to the same cel.Program
// and if fields are present in the input, but not referenced in the expression, they are ignored.
// The argument to Eval may either be an `interpreter.Activation` or a `map[string]interface{}`.
val, _, err := c.program.ContextEval(timeoutCtx, map[string]interface{}{
// The argument to Eval may either be an `interpreter.Activation` or a `map[string]any`.
val, _, err := c.program.ContextEval(timeoutCtx, map[string]any{
usernameVariableName: username,
groupsVariableName: groups,
constStringVariableName: c.consts.StringConstants,
@@ -311,15 +311,15 @@ type CELTransformationSource struct {
Consts *TransformationConstants
}
func (c *compiledUsernameTransformation) Source() interface{} {
func (c *compiledUsernameTransformation) Source() any {
return &CELTransformationSource{Expr: c.sourceExpr, Consts: c.consts}
}
func (c *compiledGroupsTransformation) Source() interface{} {
func (c *compiledGroupsTransformation) Source() any {
return &CELTransformationSource{Expr: c.sourceExpr, Consts: c.consts}
}
func (c *compiledAllowAuthenticationPolicy) Source() interface{} {
func (c *compiledAllowAuthenticationPolicy) Source() any {
return &CELTransformationSource{Expr: c.sourceExpr, Consts: c.consts}
}
+1 -1
View File
@@ -787,7 +787,7 @@ func TestTransformer(t *testing.T) {
require.NoError(t, err)
pipeline := idtransform.NewTransformationPipeline()
expectedPipelineSource := []interface{}{}
expectedPipelineSource := []any{}
for _, transform := range tt.transforms {
compiledTransform, err := transformer.CompileTransformation(transform, tt.consts)
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package scheme contains code to construct a proper runtime.Scheme for the Concierge aggregated
@@ -75,7 +75,7 @@ func New(apiGroupSuffix string) (_ *runtime.Scheme, login, identity schema.Group
// on incoming requests, restore the authenticator API group to the standard group
// note that we are responsible for duplicating this logic for every external API version
scheme.AddTypeDefaultingFunc(&loginv1alpha1.TokenCredentialRequest{}, func(obj interface{}) {
scheme.AddTypeDefaultingFunc(&loginv1alpha1.TokenCredentialRequest{}, func(obj any) {
credentialRequest := obj.(*loginv1alpha1.TokenCredentialRequest)
if credentialRequest.Spec.Authenticator.APIGroup == nil {
@@ -1,4 +1,4 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package authncache implements a cache of active authenticators.
@@ -65,7 +65,7 @@ func (c *Cache) Delete(key Key) {
// Keys currently stored in the cache.
func (c *Cache) Keys() []Key {
var result []Key
c.cache.Range(func(key, _ interface{}) bool {
c.cache.Range(func(key, _ any) bool {
result = append(result, key.(Key))
return true
})
@@ -184,7 +184,7 @@ func TestAuthenticateTokenCredentialRequest(t *testing.T) {
type audienceFreeContext struct{}
func (audienceFreeContext) Matches(in interface{}) bool {
func (audienceFreeContext) Matches(in any) bool {
ctx, isCtx := in.(context.Context)
if !isCtx {
return false
@@ -141,8 +141,8 @@ func TestController(t *testing.T) {
builder := jwt.Signed(sig).Claims(claimsWithoutSubject)
builder = builder.Claims(map[string]interface{}{customGroupsClaim: distributedGroups})
builder = builder.Claims(map[string]interface{}{"groups": distributedGroups})
builder = builder.Claims(map[string]any{customGroupsClaim: distributedGroups})
builder = builder.Claims(map[string]any{"groups": distributedGroups})
distributedClaimsJwt, err := builder.CompactSerialize()
require.NoError(t, err)
@@ -162,7 +162,7 @@ func TestController(t *testing.T) {
builder := jwt.Signed(sig).Claims(claimsWithoutSubject)
builder = builder.Claims(map[string]interface{}{"some-other-claim": distributedGroups})
builder = builder.Claims(map[string]any{"some-other-claim": distributedGroups})
distributedClaimsJwt, err := builder.CompactSerialize()
require.NoError(t, err)
@@ -634,7 +634,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -679,7 +679,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -727,7 +727,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -769,7 +769,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -812,7 +812,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -866,7 +866,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -919,7 +919,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "actual jwt authenticator and desired jwt authenticator are the same",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -965,7 +965,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -1530,7 +1530,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -1568,7 +1568,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -1648,7 +1648,7 @@ func TestController(t *testing.T) {
"logger": "jwtcachefiller-controller",
"message": "added new jwt authenticator",
"issuer": goodIssuer,
"jwtAuthenticator": map[string]interface{}{
"jwtAuthenticator": map[string]any{
"name": "test-name",
},
}},
@@ -1791,13 +1791,13 @@ func TestController(t *testing.T) {
NotBefore: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
}
var groups interface{}
var groups any
username := goodUsername
if test.jwtClaims != nil {
test.jwtClaims(&wellKnownClaims, &groups, &username)
}
var signingKey interface{} = goodECSigningKey
var signingKey any = goodECSigningKey
signingAlgo := goodECSigningAlgo
signingKID := goodECSigningKeyID
if test.jwtSignature != nil {
@@ -1860,8 +1860,8 @@ func testTableForAuthenticateTokenTests(
issuer string,
) []struct {
name string
jwtClaims func(wellKnownClaims *jwt.Claims, groups *interface{}, username *string)
jwtSignature func(key *interface{}, algo *jose.SignatureAlgorithm, kid *string)
jwtClaims func(wellKnownClaims *jwt.Claims, groups *any, username *string)
jwtSignature func(key *any, algo *jose.SignatureAlgorithm, kid *string)
wantResponse *authenticator.Response
wantAuthenticated bool
wantErr testutil.RequireErrorStringFunc
@@ -1869,8 +1869,8 @@ func testTableForAuthenticateTokenTests(
} {
tests := []struct {
name string
jwtClaims func(wellKnownClaims *jwt.Claims, groups *interface{}, username *string)
jwtSignature func(key *interface{}, algo *jose.SignatureAlgorithm, kid *string)
jwtClaims func(wellKnownClaims *jwt.Claims, groups *any, username *string)
jwtSignature func(key *any, algo *jose.SignatureAlgorithm, kid *string)
wantResponse *authenticator.Response
wantAuthenticated bool
wantErr testutil.RequireErrorStringFunc
@@ -1887,7 +1887,7 @@ func testTableForAuthenticateTokenTests(
},
{
name: "good token without groups and with RSA signature",
jwtSignature: func(key *interface{}, algo *jose.SignatureAlgorithm, kid *string) {
jwtSignature: func(key *any, algo *jose.SignatureAlgorithm, kid *string) {
*key = goodRSASigningKey
*algo = goodRSASigningAlgo
*kid = goodRSASigningKeyID
@@ -1901,7 +1901,7 @@ func testTableForAuthenticateTokenTests(
},
{
name: "good token with groups as array",
jwtClaims: func(_ *jwt.Claims, groups *interface{}, username *string) {
jwtClaims: func(_ *jwt.Claims, groups *any, username *string) {
*groups = []string{group0, group1}
},
wantResponse: &authenticator.Response{
@@ -1914,7 +1914,7 @@ func testTableForAuthenticateTokenTests(
},
{
name: "good token with good distributed groups",
jwtClaims: func(claims *jwt.Claims, groups *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, groups *any, username *string) {
},
distributedGroupsClaimURL: issuer + "/claim_source",
wantResponse: &authenticator.Response{
@@ -1927,21 +1927,21 @@ func testTableForAuthenticateTokenTests(
},
{
name: "distributed groups returns a 404",
jwtClaims: func(claims *jwt.Claims, groups *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, groups *any, username *string) {
},
distributedGroupsClaimURL: issuer + "/not_found_claim_source",
wantErr: testutil.WantMatchingErrorString(`oidc: could not expand distributed claims: while getting distributed claim "` + expectedGroupsClaim + `": error while getting distributed claim JWT: 404 Not Found`),
},
{
name: "distributed groups doesn't return the right claim",
jwtClaims: func(claims *jwt.Claims, groups *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, groups *any, username *string) {
},
distributedGroupsClaimURL: issuer + "/wrong_claim_source",
wantErr: testutil.WantMatchingErrorString(`oidc: could not expand distributed claims: jwt returned by distributed claim endpoint "` + issuer + `/wrong_claim_source" did not contain claim: `),
},
{
name: "good token with groups as string",
jwtClaims: func(_ *jwt.Claims, groups *interface{}, username *string) {
jwtClaims: func(_ *jwt.Claims, groups *any, username *string) {
*groups = group0
},
wantResponse: &authenticator.Response{
@@ -1954,7 +1954,7 @@ func testTableForAuthenticateTokenTests(
},
{
name: "good token with nbf unset",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.NotBefore = nil
},
wantResponse: &authenticator.Response{
@@ -1966,14 +1966,14 @@ func testTableForAuthenticateTokenTests(
},
{
name: "bad token with groups as map",
jwtClaims: func(_ *jwt.Claims, groups *interface{}, username *string) {
jwtClaims: func(_ *jwt.Claims, groups *any, username *string) {
*groups = map[string]string{"not an array": "or a string"}
},
wantErr: testutil.WantMatchingErrorString("oidc: parse groups claim \"" + expectedGroupsClaim + "\": json: cannot unmarshal object into Go value of type string"),
},
{
name: "bad token with wrong issuer",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.Issuer = "wrong-issuer"
},
wantResponse: nil,
@@ -1981,49 +1981,49 @@ func testTableForAuthenticateTokenTests(
},
{
name: "bad token with no audience",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.Audience = nil
},
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: expected audience "some-audience" got \[\]`),
},
{
name: "bad token with wrong audience",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.Audience = []string{"wrong-audience"}
},
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: expected audience "some-audience" got \["wrong-audience"\]`),
},
{
name: "bad token with nbf in the future",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.NotBefore = jwt.NewNumericDate(time.Date(3020, 2, 3, 4, 5, 6, 7, time.UTC))
},
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: current time .* before the nbf \(not before\) time: 3020-.*`),
},
{
name: "bad token with exp in past",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.Expiry = jwt.NewNumericDate(time.Date(1, 2, 3, 4, 5, 6, 7, time.UTC))
},
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: token is expired \(Token Expiry: .+`),
},
{
name: "bad token without exp",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
claims.Expiry = nil
},
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: token is expired \(Token Expiry: .+`),
},
{
name: "token does not have username claim",
jwtClaims: func(claims *jwt.Claims, _ *interface{}, username *string) {
jwtClaims: func(claims *jwt.Claims, _ *any, username *string) {
*username = ""
},
wantErr: testutil.WantMatchingErrorString(`oidc: parse username claims "` + expectedUsernameClaim + `": claim not present`),
},
{
name: "signing key is wrong",
jwtSignature: func(key *interface{}, algo *jose.SignatureAlgorithm, kid *string) {
jwtSignature: func(key *any, algo *jose.SignatureAlgorithm, kid *string) {
var err error
*key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
@@ -2033,7 +2033,7 @@ func testTableForAuthenticateTokenTests(
},
{
name: "signing algo is unsupported",
jwtSignature: func(key *interface{}, algo *jose.SignatureAlgorithm, kid *string) {
jwtSignature: func(key *any, algo *jose.SignatureAlgorithm, kid *string) {
var err error
*key, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
require.NoError(t, err)
@@ -2048,12 +2048,12 @@ func testTableForAuthenticateTokenTests(
func createJWT(
t *testing.T,
signingKey interface{},
signingKey any,
signingAlgo jose.SignatureAlgorithm,
kid string,
claims *jwt.Claims,
groupsClaim string,
groupsValue interface{},
groupsValue any,
distributedGroupsClaimURL string,
usernameClaim string,
usernameValue string,
@@ -2068,14 +2068,14 @@ func createJWT(
builder := jwt.Signed(sig).Claims(claims)
if groupsValue != nil {
builder = builder.Claims(map[string]interface{}{groupsClaim: groupsValue})
builder = builder.Claims(map[string]any{groupsClaim: groupsValue})
}
if distributedGroupsClaimURL != "" {
builder = builder.Claims(map[string]interface{}{"_claim_names": map[string]string{groupsClaim: "src1"}})
builder = builder.Claims(map[string]interface{}{"_claim_sources": map[string]interface{}{"src1": map[string]string{"endpoint": distributedGroupsClaimURL}}})
builder = builder.Claims(map[string]any{"_claim_names": map[string]string{groupsClaim: "src1"}})
builder = builder.Claims(map[string]any{"_claim_sources": map[string]any{"src1": map[string]string{"endpoint": distributedGroupsClaimURL}}})
}
if usernameValue != "" {
builder = builder.Claims(map[string]interface{}{usernameClaim: usernameValue})
builder = builder.Claims(map[string]any{usernameClaim: usernameValue})
}
jwt, err := builder.CompactSerialize()
require.NoError(t, err)
@@ -410,7 +410,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -452,7 +452,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -501,7 +501,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -551,7 +551,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": hostLocalIPv6Server.URL,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -859,7 +859,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpointBut404,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -912,7 +912,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": fmt.Sprintf("https://localhost:%s", localhostURL.Port()),
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -1050,7 +1050,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": hostAs127001WebhookServer.URL,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -1177,7 +1177,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -1217,7 +1217,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -1278,7 +1278,7 @@ func TestController(t *testing.T) {
"logger": "webhookcachefiller-controller",
"message": "added new webhook authenticator",
"endpoint": goodWebhookDefaultServingCertEndpoint,
"webhook": map[string]interface{}{
"webhook": map[string]any{
"name": "test-name",
},
},
@@ -715,7 +715,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
// If an object is added to the informer's client *before* the informer is started, then waiting is
// not needed because the informer's initial "list" will pick up the object.
var waitForObjectToAppearInInformer = func(obj kubeclient.Object, informer controllerlib.InformerGetter) {
var objFromInformer interface{}
var objFromInformer any
var exists bool
var err error
assert.Eventually(t, func() bool {
@@ -728,7 +728,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
}
var waitForClusterScopedObjectToAppearInInformer = func(obj kubeclient.Object, informer controllerlib.InformerGetter) {
var objFromInformer interface{}
var objFromInformer any
var exists bool
var err error
assert.Eventually(t, func() bool {
@@ -742,7 +742,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
// See comment for waitForObjectToAppearInInformer above.
var waitForObjectToBeDeletedFromInformer = func(resourceName string, informer controllerlib.InformerGetter) {
var objFromInformer interface{}
var objFromInformer any
var exists bool
var err error
assert.Eventually(t, func() bool {
@@ -19,7 +19,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedsupervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -74,7 +74,7 @@ const (
)
type activeDirectoryUpstreamGenericLDAPImpl struct {
activeDirectoryIdentityProvider v1alpha1.ActiveDirectoryIdentityProvider
activeDirectoryIdentityProvider idpv1alpha1.ActiveDirectoryIdentityProvider
}
func (g *activeDirectoryUpstreamGenericLDAPImpl) Spec() upstreamwatchers.UpstreamGenericLDAPSpec {
@@ -98,14 +98,14 @@ func (g *activeDirectoryUpstreamGenericLDAPImpl) Status() upstreamwatchers.Upstr
}
type activeDirectoryUpstreamGenericLDAPSpec struct {
activeDirectoryIdentityProvider v1alpha1.ActiveDirectoryIdentityProvider
activeDirectoryIdentityProvider idpv1alpha1.ActiveDirectoryIdentityProvider
}
func (s *activeDirectoryUpstreamGenericLDAPSpec) Host() string {
return s.activeDirectoryIdentityProvider.Spec.Host
}
func (s *activeDirectoryUpstreamGenericLDAPSpec) TLSSpec() *v1alpha1.TLSSpec {
func (s *activeDirectoryUpstreamGenericLDAPSpec) TLSSpec() *idpv1alpha1.TLSSpec {
return s.activeDirectoryIdentityProvider.Spec.TLS
}
@@ -161,7 +161,7 @@ func (s *activeDirectoryUpstreamGenericLDAPSpec) DetectAndSetSearchBase(ctx cont
}
type activeDirectoryUpstreamGenericLDAPUserSearch struct {
userSearch v1alpha1.ActiveDirectoryIdentityProviderUserSearch
userSearch idpv1alpha1.ActiveDirectoryIdentityProviderUserSearch
}
func (u *activeDirectoryUpstreamGenericLDAPUserSearch) Base() string {
@@ -190,7 +190,7 @@ func (u *activeDirectoryUpstreamGenericLDAPUserSearch) UIDAttribute() string {
}
type activeDirectoryUpstreamGenericLDAPGroupSearch struct {
groupSearch v1alpha1.ActiveDirectoryIdentityProviderGroupSearch
groupSearch idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearch
}
func (g *activeDirectoryUpstreamGenericLDAPGroupSearch) Base() string {
@@ -216,7 +216,7 @@ func (g *activeDirectoryUpstreamGenericLDAPGroupSearch) GroupNameAttribute() str
}
type activeDirectoryUpstreamGenericLDAPStatus struct {
activeDirectoryIdentityProvider v1alpha1.ActiveDirectoryIdentityProvider
activeDirectoryIdentityProvider idpv1alpha1.ActiveDirectoryIdentityProvider
}
func (s *activeDirectoryUpstreamGenericLDAPStatus) Conditions() []metav1.Condition {
@@ -318,7 +318,7 @@ func (c *activeDirectoryWatcherController) Sync(ctx controllerlib.Context) error
return nil
}
func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context, upstream *v1alpha1.ActiveDirectoryIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context, upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
spec := upstream.Spec
adUpstreamImpl := &activeDirectoryUpstreamGenericLDAPImpl{activeDirectoryIdentityProvider: *upstream}
@@ -364,15 +364,15 @@ func (c *activeDirectoryWatcherController) validateUpstream(ctx context.Context,
return upstreamwatchers.EvaluateConditions(conditions, config)
}
func (c *activeDirectoryWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.ActiveDirectoryIdentityProvider, conditions []*metav1.Condition) {
func (c *activeDirectoryWatcherController) updateStatus(ctx context.Context, upstream *idpv1alpha1.ActiveDirectoryIdentityProvider, conditions []*metav1.Condition) {
log := plog.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
hadErrorCondition := conditionsutil.MergeIDPConditions(conditions, upstream.Generation, &updated.Status.Conditions, log)
updated.Status.Phase = v1alpha1.ActiveDirectoryPhaseReady
updated.Status.Phase = idpv1alpha1.ActiveDirectoryPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.ActiveDirectoryPhaseError
updated.Status.Phase = idpv1alpha1.ActiveDirectoryPhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -22,7 +22,7 @@ import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
@@ -106,7 +106,7 @@ func TestActiveDirectoryUpstreamWatcherControllerFilterActiveDirectoryIdentityPr
}{
{
name: "any ActiveDirectoryIdentityProvider",
idp: &v1alpha1.ActiveDirectoryIdentityProvider{
idp: &idpv1alpha1.ActiveDirectoryIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
},
wantAdd: true,
@@ -176,32 +176,32 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
testCABundle := testCA.Bundle()
testCABundleBase64Encoded := base64.StdEncoding.EncodeToString(testCABundle)
validUpstream := &v1alpha1.ActiveDirectoryIdentityProvider{
validUpstream := &idpv1alpha1.ActiveDirectoryIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Name: testName, Namespace: testNamespace, Generation: 1234, UID: testResourceUID},
Spec: v1alpha1.ActiveDirectoryIdentityProviderSpec{
Spec: idpv1alpha1.ActiveDirectoryIdentityProviderSpec{
Host: testHost,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: v1alpha1.ActiveDirectoryIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: v1alpha1.ActiveDirectoryIdentityProviderUserSearch{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: idpv1alpha1.ActiveDirectoryIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: idpv1alpha1.ActiveDirectoryIdentityProviderUserSearch{
Base: testUserSearchBase,
Filter: testUserSearchFilter,
Attributes: v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{
Attributes: idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{
Username: testUserSearchUsernameAttrName,
UID: testUserSearchUIDAttrName,
},
},
GroupSearch: v1alpha1.ActiveDirectoryIdentityProviderGroupSearch{
GroupSearch: idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearch{
Base: testGroupSearchBase,
Filter: testGroupSearchFilter,
UserAttributeForFilter: testGroupSearchUserAttributeForFilter,
Attributes: v1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{
Attributes: idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{
GroupName: testGroupSearchNameAttrName,
},
SkipGroupRefresh: false,
},
},
}
editedValidUpstream := func(editFunc func(*v1alpha1.ActiveDirectoryIdentityProvider)) *v1alpha1.ActiveDirectoryIdentityProvider {
editedValidUpstream := func(editFunc func(*idpv1alpha1.ActiveDirectoryIdentityProvider)) *idpv1alpha1.ActiveDirectoryIdentityProvider {
deepCopy := validUpstream.DeepCopy()
editFunc(deepCopy)
return deepCopy
@@ -373,7 +373,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
dialErrors map[string]error
wantErr string
wantResultingCache []*upstreamldap.ProviderConfig
wantResultingUpstreams []v1alpha1.ActiveDirectoryIdentityProvider
wantResultingUpstreams []idpv1alpha1.ActiveDirectoryIdentityProvider
wantValidatedSettings map[string]upstreamwatchers.ValidatedSettings
}{
{
@@ -390,9 +390,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -413,9 +413,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
inputSecrets: []runtime.Object{},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -441,9 +441,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -468,9 +468,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -488,15 +488,15 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not base64 encoded",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -514,15 +514,15 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not valid pem data",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = base64.StdEncoding.EncodeToString([]byte("this is not pem data"))
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -540,7 +540,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "nil TLS configuration is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS = nil
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -578,9 +578,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -609,7 +609,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "sAMAccountName explicitly provided as group name attribute does not add an override",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS = nil
upstream.Spec.GroupSearch.Attributes.GroupName = "sAMAccountName"
})},
@@ -648,9 +648,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -679,7 +679,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: without a specified port it automatically switches ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.Host = "ldap.example.com" // when the port is not specified, automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -721,9 +721,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -761,7 +761,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: with a specified port it does not automatically switch ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.Host = "ldap.example.com:5678" // when the port is specified, do not automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -802,9 +802,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -827,7 +827,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "non-nil TLS configuration with empty CertificateAuthorityData is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -865,9 +865,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -884,7 +884,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "one valid upstream and one invalid upstream updates the cache to include only the valid upstream",
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Name = "other-upstream"
upstream.Generation = 42
upstream.Spec.Bind.SecretName = "non-existent-secret"
@@ -898,10 +898,10 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "other-upstream", Generation: 42, UID: "other-uid"},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -918,7 +918,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -948,9 +948,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -973,8 +973,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when testing the connection to the LDAP server fails, but later querying defaultsearchbase succeeds, then the upstream is still added to the cache anyway (treated like a warning)",
// Add to cache but not to validatedSettings so we recheck next time
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
// Add to cache, but not to validatedSettings, so we recheck next time
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
@@ -1016,9 +1016,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1041,7 +1041,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when testing the connection to the LDAP server fails, and querying defaultsearchbase fails, then the upstream is not added to the cache",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
@@ -1052,9 +1052,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(3)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1077,7 +1077,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using TLS for the current resource generation and secret version, then do not validate it again and keep using TLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1098,9 +1098,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1119,7 +1119,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
name: "when the validated cache contains LDAP server info but the search base is empty, reload everything",
// this is an invalid state that shouldn't happen now, but if it does we should consider the whole
// validatedsettings cache invalid.
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1165,9 +1165,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
"msDS-User-Account-Control-Computed": validComputedUserAccountControl,
}},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1189,7 +1189,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using TLS, and the search base was found, load TLS and search base info into the cache",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1238,9 +1238,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1262,7 +1262,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using StartTLS for the current resource generation and secret version, then do not validate it again and keep using StartTLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4242"),
@@ -1283,9 +1283,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithStartTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1302,7 +1302,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was validated for an older resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1233, "4242"), // older spec generation!
@@ -1324,9 +1324,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1343,7 +1343,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection condition failed to update previously, then write the cached condition from the previous connection validation",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4200"), // old version of the condition, as if the previous update of conditions had failed
@@ -1364,9 +1364,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"), // updated version of the condition using the cached condition value
},
@@ -1383,7 +1383,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection validation previously failed for this resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
{
@@ -1403,9 +1403,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1422,7 +1422,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated for this resource generation but the bind secret has changed, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
activeDirectoryConnectionValidTrueCondition(1234, "4241"), // same spec generation, old secret version
@@ -1444,9 +1444,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1463,11 +1463,11 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves user attributes blank, provide default values",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Filter = ""
upstream.Spec.GroupSearch.Filter = ""
upstream.Spec.GroupSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{}
upstream.Spec.GroupSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderGroupSearchAttributes{}
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
setupMocks: func(conn *mockldapconn.MockConn) {
@@ -1505,9 +1505,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1524,8 +1524,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves user and group search base blank, query for defaultNamingContext",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Base = ""
upstream.Spec.GroupSearch.Base = ""
})},
@@ -1565,9 +1565,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1589,8 +1589,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves user search base blank but provides group search base, query for defaultNamingContext",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1629,9 +1629,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1653,8 +1653,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves group search base blank but provides user search base, query for defaultNamingContext",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1693,9 +1693,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1717,8 +1717,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the input activedirectoryidentityprovider leaves group search base blank and query for defaultNamingContext fails",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1729,9 +1729,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Search(expectedDefaultNamingContextSearch()).Return(nil, errors.New("some error")).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1745,8 +1745,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when query for defaultNamingContext returns empty string",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1765,9 +1765,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}}, nil).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1781,8 +1781,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when query for defaultNamingContext returns multiple entries",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1807,9 +1807,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}}, nil).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1823,8 +1823,8 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when query for defaultNamingContext returns no entries",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1836,9 +1836,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
Entries: []*ldap.Entry{}}, nil).Times(1)
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1852,12 +1852,12 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when search base was previously found but the bind secret has changed",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
searchBaseFoundInRootDSECondition(1234),
}
upstream.Spec.UserSearch.Attributes = v1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.UserSearch.Attributes = idpv1alpha1.ActiveDirectoryIdentityProviderUserSearchAttributes{}
upstream.Spec.GroupSearch.Base = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1905,9 +1905,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testResourceUID, Generation: 1234},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1929,7 +1929,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "skipping group refresh is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.ActiveDirectoryIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.ActiveDirectoryIdentityProvider) {
upstream.Spec.GroupSearch.SkipGroupRefresh = true
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1968,9 +1968,9 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.ActiveDirectoryIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.ActiveDirectoryIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.ActiveDirectoryIdentityProviderStatus{
Status: idpv1alpha1.ActiveDirectoryIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -2133,13 +2133,13 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
}
}
func normalizeActiveDirectoryUpstreams(upstreams []v1alpha1.ActiveDirectoryIdentityProvider, now metav1.Time) []v1alpha1.ActiveDirectoryIdentityProvider {
result := make([]v1alpha1.ActiveDirectoryIdentityProvider, 0, len(upstreams))
func normalizeActiveDirectoryUpstreams(upstreams []idpv1alpha1.ActiveDirectoryIdentityProvider, now metav1.Time) []idpv1alpha1.ActiveDirectoryIdentityProvider {
result := make([]idpv1alpha1.ActiveDirectoryIdentityProvider, 0, len(upstreams))
for _, u := range upstreams {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = v1alpha1.ActiveDirectoryIdentityProviderSpec{}
normalized.Spec = idpv1alpha1.ActiveDirectoryIdentityProviderSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -21,7 +21,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/clock"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedsupervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
@@ -190,10 +190,10 @@ func (c *federationDomainWatcherController) Sync(ctx controllerlib.Context) erro
func (c *federationDomainWatcherController) processAllFederationDomains(
ctx context.Context,
federationDomains []*configv1alpha1.FederationDomain,
) ([]*federationdomainproviders.FederationDomainIssuer, map[*configv1alpha1.FederationDomain][]*metav1.Condition, error) {
federationDomains []*supervisorconfigv1alpha1.FederationDomain,
) ([]*federationdomainproviders.FederationDomainIssuer, map[*supervisorconfigv1alpha1.FederationDomain][]*metav1.Condition, error) {
federationDomainIssuers := make([]*federationdomainproviders.FederationDomainIssuer, 0)
fdToConditionsMap := map[*configv1alpha1.FederationDomain][]*metav1.Condition{}
fdToConditionsMap := map[*supervisorconfigv1alpha1.FederationDomain][]*metav1.Condition{}
crossDomainConfigValidator := newCrossFederationDomainConfigValidator(federationDomains)
for _, federationDomain := range federationDomains {
@@ -222,7 +222,7 @@ func (c *federationDomainWatcherController) processAllFederationDomains(
func (c *federationDomainWatcherController) makeFederationDomainIssuer(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*metav1.Condition, error) {
var err error
@@ -246,7 +246,7 @@ func (c *federationDomainWatcherController) makeFederationDomainIssuer(
}
func (c *federationDomainWatcherController) makeLegacyFederationDomainIssuer(
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*metav1.Condition, error) {
var defaultFederationDomainIdentityProvider *federationdomainproviders.FederationDomainIdentityProvider
@@ -337,7 +337,7 @@ func (c *federationDomainWatcherController) makeLegacyFederationDomainIssuer(
//nolint:funlen
func (c *federationDomainWatcherController) makeFederationDomainIssuerWithExplicitIDPs(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*metav1.Condition, error) {
federationDomainIdentityProviders := []*federationdomainproviders.FederationDomainIdentityProvider{}
@@ -464,7 +464,7 @@ func (c *federationDomainWatcherController) findIDPsUIDByObjectRef(objectRef cor
func (c *federationDomainWatcherController) makeTransformationPipelineAndEvaluateExamplesForIdentityProvider(
ctx context.Context,
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
validationErrorMessages *transformsValidationErrorMessages,
) (*idtransform.TransformationPipeline, bool, error) {
@@ -490,7 +490,7 @@ func (c *federationDomainWatcherController) makeTransformationPipelineAndEvaluat
}
func (c *federationDomainWatcherController) makeTransformsConstantsForIdentityProvider(
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
) (*celtransformer.TransformationConstants, error) {
consts := &celtransformer.TransformationConstants{
StringConstants: map[string]string{},
@@ -518,7 +518,7 @@ func (c *federationDomainWatcherController) makeTransformsConstantsForIdentityPr
}
func (c *federationDomainWatcherController) makeTransformationPipelineForIdentityProvider(
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
consts *celtransformer.TransformationConstants,
) (*idtransform.TransformationPipeline, string, error) {
@@ -564,7 +564,7 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
func (c *federationDomainWatcherController) evaluateExamplesForIdentityProvider(
ctx context.Context,
idp configv1alpha1.FederationDomainIdentityProvider,
idp supervisorconfigv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
pipeline *idtransform.TransformationPipeline,
) (bool, string) {
@@ -662,7 +662,7 @@ func appendIdentityProviderObjectRefKindCondition(expectedKinds []string, badSuf
func appendIdentityProvidersFoundCondition(
idpNotFoundIndices []int,
federationDomainIdentityProviders []configv1alpha1.FederationDomainIdentityProvider,
federationDomainIdentityProviders []supervisorconfigv1alpha1.FederationDomainIdentityProvider,
conditions []*metav1.Condition,
) []*metav1.Condition {
if len(idpNotFoundIndices) != 0 {
@@ -789,13 +789,13 @@ func appendIssuerURLValidCondition(err error, conditions []*metav1.Condition) []
func (c *federationDomainWatcherController) updateStatus(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
conditions []*metav1.Condition,
) error {
updated := federationDomain.DeepCopy()
if conditionsutil.HadErrorCondition(conditions) {
updated.Status.Phase = configv1alpha1.FederationDomainPhaseError
updated.Status.Phase = supervisorconfigv1alpha1.FederationDomainPhaseError
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionFalse,
@@ -803,7 +803,7 @@ func (c *federationDomainWatcherController) updateStatus(
Message: "the FederationDomain is not ready: see other conditions for details",
})
} else {
updated.Status.Phase = configv1alpha1.FederationDomainPhaseReady
updated.Status.Phase = supervisorconfigv1alpha1.FederationDomainPhaseReady
conditions = append(conditions, &metav1.Condition{
Type: typeReady,
Status: metav1.ConditionTrue,
@@ -858,7 +858,7 @@ func issuerURLToIssuerKey(issuerURL *url.URL) string {
return fmt.Sprintf("%s://%s%s", issuerURL.Scheme, strings.ToLower(issuerURL.Host), issuerURL.Path)
}
func (v *crossFederationDomainConfigValidator) Validate(federationDomain *configv1alpha1.FederationDomain, conditions []*metav1.Condition) []*metav1.Condition {
func (v *crossFederationDomainConfigValidator) Validate(federationDomain *supervisorconfigv1alpha1.FederationDomain, conditions []*metav1.Condition) []*metav1.Condition {
issuerURL, urlParseErr := url.Parse(federationDomain.Spec.Issuer)
if urlParseErr != nil {
@@ -913,7 +913,7 @@ func (v *crossFederationDomainConfigValidator) Validate(federationDomain *config
return conditions
}
func newCrossFederationDomainConfigValidator(federationDomains []*configv1alpha1.FederationDomain) *crossFederationDomainConfigValidator {
func newCrossFederationDomainConfigValidator(federationDomains []*supervisorconfigv1alpha1.FederationDomain) *crossFederationDomainConfigValidator {
// Make a map of issuer strings -> count of how many times we saw that issuer string.
// This will help us complain when there are duplicate issuer strings.
// Also make a helper function for forming keys into this map.
File diff suppressed because it is too large Load Diff
@@ -16,7 +16,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedsupervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -26,7 +26,7 @@ import (
type federationDomainSecretsController struct {
secretHelper SecretHelper
secretRefFunc func(domain *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference
secretRefFunc func(domain *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference
kubeClient kubernetes.Interface
pinnipedClient pinnipedsupervisorclientset.Interface
federationDomainInformer configinformers.FederationDomainInformer
@@ -38,7 +38,7 @@ type federationDomainSecretsController struct {
// provides the parent/child mapping logic.
func NewFederationDomainSecretsController(
secretHelper SecretHelper,
secretRefFunc func(domain *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference,
secretRefFunc func(domain *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference,
kubeClient kubernetes.Interface,
pinnipedClient pinnipedsupervisorclientset.Interface,
secretInformer corev1informers.SecretInformer,
@@ -144,7 +144,7 @@ func (c *federationDomainSecretsController) Sync(ctx controllerlib.Context) erro
// secretNeedsUpdate returns whether or not the Secret, with name secretName, for the federationDomain param
// needs to be updated. It returns the existing secret as its second argument.
func (c *federationDomainSecretsController) secretNeedsUpdate(
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
secretName string,
) (bool, *corev1.Secret, error) {
// This FederationDomain says it has a secret associated with it. Let's try to get it from the cache.
@@ -168,7 +168,7 @@ func (c *federationDomainSecretsController) secretNeedsUpdate(
func (c *federationDomainSecretsController) createOrUpdateSecret(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
newSecret **corev1.Secret,
) error {
secretClient := c.kubeClient.CoreV1().Secrets((*newSecret).Namespace)
@@ -207,7 +207,7 @@ func (c *federationDomainSecretsController) createOrUpdateSecret(
func (c *federationDomainSecretsController) updateFederationDomainStatus(
ctx context.Context,
newFederationDomain *configv1alpha1.FederationDomain,
newFederationDomain *supervisorconfigv1alpha1.FederationDomain,
) error {
federationDomainClient := c.pinnipedClient.ConfigV1alpha1().FederationDomains(newFederationDomain.Namespace)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
@@ -22,7 +22,7 @@ import (
kubernetesfake "k8s.io/client-go/kubernetes/fake"
kubetesting "k8s.io/client-go/testing"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
@@ -72,7 +72,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Name: "some-name",
Controller: boolPtr(true),
},
@@ -88,7 +88,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
},
@@ -104,7 +104,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -128,7 +128,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Kind: "UnrelatedKind",
},
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -149,7 +149,7 @@ func TestFederationDomainControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -214,7 +214,7 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
tests := []struct {
name string
federationDomain configv1alpha1.FederationDomain
federationDomain supervisorconfigv1alpha1.FederationDomain
wantAdd bool
wantUpdate bool
wantDelete bool
@@ -222,7 +222,7 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
}{
{
name: "anything goes",
federationDomain: configv1alpha1.FederationDomain{},
federationDomain: supervisorconfigv1alpha1.FederationDomain{},
wantAdd: true,
wantUpdate: true,
wantDelete: true,
@@ -260,7 +260,7 @@ func TestNewFederationDomainSecretsControllerFilterFederationDomain(t *testing.T
withInformer.WithInformer,
)
unrelated := configv1alpha1.FederationDomain{}
unrelated := supervisorconfigv1alpha1.FederationDomain{}
filter := withInformer.GetFilterForInformer(federationDomainInformer)
require.Equal(t, test.wantAdd, filter.Add(test.federationDomain.DeepCopy()))
require.Equal(t, test.wantUpdate, filter.Update(&unrelated, test.federationDomain.DeepCopy()))
@@ -285,8 +285,8 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
)
federationDomainGVR := schema.GroupVersionResource{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Resource: "federationdomains",
}
@@ -296,7 +296,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
Resource: "secrets",
}
goodFederationDomain := &configv1alpha1.FederationDomain{
goodFederationDomain := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: federationDomainName,
Namespace: namespace,
@@ -359,7 +359,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
tests := []struct {
name string
storage func(**configv1alpha1.FederationDomain, **corev1.Secret)
storage func(**supervisorconfigv1alpha1.FederationDomain, **corev1.Secret)
client func(*pinnipedfake.Clientset, *kubernetesfake.Clientset)
secretHelper func(*mocksecrethelper.MockSecretHelper)
wantFederationDomainActions []kubetesting.Action
@@ -368,20 +368,20 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
}{
{
name: "FederationDomain does not exist and secret does not exist",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*federationDomain = nil
*s = nil
},
},
{
name: "FederationDomain does not exist and secret exists",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*federationDomain = nil
},
},
{
name: "FederationDomain exists and secret does not exist",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -399,7 +399,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and secret does not exist and upon updating FederationDomain we learn a new status field has been set",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -422,7 +422,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and secret does not exist and upon updating FederationDomain we learn all status fields have been set",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -444,7 +444,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -505,7 +505,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and secret does not exist and creating secret fails",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = nil
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -541,7 +541,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists and updating secret fails due to conflict",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -570,7 +570,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists and getting FederationDomain fails",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -594,7 +594,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
},
{
name: "FederationDomain exists and invalid secret exists and updating FederationDomain fails due to conflict",
storage: func(federationDomain **configv1alpha1.FederationDomain, s **corev1.Secret) {
storage: func(federationDomain **supervisorconfigv1alpha1.FederationDomain, s **corev1.Secret) {
*s = invalidSecret.DeepCopy()
},
secretHelper: func(secretHelper *mocksecrethelper.MockSecretHelper) {
@@ -673,7 +673,7 @@ func TestFederationDomainSecretsControllerSync(t *testing.T) {
c := NewFederationDomainSecretsController(
secretHelper,
func(fd *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
func(fd *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
return &fd.Secrets.TokenSigningKey
},
kubeAPIClient,
@@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
)
// SecretHelper describes an object that can Generate() a Secret and determine whether a Secret
@@ -20,9 +20,9 @@ import (
// A SecretHelper has a NamePrefix() that can be used to identify it from other SecretHelper instances.
type SecretHelper interface {
NamePrefix() string
Generate(*configv1alpha1.FederationDomain) (*corev1.Secret, error)
IsValid(*configv1alpha1.FederationDomain, *corev1.Secret) bool
ObserveActiveSecretAndUpdateParentFederationDomain(*configv1alpha1.FederationDomain, *corev1.Secret) *configv1alpha1.FederationDomain
Generate(*supervisorconfigv1alpha1.FederationDomain) (*corev1.Secret, error)
IsValid(*supervisorconfigv1alpha1.FederationDomain, *corev1.Secret) bool
ObserveActiveSecretAndUpdateParentFederationDomain(*supervisorconfigv1alpha1.FederationDomain, *corev1.Secret) *supervisorconfigv1alpha1.FederationDomain
Handles(metav1.Object) bool
}
@@ -89,7 +89,7 @@ type symmetricSecretHelper struct {
func (s *symmetricSecretHelper) NamePrefix() string { return s.namePrefix }
// Generate implements SecretHelper.Generate().
func (s *symmetricSecretHelper) Generate(parent *configv1alpha1.FederationDomain) (*corev1.Secret, error) {
func (s *symmetricSecretHelper) Generate(parent *supervisorconfigv1alpha1.FederationDomain) (*corev1.Secret, error) {
key := make([]byte, symmetricKeySize)
if _, err := s.rand.Read(key); err != nil {
return nil, err
@@ -102,8 +102,8 @@ func (s *symmetricSecretHelper) Generate(parent *configv1alpha1.FederationDomain
Labels: s.labels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: federationDomainKind,
}),
},
@@ -116,7 +116,7 @@ func (s *symmetricSecretHelper) Generate(parent *configv1alpha1.FederationDomain
}
// IsValid implements SecretHelper.IsValid().
func (s *symmetricSecretHelper) IsValid(parent *configv1alpha1.FederationDomain, secret *corev1.Secret) bool {
func (s *symmetricSecretHelper) IsValid(parent *supervisorconfigv1alpha1.FederationDomain, secret *corev1.Secret) bool {
if !metav1.IsControlledBy(secret, parent) {
return false
}
@@ -138,9 +138,9 @@ func (s *symmetricSecretHelper) IsValid(parent *configv1alpha1.FederationDomain,
// ObserveActiveSecretAndUpdateParentFederationDomain implements SecretHelper.ObserveActiveSecretAndUpdateParentFederationDomain().
func (s *symmetricSecretHelper) ObserveActiveSecretAndUpdateParentFederationDomain(
federationDomain *configv1alpha1.FederationDomain,
federationDomain *supervisorconfigv1alpha1.FederationDomain,
secret *corev1.Secret,
) *configv1alpha1.FederationDomain {
) *supervisorconfigv1alpha1.FederationDomain {
s.updateCacheFunc(federationDomain.Spec.Issuer, secret.Data[symmetricSecretDataKey])
switch s.secretUsage {
@@ -189,6 +189,6 @@ func IsFederationDomainSecretOfType(obj metav1.Object, secretType corev1.SecretT
func isFederationDomainControllee(obj metav1.Object) bool {
controller := metav1.GetControllerOf(obj)
return controller != nil &&
controller.APIVersion == configv1alpha1.SchemeGroupVersion.String() &&
controller.APIVersion == supervisorconfigv1alpha1.SchemeGroupVersion.String() &&
controller.Kind == federationDomainKind
}
@@ -12,7 +12,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
)
const keyWith32Bytes = "0123456789abcdef0123456789abcdef"
@@ -24,13 +24,13 @@ func TestSymmetricSecretHelper(t *testing.T) {
name string
secretUsage SecretUsage
wantSecretType corev1.SecretType
wantSetFederationDomainField func(*configv1alpha1.FederationDomain) string
wantSetFederationDomainField func(*supervisorconfigv1alpha1.FederationDomain) string
}{
{
name: "token signing key",
secretUsage: SecretUsageTokenSigningKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-token-signing-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
wantSetFederationDomainField: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.TokenSigningKey.Name
},
},
@@ -38,7 +38,7 @@ func TestSymmetricSecretHelper(t *testing.T) {
name: "state signing key",
secretUsage: SecretUsageStateSigningKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-state-signing-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
wantSetFederationDomainField: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateSigningKey.Name
},
},
@@ -46,7 +46,7 @@ func TestSymmetricSecretHelper(t *testing.T) {
name: "state encryption key",
secretUsage: SecretUsageStateEncryptionKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-state-encryption-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
wantSetFederationDomainField: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateEncryptionKey.Name
},
},
@@ -74,7 +74,7 @@ func TestSymmetricSecretHelper(t *testing.T) {
},
)
parent := &configv1alpha1.FederationDomain{
parent := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
UID: "some-uid",
Namespace: "some-namespace",
@@ -89,8 +89,8 @@ func TestSymmetricSecretHelper(t *testing.T) {
Labels: labels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
}),
},
@@ -124,7 +124,7 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
name string
secretUsage SecretUsage
child func(*corev1.Secret)
parent func(*configv1alpha1.FederationDomain)
parent func(*supervisorconfigv1alpha1.FederationDomain)
want bool
}{
{
@@ -167,7 +167,7 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
child: func(s *corev1.Secret) {
s.Type = FederationDomainTokenSigningKeyType
},
parent: func(federationDomain *configv1alpha1.FederationDomain) {
parent: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) {
federationDomain.UID = "wrong"
},
want: false,
@@ -184,7 +184,7 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
h := NewSymmetricSecretHelper("none of these args matter", nil, nil, test.secretUsage, nil)
parent := &configv1alpha1.FederationDomain{
parent := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "some-parent-name",
Namespace: "some-namespace",
@@ -197,8 +197,8 @@ func TestSymmetricSecretHelperIsValid(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
}),
},
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
@@ -17,7 +17,7 @@ import (
k8sinformers "k8s.io/client-go/informers"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
@@ -82,13 +82,13 @@ func TestJWKSObserverControllerInformerFilters(t *testing.T) {
when("watching FederationDomain objects", func() {
var (
subject controllerlib.Filter
provider, otherProvider *v1alpha1.FederationDomain
provider, otherProvider *supervisorconfigv1alpha1.FederationDomain
)
it.Before(func() {
subject = federationDomainInformerFilter
provider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
provider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
})
when("any FederationDomain changes", func() {
@@ -204,78 +204,78 @@ func TestJWKSObserverControllerSync(t *testing.T) {
)
it.Before(func() {
federationDomainWithoutSecret1 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain1",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"},
Status: v1alpha1.FederationDomainStatus{}, // no Secrets.JWKS field
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{}, // no Secrets.JWKS field
}
federationDomainWithoutSecret2 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain2",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer2.com"},
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer2.com"},
// no Status field
}
federationDomainWithBadSecret := &v1alpha1.FederationDomain{
federationDomainWithBadSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://bad-secret-issuer.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://bad-secret-issuer.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "bad-secret-name"},
},
},
}
federationDomainWithBadJWKSSecret := &v1alpha1.FederationDomain{
federationDomainWithBadJWKSSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-jwks-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://bad-jwks-secret-issuer.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://bad-jwks-secret-issuer.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "bad-jwks-secret-name"},
},
},
}
federationDomainWithBadActiveJWKSecret := &v1alpha1.FederationDomain{
federationDomainWithBadActiveJWKSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-active-jwk-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://bad-active-jwk-secret-issuer.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://bad-active-jwk-secret-issuer.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "bad-active-jwk-secret-name"},
},
},
}
federationDomainWithGoodSecret1 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain1",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret1.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret1.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "good-jwks-secret-name1"},
},
},
}
federationDomainWithGoodSecret2 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain2",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret2.com"},
Status: v1alpha1.FederationDomainStatus{
Secrets: v1alpha1.FederationDomainSecrets{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://issuer-with-good-secret2.com"},
Status: supervisorconfigv1alpha1.FederationDomainStatus{
Secrets: supervisorconfigv1alpha1.FederationDomainSecrets{
JWKS: corev1.LocalObjectReference{Name: "good-jwks-secret-name2"},
},
},
@@ -22,7 +22,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedsupervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -52,7 +52,7 @@ const (
// generateKey is stubbed out for the purpose of testing. The default behavior is to generate an EC key.
var generateKey = generateECKey //nolint:gochecknoglobals
func generateECKey(r io.Reader) (interface{}, error) {
func generateECKey(r io.Reader) (any, error) {
return ecdsa.GenerateKey(elliptic.P256(), r)
}
@@ -168,7 +168,7 @@ func (c *jwksWriterController) Sync(ctx controllerlib.Context) error {
return nil
}
func (c *jwksWriterController) secretNeedsUpdate(federationDomain *configv1alpha1.FederationDomain) (bool, error) {
func (c *jwksWriterController) secretNeedsUpdate(federationDomain *supervisorconfigv1alpha1.FederationDomain) (bool, error) {
if federationDomain.Status.Secrets.JWKS.Name == "" {
// If the FederationDomain says it doesn't have a secret associated with it, then let's create one.
return true, nil
@@ -193,7 +193,7 @@ func (c *jwksWriterController) secretNeedsUpdate(federationDomain *configv1alpha
return false, nil
}
func (c *jwksWriterController) generateSecret(federationDomain *configv1alpha1.FederationDomain) (*corev1.Secret, error) {
func (c *jwksWriterController) generateSecret(federationDomain *supervisorconfigv1alpha1.FederationDomain) (*corev1.Secret, error) {
// Note! This is where we could potentially add more handling of FederationDomain spec fields which tell us how
// this FederationDomain should sign and verify ID tokens (e.g., hardcoded token secret, gRPC
// connection to KMS, etc).
@@ -231,8 +231,8 @@ func (c *jwksWriterController) generateSecret(federationDomain *configv1alpha1.F
Labels: c.jwksSecretLabels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(federationDomain, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: federationDomainKind,
}),
},
@@ -284,7 +284,7 @@ func (c *jwksWriterController) createOrUpdateSecret(
func (c *jwksWriterController) updateFederationDomainStatus(
ctx context.Context,
newFederationDomain *configv1alpha1.FederationDomain,
newFederationDomain *supervisorconfigv1alpha1.FederationDomain,
) error {
federationDomainClient := c.pinnipedClient.ConfigV1alpha1().FederationDomains(newFederationDomain.Namespace)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
@@ -22,7 +22,7 @@ import (
kubernetesfake "k8s.io/client-go/kubernetes/fake"
kubetesting "k8s.io/client-go/testing"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
@@ -71,7 +71,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Name: "some-name",
Controller: boolPtr(true),
},
@@ -87,7 +87,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
},
@@ -103,7 +103,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -127,7 +127,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Kind: "UnrelatedKind",
},
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -148,7 +148,7 @@ func TestJWKSWriterControllerFilterSecret(t *testing.T) {
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
Name: "some-name",
Controller: boolPtr(true),
@@ -204,7 +204,7 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
tests := []struct {
name string
federationDomain configv1alpha1.FederationDomain
federationDomain supervisorconfigv1alpha1.FederationDomain
wantAdd bool
wantUpdate bool
wantDelete bool
@@ -212,7 +212,7 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
}{
{
name: "anything goes",
federationDomain: configv1alpha1.FederationDomain{},
federationDomain: supervisorconfigv1alpha1.FederationDomain{},
wantAdd: true,
wantUpdate: true,
wantDelete: true,
@@ -241,7 +241,7 @@ func TestJWKSWriterControllerFilterFederationDomain(t *testing.T) {
withInformer.WithInformer,
)
unrelated := configv1alpha1.FederationDomain{}
unrelated := supervisorconfigv1alpha1.FederationDomain{}
filter := withInformer.GetFilterForInformer(federationDomainInformer)
require.Equal(t, test.wantAdd, filter.Add(test.federationDomain.DeepCopy()))
require.Equal(t, test.wantUpdate, filter.Update(&unrelated, test.federationDomain.DeepCopy()))
@@ -265,18 +265,18 @@ func TestJWKSWriterControllerSync(t *testing.T) {
require.NoError(t, err)
federationDomainGVR := schema.GroupVersionResource{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Group: supervisorconfigv1alpha1.SchemeGroupVersion.Group,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Resource: "federationdomains",
}
goodFederationDomain := &configv1alpha1.FederationDomain{
goodFederationDomain := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-federationDomain",
Namespace: namespace,
UID: "good-federationDomain-uid",
},
Spec: configv1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://some-issuer.com",
},
}
@@ -332,7 +332,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
secrets []*corev1.Secret
configKubeClient func(*kubernetesfake.Clientset)
configPinnipedClient func(*pinnipedfake.Clientset)
federationDomains []*configv1alpha1.FederationDomain
federationDomains []*supervisorconfigv1alpha1.FederationDomain
generateKeyErr error
wantGenerateKeyCount int
wantSecretActions []kubetesting.Action
@@ -342,7 +342,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "new federationDomain with no secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
wantGenerateKeyCount: 1,
@@ -358,7 +358,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "federationDomain without status with existing secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
secrets: []*corev1.Secret{
@@ -376,7 +376,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "existing federationDomain with no secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
wantGenerateKeyCount: 1,
@@ -391,7 +391,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "existing federationDomain with existing secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -406,7 +406,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "missing jwk in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -424,7 +424,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "missing jwks in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -442,7 +442,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "wrong type in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -460,7 +460,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwk JSON in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -478,7 +478,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwks JSON in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -496,7 +496,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "public jwk in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -514,7 +514,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "private jwks in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -532,7 +532,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwk key in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -550,7 +550,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "invalid jwks key in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -568,7 +568,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "missing active jwks in secret",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
secrets: []*corev1.Secret{
@@ -586,7 +586,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "generate key fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomainWithStatus,
},
generateKeyErr: errors.New("some generate error"),
@@ -595,7 +595,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "get secret fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configKubeClient: func(client *kubernetesfake.Clientset) {
@@ -608,7 +608,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "create secret fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configKubeClient: func(client *kubernetesfake.Clientset) {
@@ -621,7 +621,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "update secret fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
secrets: []*corev1.Secret{
@@ -637,7 +637,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "get FederationDomain fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configPinnipedClient: func(client *pinnipedfake.Clientset) {
@@ -650,7 +650,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
{
name: "update federationDomain fails",
key: controllerlib.Key{Namespace: goodFederationDomain.Namespace, Name: goodFederationDomain.Name},
federationDomains: []*configv1alpha1.FederationDomain{
federationDomains: []*supervisorconfigv1alpha1.FederationDomain{
goodFederationDomain,
},
configPinnipedClient: func(client *pinnipedfake.Clientset) {
@@ -665,7 +665,7 @@ func TestJWKSWriterControllerSync(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
// We shouldn't run this test in parallel since it messes with a global function (generateKey).
generateKeyCount := 0
generateKey = func(_ io.Reader) (interface{}, error) {
generateKey = func(_ io.Reader) (any, error) {
generateKeyCount++
return goodKey, test.generateKeyErr
}
@@ -13,7 +13,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
@@ -30,7 +30,7 @@ const (
)
type ldapUpstreamGenericLDAPImpl struct {
ldapIdentityProvider v1alpha1.LDAPIdentityProvider
ldapIdentityProvider idpv1alpha1.LDAPIdentityProvider
}
func (g *ldapUpstreamGenericLDAPImpl) Spec() upstreamwatchers.UpstreamGenericLDAPSpec {
@@ -54,14 +54,14 @@ func (g *ldapUpstreamGenericLDAPImpl) Status() upstreamwatchers.UpstreamGenericL
}
type ldapUpstreamGenericLDAPSpec struct {
ldapIdentityProvider v1alpha1.LDAPIdentityProvider
ldapIdentityProvider idpv1alpha1.LDAPIdentityProvider
}
func (s *ldapUpstreamGenericLDAPSpec) Host() string {
return s.ldapIdentityProvider.Spec.Host
}
func (s *ldapUpstreamGenericLDAPSpec) TLSSpec() *v1alpha1.TLSSpec {
func (s *ldapUpstreamGenericLDAPSpec) TLSSpec() *idpv1alpha1.TLSSpec {
return s.ldapIdentityProvider.Spec.TLS
}
@@ -84,7 +84,7 @@ func (s *ldapUpstreamGenericLDAPSpec) DetectAndSetSearchBase(_ context.Context,
}
type ldapUpstreamGenericLDAPUserSearch struct {
userSearch v1alpha1.LDAPIdentityProviderUserSearch
userSearch idpv1alpha1.LDAPIdentityProviderUserSearch
}
func (u *ldapUpstreamGenericLDAPUserSearch) Base() string {
@@ -104,7 +104,7 @@ func (u *ldapUpstreamGenericLDAPUserSearch) UIDAttribute() string {
}
type ldapUpstreamGenericLDAPGroupSearch struct {
groupSearch v1alpha1.LDAPIdentityProviderGroupSearch
groupSearch idpv1alpha1.LDAPIdentityProviderGroupSearch
}
func (g *ldapUpstreamGenericLDAPGroupSearch) Base() string {
@@ -124,7 +124,7 @@ func (g *ldapUpstreamGenericLDAPGroupSearch) GroupNameAttribute() string {
}
type ldapUpstreamGenericLDAPStatus struct {
ldapIdentityProvider v1alpha1.LDAPIdentityProvider
ldapIdentityProvider idpv1alpha1.LDAPIdentityProvider
}
func (s *ldapUpstreamGenericLDAPStatus) Conditions() []metav1.Condition {
@@ -226,7 +226,7 @@ func (c *ldapWatcherController) Sync(ctx controllerlib.Context) error {
return nil
}
func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *idpv1alpha1.LDAPIdentityProvider) (p upstreamprovider.UpstreamLDAPIdentityProviderI, requeue bool) {
spec := upstream.Spec
config := &upstreamldap.ProviderConfig{
@@ -256,15 +256,15 @@ func (c *ldapWatcherController) validateUpstream(ctx context.Context, upstream *
return upstreamwatchers.EvaluateConditions(conditions, config)
}
func (c *ldapWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.LDAPIdentityProvider, conditions []*metav1.Condition) {
func (c *ldapWatcherController) updateStatus(ctx context.Context, upstream *idpv1alpha1.LDAPIdentityProvider, conditions []*metav1.Condition) {
log := plog.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
hadErrorCondition := conditionsutil.MergeIDPConditions(conditions, upstream.Generation, &updated.Status.Conditions, log)
updated.Status.Phase = v1alpha1.LDAPPhaseReady
updated.Status.Phase = idpv1alpha1.LDAPPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.LDAPPhaseError
updated.Status.Phase = idpv1alpha1.LDAPPhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -21,7 +21,7 @@ import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
@@ -105,7 +105,7 @@ func TestLDAPUpstreamWatcherControllerFilterLDAPIdentityProviders(t *testing.T)
}{
{
name: "any LDAPIdentityProvider",
idp: &v1alpha1.LDAPIdentityProvider{
idp: &idpv1alpha1.LDAPIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Name: "some-name", Namespace: "some-namespace"},
},
wantAdd: true,
@@ -175,37 +175,37 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
testCABundle := testCA.Bundle()
testCABundleBase64Encoded := base64.StdEncoding.EncodeToString(testCABundle)
validUpstream := &v1alpha1.LDAPIdentityProvider{
validUpstream := &idpv1alpha1.LDAPIdentityProvider{
ObjectMeta: metav1.ObjectMeta{
Name: testName,
Namespace: testNamespace,
Generation: 1234,
UID: testResourceUID,
},
Spec: v1alpha1.LDAPIdentityProviderSpec{
Spec: idpv1alpha1.LDAPIdentityProviderSpec{
Host: testHost,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: v1alpha1.LDAPIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: v1alpha1.LDAPIdentityProviderUserSearch{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testCABundleBase64Encoded},
Bind: idpv1alpha1.LDAPIdentityProviderBind{SecretName: testBindSecretName},
UserSearch: idpv1alpha1.LDAPIdentityProviderUserSearch{
Base: testUserSearchBase,
Filter: testUserSearchFilter,
Attributes: v1alpha1.LDAPIdentityProviderUserSearchAttributes{
Attributes: idpv1alpha1.LDAPIdentityProviderUserSearchAttributes{
Username: testUserSearchUsernameAttrName,
UID: testUserSearchUIDAttrName,
},
},
GroupSearch: v1alpha1.LDAPIdentityProviderGroupSearch{
GroupSearch: idpv1alpha1.LDAPIdentityProviderGroupSearch{
Base: testGroupSearchBase,
Filter: testGroupSearchFilter,
UserAttributeForFilter: testGroupSearchUserAttributeForFilter,
Attributes: v1alpha1.LDAPIdentityProviderGroupSearchAttributes{
Attributes: idpv1alpha1.LDAPIdentityProviderGroupSearchAttributes{
GroupName: testGroupSearchNameAttrName,
},
SkipGroupRefresh: false,
},
},
}
editedValidUpstream := func(editFunc func(*v1alpha1.LDAPIdentityProvider)) *v1alpha1.LDAPIdentityProvider {
editedValidUpstream := func(editFunc func(*idpv1alpha1.LDAPIdentityProvider)) *idpv1alpha1.LDAPIdentityProvider {
deepCopy := validUpstream.DeepCopy()
editFunc(deepCopy)
return deepCopy
@@ -303,7 +303,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
dialErrors map[string]error
wantErr string
wantResultingCache []*upstreamldap.ProviderConfig
wantResultingUpstreams []v1alpha1.LDAPIdentityProvider
wantResultingUpstreams []idpv1alpha1.LDAPIdentityProvider
wantValidatedSettings map[string]upstreamwatchers.ValidatedSettings
}{
{
@@ -320,9 +320,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -342,9 +342,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
inputSecrets: []runtime.Object{},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -370,9 +370,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -397,9 +397,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -417,15 +417,15 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not base64 encoded",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = "this-is-not-base64-encoded"
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -443,15 +443,15 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "CertificateAuthorityData is not valid pem data",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = base64.StdEncoding.EncodeToString([]byte("this is not pem data"))
})},
inputSecrets: []runtime.Object{validBindUserSecret("")},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -469,7 +469,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "nil TLS configuration is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS = nil
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -501,9 +501,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -530,7 +530,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: without a specified port it automatically switches ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.Host = "ldap.example.com" // when the port is not specified, automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -566,9 +566,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -604,7 +604,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when TLS connection fails it tries to use StartTLS instead: with a specified port it does not automatically switch ports",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.Host = "ldap.example.com:5678" // when the port is specified, do not automatically switch ports for StartTLS
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -639,9 +639,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -663,7 +663,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "non-nil TLS configuration with empty CertificateAuthorityData is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.TLS.CertificateAuthorityData = ""
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -695,9 +695,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -713,7 +713,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "one valid upstream and one invalid upstream updates the cache to include only the valid upstream",
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{validUpstream, editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Name = "other-upstream"
upstream.Generation = 42
upstream.Spec.Bind.SecretName = "non-existent-secret"
@@ -727,10 +727,10 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "other-upstream", Generation: 42, UID: "other-uid"},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{
@@ -747,7 +747,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -774,9 +774,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
wantErr: controllerlib.ErrSyntheticRequeue.Error(),
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -798,7 +798,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using TLS for the current resource generation and secret version, then do not validate it again and keep using TLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4242"),
@@ -817,9 +817,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -835,7 +835,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated using StartTLS for the current resource generation and secret version, then do not validate it again and keep using StartTLS",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4242"),
@@ -854,9 +854,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithStartTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -872,7 +872,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was validated for an older resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1233, "4242"), // older spec generation!
@@ -892,9 +892,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -910,7 +910,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection condition failed to update previously, then write the cached condition from the previous connection validation",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234 // current generation
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4200"), // old version of the condition, as if the previous update of conditions had failed
@@ -930,9 +930,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
// Should not perform a test dial and bind. No mocking here means the test will fail if Bind() or Close() are called.
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"), // updated version of the condition using the cached condition value
},
@@ -948,7 +948,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection validation previously failed for this resource generation, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
{
@@ -968,9 +968,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -987,7 +987,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
{
name: "when the validated settings cache is incomplete, then try to validate it again",
// this shouldn't happen, but if it does, just throw it out and try again.
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
{
@@ -1011,9 +1011,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1029,7 +1029,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "when the LDAP server connection was already validated for this resource generation but the bind secret has changed, then try to validate it again",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Generation = 1234
upstream.Status.Conditions = []metav1.Condition{
ldapConnectionValidTrueCondition(1234, "4241"), // same spec generation, old secret version
@@ -1049,9 +1049,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
conn.EXPECT().Close().Times(1)
},
wantResultingCache: []*upstreamldap.ProviderConfig{providerConfigForValidUpstreamWithTLS},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: allConditionsTrue(1234, "4242"),
},
@@ -1066,7 +1066,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}}},
{
name: "skipping group refresh is valid",
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *v1alpha1.LDAPIdentityProvider) {
inputUpstreams: []runtime.Object{editedValidUpstream(func(upstream *idpv1alpha1.LDAPIdentityProvider) {
upstream.Spec.GroupSearch.SkipGroupRefresh = true
})},
inputSecrets: []runtime.Object{validBindUserSecret("4242")},
@@ -1099,9 +1099,9 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
},
},
},
wantResultingUpstreams: []v1alpha1.LDAPIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.LDAPIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testResourceUID},
Status: v1alpha1.LDAPIdentityProviderStatus{
Status: idpv1alpha1.LDAPIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
bindSecretValidTrueCondition(1234),
@@ -1226,13 +1226,13 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
}
}
func normalizeLDAPUpstreams(upstreams []v1alpha1.LDAPIdentityProvider, now metav1.Time) []v1alpha1.LDAPIdentityProvider {
result := make([]v1alpha1.LDAPIdentityProvider, 0, len(upstreams))
func normalizeLDAPUpstreams(upstreams []idpv1alpha1.LDAPIdentityProvider, now metav1.Time) []idpv1alpha1.LDAPIdentityProvider {
result := make([]idpv1alpha1.LDAPIdentityProvider, 0, len(upstreams))
for _, u := range upstreams {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = v1alpha1.LDAPIdentityProviderSpec{}
normalized.Spec = idpv1alpha1.LDAPIdentityProviderSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -14,7 +14,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
configInformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/config/v1alpha1"
@@ -127,7 +127,7 @@ func (c *oidcClientWatcherController) Sync(ctx controllerlib.Context) error {
func (c *oidcClientWatcherController) updateStatus(
ctx context.Context,
upstream *v1alpha1.OIDCClient,
upstream *supervisorconfigv1alpha1.OIDCClient,
conditions []*metav1.Condition,
totalClientSecrets int,
) error {
@@ -136,9 +136,9 @@ func (c *oidcClientWatcherController) updateStatus(
hadErrorCondition := conditionsutil.MergeConfigConditions(conditions,
upstream.Generation, &updated.Status.Conditions, plog.New(), metav1.Now())
updated.Status.Phase = v1alpha1.OIDCClientPhaseReady
updated.Status.Phase = supervisorconfigv1alpha1.OIDCClientPhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.OIDCClientPhaseError
updated.Status.Phase = supervisorconfigv1alpha1.OIDCClientPhaseError
}
updated.Status.TotalClientSecrets = int32(totalClientSecrets)
@@ -16,7 +16,7 @@ import (
k8sinformers "k8s.io/client-go/informers"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
@@ -93,14 +93,14 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
tests := []struct {
name string
oidcClient configv1alpha1.OIDCClient
oidcClient supervisorconfigv1alpha1.OIDCClient
wantAdd bool
wantUpdate bool
wantDelete bool
}{
{
name: "name has client.oauth.pinniped.dev- prefix",
oidcClient: configv1alpha1.OIDCClient{
oidcClient: supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Name: "client.oauth.pinniped.dev-foo"},
},
wantAdd: true,
@@ -109,7 +109,7 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
},
{
name: "name does not have client.oauth.pinniped.dev- prefix",
oidcClient: configv1alpha1.OIDCClient{
oidcClient: supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Name: "something.oauth.pinniped.dev-foo"},
},
wantAdd: false,
@@ -118,7 +118,7 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
},
{
name: "other names without any particular pinniped.dev prefixes",
oidcClient: configv1alpha1.OIDCClient{
oidcClient: supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Name: "something"},
},
wantAdd: false,
@@ -147,7 +147,7 @@ func TestOIDCClientWatcherControllerFilterOIDCClient(t *testing.T) {
withInformer.WithInformer,
)
unrelated := configv1alpha1.OIDCClient{}
unrelated := supervisorconfigv1alpha1.OIDCClient{}
filter := withInformer.GetFilterForInformer(oidcClientsInformer)
require.Equal(t, tt.wantAdd, filter.Add(&tt.oidcClient))
require.Equal(t, tt.wantUpdate, filter.Update(&unrelated, &tt.oidcClient))
@@ -251,7 +251,7 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
inputObjects []runtime.Object
inputSecrets []runtime.Object
wantErr string
wantResultingOIDCClients []configv1alpha1.OIDCClient
wantResultingOIDCClients []supervisorconfigv1alpha1.OIDCClient
wantAPIActions int
}{
{
@@ -260,37 +260,37 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "OIDCClient with wrong prefix is ignored",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
}},
wantAPIActions: 0, // no updates
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
}},
},
{
name: "successfully validate minimal OIDCClient and one client secret stored (while ignoring client with wrong prefix)",
inputObjects: []runtime.Object{
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
},
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
},
},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "wrong-prefix-name", Generation: 1234, UID: testUID},
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -304,18 +304,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate minimal OIDCClient and two client secrets stored",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost, testutil.HashedPassword2AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -328,13 +328,13 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "an already validated OIDCClient does not have its conditions updated when everything is still valid",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(earlier, 1234),
@@ -346,9 +346,9 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 0, // no updates
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(earlier, 1234),
@@ -361,14 +361,14 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "missing required minimum settings and missing client secret storage",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{},
}},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234, `"authorization_code" must always be included in "allowedGrantTypes"`),
@@ -380,18 +380,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "client secret storage exists but cannot be read",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUIDWithWrongVersion(t, testNamespace, testUID)},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -403,18 +403,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "client secret storage exists but does not contain any client secrets",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -427,11 +427,11 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "client secret storage exists but some of the client secrets are invalid bcrypt hashes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{
@@ -439,9 +439,9 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
[]string{testutil.HashedPassword1AtSupervisorMinCost, testutil.HashedPassword1JustBelowSupervisorMinCost, testutil.HashedPassword1InvalidFormat}),
},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -458,24 +458,24 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
{
name: "can operate on multiple at a time, e.g. one is valid one another is missing required minimum settings",
inputObjects: []runtime.Object{
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test1", Generation: 1234, UID: "uid1"},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
},
&configv1alpha1.OIDCClient{
&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test2", Generation: 4567, UID: "uid2"},
Spec: configv1alpha1.OIDCClientSpec{},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{},
},
},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, "uid1", []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 2, // one update for each OIDCClient
wantResultingOIDCClients: []configv1alpha1.OIDCClient{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test1", Generation: 1234, UID: "uid1"},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -487,7 +487,7 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "client.oauth.pinniped.dev-test2", Generation: 4567, UID: "uid2"},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 4567, `"authorization_code" must always be included in "allowedGrantTypes"`),
@@ -501,14 +501,14 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "a previously invalid OIDCClient has its spec changed to become valid so the conditions are updated",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 4567, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
// was invalid on previous run of controller which observed an old generation at an earlier time
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(earlier, 1234, `"authorization_code" must always be included in "allowedGrantTypes"`),
@@ -520,10 +520,10 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 4567, UID: testUID},
// status was updated to reflect the current generation at the current time
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 4567),
@@ -536,18 +536,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "refresh_token must be included in allowedGrantTypes when offline_access is included in allowedScopes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access"},
},
}},
wantAPIActions: 1, // one update
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234, `"refresh_token" must be included in "allowedGrantTypes" when "offline_access" is included in "allowedScopes"`),
@@ -560,18 +560,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "multiple errors on allowedScopes and allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"pinniped:request-audience"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"pinniped:request-audience"},
},
}},
wantAPIActions: 1, // one update
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234,
@@ -589,18 +589,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "another combination of multiple errors on allowedScopes and allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"offline_access"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"offline_access"},
},
}},
wantAPIActions: 1, // one update
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234,
@@ -617,18 +617,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "urn:ietf:params:oauth:grant-type:token-exchange must be included in allowedGrantTypes when pinniped:request-audience is included in allowedScopes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
sadAllowedGrantTypesCondition(now, 1234, `"urn:ietf:params:oauth:grant-type:token-exchange" must be included in "allowedGrantTypes" when "pinniped:request-audience" is included in "allowedScopes"`),
@@ -641,18 +641,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "offline_access must be included in allowedScopes when refresh_token is included in allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -665,18 +665,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "username and groups must also be included in allowedScopes when pinniped:request-audience is included in allowedScopes: both missing",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -689,18 +689,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "username and groups must also be included in allowedScopes when pinniped:request-audience is included in allowedScopes: username missing",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -713,18 +713,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "username and groups must also be included in allowedScopes when pinniped:request-audience is included in allowedScopes: groups missing",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid", "pinniped:request-audience", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "pinniped:request-audience", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -737,18 +737,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "pinniped:request-audience must be included in allowedScopes when urn:ietf:params:oauth:grant-type:token-exchange is included in allowedGrantTypes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []configv1alpha1.Scope{"openid"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -761,18 +761,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient with all allowedGrantTypes and all allowedScopes",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -785,18 +785,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access without username/groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -809,18 +809,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access with username",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -833,18 +833,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access with groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -857,18 +857,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient for offline access without kube API access with both username and groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -881,18 +881,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient without offline access without kube API access with username",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -905,18 +905,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient without offline access without kube API access with groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "username"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "username"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -929,18 +929,18 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
},
{
name: "successfully validate an OIDCClient without offline access without kube API access with both username and groups",
inputObjects: []runtime.Object{&configv1alpha1.OIDCClient{
inputObjects: []runtime.Object{&supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{"openid", "username", "groups"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "username", "groups"},
},
}},
inputSecrets: []runtime.Object{testutil.OIDCClientSecretStorageSecretForUID(t, testNamespace, testUID, []string{testutil.HashedPassword1AtSupervisorMinCost})},
wantAPIActions: 1, // one update
wantResultingOIDCClients: []configv1alpha1.OIDCClient{{
wantResultingOIDCClients: []supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: configv1alpha1.OIDCClientStatus{
Status: supervisorconfigv1alpha1.OIDCClientStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAllowedGrantTypesCondition(now, 1234),
@@ -995,13 +995,13 @@ func TestOIDCClientWatcherControllerSync(t *testing.T) {
}
}
func normalizeOIDCClients(oidcClients []configv1alpha1.OIDCClient, now metav1.Time) []configv1alpha1.OIDCClient {
result := make([]configv1alpha1.OIDCClient, 0, len(oidcClients))
func normalizeOIDCClients(oidcClients []supervisorconfigv1alpha1.OIDCClient, now metav1.Time) []supervisorconfigv1alpha1.OIDCClient {
result := make([]supervisorconfigv1alpha1.OIDCClient, 0, len(oidcClients))
for _, u := range oidcClients {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = configv1alpha1.OIDCClientSpec{}
normalized.Spec = supervisorconfigv1alpha1.OIDCClientSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -25,7 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
idpinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions/idp/v1alpha1"
@@ -102,7 +102,7 @@ type lruValidatorCacheEntry struct {
client *http.Client
}
func (c *lruValidatorCache) getProvider(spec *v1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client) {
func (c *lruValidatorCache) getProvider(spec *idpv1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client) {
if result, ok := c.cache.Get(c.cacheKey(spec)); ok {
entry := result.(*lruValidatorCacheEntry)
return entry.provider, entry.client
@@ -110,11 +110,11 @@ func (c *lruValidatorCache) getProvider(spec *v1alpha1.OIDCIdentityProviderSpec)
return nil, nil
}
func (c *lruValidatorCache) putProvider(spec *v1alpha1.OIDCIdentityProviderSpec, provider *coreosoidc.Provider, client *http.Client) {
func (c *lruValidatorCache) putProvider(spec *idpv1alpha1.OIDCIdentityProviderSpec, provider *coreosoidc.Provider, client *http.Client) {
c.cache.Set(c.cacheKey(spec), &lruValidatorCacheEntry{provider: provider, client: client}, oidcValidatorCacheTTL)
}
func (c *lruValidatorCache) cacheKey(spec *v1alpha1.OIDCIdentityProviderSpec) interface{} {
func (c *lruValidatorCache) cacheKey(spec *idpv1alpha1.OIDCIdentityProviderSpec) any {
var key struct{ issuer, caBundle string }
key.issuer = spec.Issuer
if spec.TLS != nil {
@@ -130,8 +130,8 @@ type oidcWatcherController struct {
oidcIdentityProviderInformer idpinformers.OIDCIdentityProviderInformer
secretInformer corev1informers.SecretInformer
validatorCache interface {
getProvider(*v1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client)
putProvider(*v1alpha1.OIDCIdentityProviderSpec, *coreosoidc.Provider, *http.Client)
getProvider(*idpv1alpha1.OIDCIdentityProviderSpec) (*coreosoidc.Provider, *http.Client)
putProvider(*idpv1alpha1.OIDCIdentityProviderSpec, *coreosoidc.Provider, *http.Client)
}
}
@@ -191,9 +191,9 @@ func (c *oidcWatcherController) Sync(ctx controllerlib.Context) error {
return nil
}
// validateUpstream validates the provided v1alpha1.OIDCIdentityProvider and returns the validated configuration as a
// provider.UpstreamOIDCIdentityProvider. As a side effect, it also updates the status of the v1alpha1.OIDCIdentityProvider.
func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upstream *v1alpha1.OIDCIdentityProvider) *upstreamoidc.ProviderConfig {
// validateUpstream validates the provided idpv1alpha1.OIDCIdentityProvider and returns the validated configuration as a
// provider.UpstreamOIDCIdentityProvider. As a side effect, it also updates the status of the idpv1alpha1.OIDCIdentityProvider.
func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upstream *idpv1alpha1.OIDCIdentityProvider) *upstreamoidc.ProviderConfig {
authorizationConfig := upstream.Spec.AuthorizationConfig
additionalAuthcodeAuthorizeParameters := map[string]string{}
@@ -261,7 +261,7 @@ func (c *oidcWatcherController) validateUpstream(ctx controllerlib.Context, upst
}
// validateSecret validates the .spec.client.secretName field and returns the appropriate ClientCredentialsValid condition.
func (c *oidcWatcherController) validateSecret(upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
func (c *oidcWatcherController) validateSecret(upstream *idpv1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
secretName := upstream.Spec.Client.SecretName
// Fetch the Secret from informer cache.
@@ -309,7 +309,7 @@ func (c *oidcWatcherController) validateSecret(upstream *v1alpha1.OIDCIdentityPr
}
// validateIssuer validates the .spec.issuer field, performs OIDC discovery, and returns the appropriate OIDCDiscoverySucceeded condition.
func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *idpv1alpha1.OIDCIdentityProvider, result *upstreamoidc.ProviderConfig) *metav1.Condition {
// Get the provider and HTTP Client from cache if possible.
discoveredProvider, httpClient := c.validatorCache.getProvider(&upstream.Spec)
@@ -408,15 +408,15 @@ func (c *oidcWatcherController) validateIssuer(ctx context.Context, upstream *v1
}
}
func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *v1alpha1.OIDCIdentityProvider, conditions []*metav1.Condition) {
func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *idpv1alpha1.OIDCIdentityProvider, conditions []*metav1.Condition) {
log := c.log.WithValues("namespace", upstream.Namespace, "name", upstream.Name)
updated := upstream.DeepCopy()
hadErrorCondition := conditionsutil.MergeIDPConditions(conditions, upstream.Generation, &updated.Status.Conditions, log)
updated.Status.Phase = v1alpha1.PhaseReady
updated.Status.Phase = idpv1alpha1.PhaseReady
if hadErrorCondition {
updated.Status.Phase = v1alpha1.PhaseError
updated.Status.Phase = idpv1alpha1.PhaseError
}
if equality.Semantic.DeepEqual(upstream, updated) {
@@ -432,7 +432,7 @@ func (c *oidcWatcherController) updateStatus(ctx context.Context, upstream *v1al
}
}
func getClient(upstream *v1alpha1.OIDCIdentityProvider) (*http.Client, error) {
func getClient(upstream *idpv1alpha1.OIDCIdentityProvider) (*http.Client, error) {
if upstream.Spec.TLS == nil || upstream.Spec.TLS.CertificateAuthorityData == "" {
return defaultClientShortTimeout(nil), nil
}
@@ -23,7 +23,7 @@ import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority"
@@ -140,7 +140,7 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
testAdditionalScopes = []string{"scope1", "scope2", "scope3"}
testExpectedScopes = []string{"openid", "scope1", "scope2", "scope3"}
testDefaultExpectedScopes = []string{"openid", "offline_access", "email", "profile"}
testAdditionalParams = []v1alpha1.Parameter{{Name: "prompt", Value: "consent"}, {Name: "foo", Value: "bar"}}
testAdditionalParams = []idpv1alpha1.Parameter{{Name: "prompt", Value: "consent"}, {Name: "foo", Value: "bar"}}
testExpectedAdditionalParams = map[string]string{"prompt": "consent", "foo": "bar"}
testClientID = "test-oidc-client-id"
testClientSecret = "test-oidc-client-secret"
@@ -156,19 +156,19 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
wantErr string
wantLogs []string
wantResultingCache []*oidctestutil.TestUpstreamOIDCIdentityProvider
wantResultingUpstreams []v1alpha1.OIDCIdentityProvider
wantResultingUpstreams []idpv1alpha1.OIDCIdentityProvider
}{
{
name: "no upstreams",
},
{
name: "missing secret",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{},
@@ -180,9 +180,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="secret \"test-client-secret\" not found" "name"="test-name" "namespace"="test-namespace" "reason"="SecretNotFound" "type"="ClientCredentialsValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -206,12 +206,12 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "secret has wrong type",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -227,9 +227,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "name"="test-name" "namespace"="test-namespace" "reason"="SecretWrongType" "type"="ClientCredentialsValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -253,12 +253,12 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "secret is missing key",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -273,9 +273,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "name"="test-name" "namespace"="test-namespace" "reason"="SecretMissingKeys" "type"="ClientCredentialsValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -299,14 +299,14 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "TLS CA bundle is invalid base64",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "test-name"},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: "invalid-base64",
},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -322,9 +322,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -348,14 +348,14 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "TLS CA bundle does not have any certificates",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "test-name"},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte("not-a-pem-ca-bundle")),
},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -371,9 +371,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: no certificates found" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -397,11 +397,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer is invalid URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: "%invalid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -417,9 +417,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse issuer URL: parse \"%invalid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": invalid URL escape \"%in\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -443,11 +443,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer is insecure http URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: strings.Replace(testIssuerURL, "https", "http", 1),
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -463,9 +463,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="issuer URL '` + strings.Replace(testIssuerURL, "https", "http", 1) + `' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -489,11 +489,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer contains a query param",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "?sub=foo",
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -509,9 +509,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="issuer URL '` + testIssuerURL + "?sub=foo" + `' cannot contain query or fragment component" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -535,11 +535,11 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "issuer contains a fragment",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "#fragment",
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -555,9 +555,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="issuer URL '` + testIssuerURL + "#fragment" + `' cannot contain query or fragment component" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -581,12 +581,12 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
},
{
name: "really long issuer with invalid CA bundle",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/valid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: wrongCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: wrongCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -603,9 +603,9 @@ func TestOIDCUpstreamWatcherControllerSync(t *testing.T) {
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/valid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\":\nGet \"` + testIssuerURL + `/valid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/.well-known/openid-configuration\": tls: failed to verify certificate: x509: certificate signed by unknown authority" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -630,12 +630,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns invalid authorize URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/invalid",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -651,9 +651,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -677,12 +677,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns invalid revocation URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/invalid-revocation-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -698,9 +698,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse revocation endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -724,12 +724,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns insecure authorize URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/insecure",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -745,9 +745,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL 'http://example.com/authorize' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -771,12 +771,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns insecure revocation URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/insecure-revocation-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -792,9 +792,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="revocation endpoint URL 'http://example.com/revoke' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -818,12 +818,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns insecure token URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/insecure-token-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -839,9 +839,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="token endpoint URL 'http://example.com/token' must have \"https\" scheme, not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -865,12 +865,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns no token URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/missing-token-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -886,9 +886,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="token endpoint URL '' must have \"https\" scheme, not \"\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -912,12 +912,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer returns no auth URL",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/missing-auth-url",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -933,9 +933,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL '' must have \"https\" scheme, not \"\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -959,19 +959,19 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "upstream with error becomes valid",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "test-name", UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: append(testAdditionalScopes, "xyz", "openid"), // adds openid unnecessarily
AllowPasswordGrant: true,
},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{Type: "ClientCredentialsValid", Status: "False", LastTransitionTime: earlier, Reason: "SomeError1", Message: "some previous error 1"},
@@ -1004,9 +1004,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -1018,15 +1018,15 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with default authorizationConfig",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1060,9 +1060,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1074,15 +1074,15 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with no revocation endpoint in the discovery document",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/valid-without-revocation",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1116,9 +1116,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1130,18 +1130,18 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with additionalScopes set to override the default",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
Claims: v1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
Claims: idpv1alpha1.OIDCClaims{Groups: testGroupsClaim, Username: testUsernameClaim},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: testAdditionalScopes,
},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1175,9 +1175,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1189,18 +1189,18 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "existing valid upstream with trailing slash and more optional settings",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/ends-with-slash/",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: testAdditionalScopes,
AdditionalAuthorizeParameters: testAdditionalParams,
AllowPasswordGrant: true,
},
Claims: v1alpha1.OIDCClaims{
Claims: idpv1alpha1.OIDCClaims{
Groups: testGroupsClaim,
Username: testUsernameClaim,
AdditionalClaimMappings: map[string]string{
@@ -1208,7 +1208,7 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
},
},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidConditionEarlier,
@@ -1244,9 +1244,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
ResourceUID: testUID,
},
},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Ready",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "True", LastTransitionTime: earlier, Reason: "Success", Message: "additionalAuthorizeParameters parameter names are allowed", ObservedGeneration: 1234},
@@ -1258,14 +1258,14 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "has disallowed additionalAuthorizeParams keys",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL,
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
AdditionalAuthorizeParameters: []v1alpha1.Parameter{
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalAuthorizeParameters: []idpv1alpha1.Parameter{
{Name: "response_type", Value: "foo"},
{Name: "scope", Value: "foo"},
{Name: "client_id", Value: "foo"},
@@ -1293,9 +1293,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="the following additionalAuthorizeParameters are not allowed: response_type,scope,client_id,state,nonce,code_challenge,code_challenge_method,redirect_uri,hd" "name"="test-name" "namespace"="test-namespace" "reason"="DisallowedParameterName" "type"="AdditionalAuthorizeParametersValid"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
{Type: "AdditionalAuthorizeParametersValid", Status: "False", LastTransitionTime: now, Reason: "DisallowedParameterName",
@@ -1309,12 +1309,12 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
},
{
name: "issuer is invalid URL, missing trailing slash when the OIDC discovery endpoint returns the URL with a trailing slash",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/ends-with-slash", // this does not end with slash when it should, thus this is an error case
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -1331,9 +1331,9 @@ Get "` + testIssuerURL + `/valid-url-that-is-really-really-long-nananananananana
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/ends-with-slash\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/ends-with-slash\" got \"` + testIssuerURL + `/ends-with-slash/\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -1358,12 +1358,12 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
},
{
name: "issuer is invalid URL, extra trailing slash",
inputUpstreams: []runtime.Object{&v1alpha1.OIDCIdentityProvider{
inputUpstreams: []runtime.Object{&idpv1alpha1.OIDCIdentityProvider{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Spec: v1alpha1.OIDCIdentityProviderSpec{
Spec: idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: testIssuerURL + "/",
TLS: &v1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: v1alpha1.OIDCClient{SecretName: testSecretName},
TLS: &idpv1alpha1.TLSSpec{CertificateAuthorityData: testIssuerCABase64},
Client: idpv1alpha1.OIDCClient{SecretName: testSecretName},
},
}},
inputSecrets: []runtime.Object{&corev1.Secret{
@@ -1380,9 +1380,9 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
`oidc-upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"` + testIssuerURL + `/\":\noidc: issuer did not match the issuer returned by provider, expected \"` + testIssuerURL + `/\" got \"` + testIssuerURL + `\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
},
wantResultingCache: []*oidctestutil.TestUpstreamOIDCIdentityProvider{},
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
wantResultingUpstreams: []idpv1alpha1.OIDCIdentityProvider{{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName},
Status: v1alpha1.OIDCIdentityProviderStatus{
Status: idpv1alpha1.OIDCIdentityProviderStatus{
Phase: "Error",
Conditions: []metav1.Condition{
happyAdditionalAuthorizeParametersValidCondition,
@@ -1504,13 +1504,13 @@ func unwrapTransport(t *testing.T, rt http.RoundTripper) *http.Transport {
}
}
func normalizeOIDCUpstreams(upstreams []v1alpha1.OIDCIdentityProvider, now metav1.Time) []v1alpha1.OIDCIdentityProvider {
result := make([]v1alpha1.OIDCIdentityProvider, 0, len(upstreams))
func normalizeOIDCUpstreams(upstreams []idpv1alpha1.OIDCIdentityProvider, now metav1.Time) []idpv1alpha1.OIDCIdentityProvider {
result := make([]idpv1alpha1.OIDCIdentityProvider, 0, len(upstreams))
for _, u := range upstreams {
normalized := u.DeepCopy()
// We're only interested in comparing the status, so zero out the spec.
normalized.Spec = v1alpha1.OIDCIdentityProviderSpec{}
normalized.Spec = idpv1alpha1.OIDCIdentityProviderSpec{}
// Round down the LastTransitionTime values to `now` if they were just updated. This makes
// it much easier to encode assertions about the expected timestamps.
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
@@ -18,7 +18,7 @@ import (
k8sinformers "k8s.io/client-go/informers"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
@@ -83,13 +83,13 @@ func TestTLSCertObserverControllerInformerFilters(t *testing.T) {
when("watching FederationDomain objects", func() {
var (
subject controllerlib.Filter
provider, otherProvider *v1alpha1.FederationDomain
provider, otherProvider *supervisorconfigv1alpha1.FederationDomain
)
it.Before(func() {
subject = federationDomainInformerFilter
provider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &v1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
provider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-name", Namespace: "any-namespace"}}
otherProvider = &supervisorconfigv1alpha1.FederationDomain{ObjectMeta: metav1.ObjectMeta{Name: "any-other-name", Namespace: "any-other-namespace"}}
})
when("any FederationDomain changes", func() {
@@ -219,75 +219,75 @@ func TestTLSCertObserverControllerSync(t *testing.T) {
it.Before(func() {
var err error
federationDomainWithoutSecret1 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain1",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"}, // no SNICertificateSecretName field
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: "https://no-secret-issuer1.com"}, // no SNICertificateSecretName field
}
federationDomainWithoutSecret2 := &v1alpha1.FederationDomain{
federationDomainWithoutSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "no-secret-federationdomain2",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://no-secret-issuer2.com",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: ""},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: ""},
},
}
federationDomainWithBadSecret := &v1alpha1.FederationDomain{
federationDomainWithBadSecret := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-secret-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://bad-secret-issuer.com",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "bad-tls-secret-name"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "bad-tls-secret-name"},
},
}
// Also add one with a URL that cannot be parsed to make sure that the controller is not confused by invalid URLs.
invalidIssuerURL := ":/host//path"
_, err = url.Parse(invalidIssuerURL) //nolint:staticcheck // Yes, this URL is intentionally invalid.
r.Error(err)
federationDomainWithBadIssuer := &v1alpha1.FederationDomain{
federationDomainWithBadIssuer := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "bad-issuer-federationdomain",
Namespace: installedInNamespace,
},
Spec: v1alpha1.FederationDomainSpec{Issuer: invalidIssuerURL},
Spec: supervisorconfigv1alpha1.FederationDomainSpec{Issuer: invalidIssuerURL},
}
federationDomainWithGoodSecret1 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret1 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain1",
Namespace: installedInNamespace,
},
// Issuer hostname should be treated in a case-insensitive way and SNI ignores port numbers. Test without a port number.
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://www.iSSuer-wiTh-goOd-secRet1.cOm/path",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
},
}
federationDomainWithGoodSecret2 := &v1alpha1.FederationDomain{
federationDomainWithGoodSecret2 := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "good-secret-federationdomain2",
Namespace: installedInNamespace,
},
// Issuer hostname should be treated in a case-insensitive way and SNI ignores port numbers. Test with a port number.
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://www.issUEr-WIth-gOOd-seCret2.com:1234/path",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name2"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name2"},
},
}
federationDomainWithIPv6Issuer := &v1alpha1.FederationDomain{
federationDomainWithIPv6Issuer := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "ipv6-issuer-federationdomain",
Namespace: installedInNamespace,
},
// Issuer hostname should be treated correctly when it is an IPv6 address. Test with a port number.
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://[2001:db8::1]:1234/path",
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: "good-tls-secret-name1"},
},
}
testCrt1 := readTestFile("testdata/test.crt")
@@ -1,4 +1,4 @@
// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package upstreamwatchers
@@ -14,7 +14,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1informers "k8s.io/client-go/informers/core/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog"
@@ -110,7 +110,7 @@ type UpstreamGenericLDAPIDP interface {
type UpstreamGenericLDAPSpec interface {
Host() string
TLSSpec() *v1alpha1.TLSSpec
TLSSpec() *idpv1alpha1.TLSSpec
BindSecretName() string
UserSearch() UpstreamGenericLDAPUserSearch
GroupSearch() UpstreamGenericLDAPGroupSearch
@@ -135,7 +135,7 @@ type UpstreamGenericLDAPStatus interface {
Conditions() []metav1.Condition
}
func ValidateTLSConfig(tlsSpec *v1alpha1.TLSSpec, config *upstreamldap.ProviderConfig) *metav1.Condition {
func ValidateTLSConfig(tlsSpec *idpv1alpha1.TLSSpec, config *upstreamldap.ProviderConfig) *metav1.Condition {
if tlsSpec == nil {
return validTLSCondition(noTLSConfigurationMessage)
}
@@ -278,8 +278,8 @@ func (c *garbageCollectorController) tryRevokeUpstreamOIDCToken(ctx context.Cont
return nil
}
func logKV(secret *corev1.Secret) []interface{} {
return []interface{}{
func logKV(secret *corev1.Secret) []any {
return []any{
"secretName", secret.Name,
"secretNamespace", secret.Namespace,
"secretType", string(secret.Type),
+2 -2
View File
@@ -72,8 +72,8 @@ func unsyncedInformers(status map[reflect.Type]bool) []string {
return names
}
func anyToFullname(any interface{}) string {
typ := reflect.TypeOf(any)
func anyToFullname(a any) string {
typ := reflect.TypeOf(a)
return typeToFullname(typ)
}
+2 -2
View File
@@ -1,11 +1,11 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
type die string
func crash(i interface{}) {
func crash(i any) {
mustDie, ok := i.(die)
if ok {
panic(string(mustDie))
+5 -5
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
@@ -60,7 +60,7 @@ func WithInformer(getter InformerGetter, filter Filter, opt InformerOption) Opti
}
_, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
AddFunc: func(obj any) {
object := metaOrDie(obj)
if filter.Add(object) {
plog.Debug("handling add",
@@ -73,7 +73,7 @@ func WithInformer(getter InformerGetter, filter Filter, opt InformerOption) Opti
c.add(filter, object)
}
},
UpdateFunc: func(oldObj, newObj interface{}) {
UpdateFunc: func(oldObj, newObj any) {
oldObject := metaOrDie(oldObj)
newObject := metaOrDie(newObj)
if filter.Update(oldObject, newObject) {
@@ -87,7 +87,7 @@ func WithInformer(getter InformerGetter, filter Filter, opt InformerOption) Opti
c.add(filter, newObject)
}
},
DeleteFunc: func(obj interface{}) {
DeleteFunc: func(obj any) {
accessor, err := meta.Accessor(obj)
if err != nil {
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
@@ -146,7 +146,7 @@ func toOnceOpt(opt Option) Option {
}
}
func metaOrDie(obj interface{}) metav1.Object {
func metaOrDie(obj any) metav1.Object {
accessor, err := meta.Accessor(obj)
if err != nil {
panic(err) // this should never happen
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
@@ -16,7 +16,7 @@ var _ events.EventRecorder = klogRecorder{}
type klogRecorder struct{}
func (n klogRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{}) {
func (n klogRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...any) {
plog.Debug("recording event",
"regarding", regarding,
"related", related,
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package controllerlib
@@ -34,7 +34,7 @@ type Key struct {
Name string
// TODO determine if it makes sense to add a field like:
// Extra interface{}
// Extra any
// This would allow a custom ParentFunc to pass extra data through to the Syncer
// The boxed type would have to be comparable (i.e. usable as a map key)
}
+1 -1
View File
@@ -48,7 +48,7 @@ type Storage interface {
GetName(signature string) string
}
type JSON interface{} // document that we need valid JSON types
type JSON any // document that we need valid JSON types
func New(resource string, secrets corev1client.SecretInterface, clock func() time.Time) Storage {
return &secretsStorage{
+1 -1
View File
@@ -244,4 +244,4 @@ func TestNewServingCert(t *testing.T) {
type fakeT struct{}
func (fakeT) Errorf(string, ...interface{}) {}
func (fakeT) Errorf(string, ...any) {}
+4 -4
View File
@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package execcredcache implements a cache for Kubernetes ExecCredential data.
@@ -50,7 +50,7 @@ func New(path string) *Cache {
}
}
func (c *Cache) Get(key interface{}) *clientauthenticationv1beta1.ExecCredential {
func (c *Cache) Get(key any) *clientauthenticationv1beta1.ExecCredential {
// If the cache file does not exist, exit immediately with no error log
if _, err := os.Stat(c.path); errors.Is(err, os.ErrNotExist) {
return nil
@@ -80,7 +80,7 @@ func (c *Cache) Get(key interface{}) *clientauthenticationv1beta1.ExecCredential
return result
}
func (c *Cache) Put(key interface{}, cred *clientauthenticationv1beta1.ExecCredential) {
func (c *Cache) Put(key any, cred *clientauthenticationv1beta1.ExecCredential) {
// Create the cache directory if it does not exist.
if err := os.MkdirAll(filepath.Dir(c.path), 0700); err != nil && !errors.Is(err, os.ErrExist) {
c.errReporter(fmt.Errorf("could not create credential cache directory: %w", err))
@@ -111,7 +111,7 @@ func (c *Cache) Put(key interface{}, cred *clientauthenticationv1beta1.ExecCrede
})
}
func jsonSHA256Hex(key interface{}) string {
func jsonSHA256Hex(key any) string {
hash := sha256.New()
if err := json.NewEncoder(hash).Encode(key); err != nil {
panic(err)
@@ -15,7 +15,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclient "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
@@ -179,7 +179,7 @@ func PinnipedCLI() *Client {
}
}
func oidcClientCRToFositeClient(oidcClient *configv1alpha1.OIDCClient, clientSecrets []string) *Client {
func oidcClientCRToFositeClient(oidcClient *supervisorconfigv1alpha1.OIDCClient, clientSecrets []string) *Client {
// Allow the user to optionally override the default timeouts for these clients.
idTokenLifetimeOverrideInSeconds := oidcClient.Spec.TokenLifetimes.IDTokenSeconds
var idTokenLifetime time.Duration
@@ -215,7 +215,7 @@ func oidcClientCRToFositeClient(oidcClient *configv1alpha1.OIDCClient, clientSec
}
}
func scopesToArguments(scopes []configv1alpha1.Scope) fosite.Arguments {
func scopesToArguments(scopes []supervisorconfigv1alpha1.Scope) fosite.Arguments {
a := make(fosite.Arguments, len(scopes))
for i, scope := range scopes {
a[i] = string(scope)
@@ -223,7 +223,7 @@ func scopesToArguments(scopes []configv1alpha1.Scope) fosite.Arguments {
return a
}
func grantTypesToArguments(grantTypes []configv1alpha1.GrantType) fosite.Arguments {
func grantTypesToArguments(grantTypes []supervisorconfigv1alpha1.GrantType) fosite.Arguments {
a := make(fosite.Arguments, len(grantTypes))
for i, grantType := range grantTypes {
a[i] = string(grantType)
@@ -231,7 +231,7 @@ func grantTypesToArguments(grantTypes []configv1alpha1.GrantType) fosite.Argumen
return a
}
func redirectURIsToStrings(uris []configv1alpha1.RedirectURI) []string {
func redirectURIsToStrings(uris []supervisorconfigv1alpha1.RedirectURI) []string {
s := make([]string, len(uris))
for i, uri := range uris {
s[i] = string(uri)
@@ -20,7 +20,7 @@ import (
coretesting "k8s.io/client-go/testing"
"k8s.io/utils/ptr"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/oidcclientsecretstorage"
@@ -39,7 +39,7 @@ func TestClientManager(t *testing.T) {
tests := []struct {
name string
secrets []*corev1.Secret
oidcClients []*configv1alpha1.OIDCClient
oidcClients []*supervisorconfigv1alpha1.OIDCClient
addKubeReactions func(client *fake.Clientset)
addSupervisorReactions func(client *supervisorfake.Clientset)
run func(t *testing.T, subject *ClientManager)
@@ -62,7 +62,7 @@ func TestClientManager(t *testing.T) {
},
{
name: "find pinniped-cli client when some dynamic clients also exist",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID}},
},
run: func(t *testing.T, subject *ClientManager) {
@@ -74,7 +74,7 @@ func TestClientManager(t *testing.T) {
},
{
name: "client not found",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID}},
},
run: func(t *testing.T, subject *ClientManager) {
@@ -89,13 +89,13 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a dynamic client when its storage secret does not exist (client is invalid because is has no client secret)",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
},
},
},
@@ -107,13 +107,13 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a dynamic client which is invalid due to its spec",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []configv1alpha1.Scope{}, // at least "openid" is required here, so this makes the client invalid
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{}, // at least "openid" is required here, so this makes the client invalid
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80"},
},
},
},
@@ -128,13 +128,13 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a dynamic client which somehow does not have the required prefix in its name, just in case, although should not be possible since prefix is a validation on the CRD",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: "does-not-have-prefix", Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
},
},
},
@@ -166,7 +166,7 @@ func TestClientManager(t *testing.T) {
},
{
name: "when there is an unexpected error getting the storage secret for the OIDCClient",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID}},
},
addKubeReactions: func(client *fake.Clientset) {
@@ -182,14 +182,14 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a valid dynamic client without an ID token lifetime configuration",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
TokenLifetimes: configv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: nil},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:80", "https://foobar.com/callback"},
TokenLifetimes: supervisorconfigv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: nil},
},
},
{
@@ -217,14 +217,14 @@ func TestClientManager(t *testing.T) {
},
{
name: "find a valid dynamic client with an ID token lifetime configuration",
oidcClients: []*configv1alpha1.OIDCClient{
oidcClients: []*supervisorconfigv1alpha1.OIDCClient{
{
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: testName, Generation: 1234, UID: testUID},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
AllowedRedirectURIs: []configv1alpha1.RedirectURI{"http://localhost:8080"},
TokenLifetimes: configv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: ptr.To[int32](4242)},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{"http://localhost:8080"},
TokenLifetimes: supervisorconfigv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: ptr.To[int32](4242)},
},
},
{
@@ -73,7 +73,7 @@ func NewPinnipedSession(
Custom: customSessionData,
}
extras := map[string]interface{}{}
extras := map[string]any{}
extras[oidcapi.IDTokenClaimAuthorizedParty] = c.ClientID
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package dynamiccodec provides a type that can encode information using a just-in-time signing and
@@ -41,12 +41,12 @@ func New(lifespan time.Duration, signingKeyFunc, encryptionKeyFunc KeyFunc) *Cod
}
// Encode implements oidc.Encode().
func (c *Codec) Encode(name string, value interface{}) (string, error) {
func (c *Codec) Encode(name string, value any) (string, error) {
return c.delegate().Encode(name, value)
}
// Decode implements oidc.Decode().
func (c *Codec) Decode(name string, value string, into interface{}) error {
func (c *Codec) Decode(name string, value string, into any) error {
return c.delegate().Decode(name, value, into)
}
@@ -673,7 +673,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
wantUnnecessaryStoredRecords int
wantPasswordGrantCall *expectedPasswordGrant
wantDownstreamCustomSessionData *psession.CustomSessionData
wantDownstreamAdditionalClaims map[string]interface{}
wantDownstreamAdditionalClaims map[string]any
}
tests := []testCase{
{
@@ -929,7 +929,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
"downstreamMissingClaim": "upstreamMissingClaim",
}).
WithIDTokenClaim("upstreamCustomClaim", "i am a claim value").
WithIDTokenClaim("upstreamOtherClaim", []interface{}{"hello", true}).
WithIDTokenClaim("upstreamOtherClaim", []any{"hello", true}).
Build()),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
@@ -949,9 +949,9 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSession,
wantDownstreamAdditionalClaims: map[string]interface{}{
wantDownstreamAdditionalClaims: map[string]any{
"downstreamCustomClaim": "i am a claim value",
"downstreamOtherClaim": []interface{}{"hello", true},
"downstreamOtherClaim": []any{"hello", true},
},
},
{
@@ -2961,7 +2961,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
name: "OIDC upstream password grant: upstream IDP's configured groups claim in the ID token is a slice of interfaces",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
passwordGrantUpstreamOIDCIdentityProviderBuilder().
WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"group1", "group2"}).Build(),
WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"group1", "group2"}).Build(),
),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
@@ -3169,7 +3169,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
{
name: "OIDC upstream password grant: upstream ID token contains groups claim where one element is invalid",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
passwordGrantUpstreamOIDCIdentityProviderBuilder().WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"foo", 7}).Build(),
passwordGrantUpstreamOIDCIdentityProviderBuilder().WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"foo", 7}).Build(),
),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
@@ -3638,7 +3638,7 @@ type errorReturningEncoder struct {
oidc.Codec
}
func (*errorReturningEncoder) Encode(_ string, _ interface{}) (string, error) {
func (*errorReturningEncoder) Encode(_ string, _ any) (string, error) {
return "", fmt.Errorf("some encoding error")
}
@@ -19,7 +19,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/oidc"
@@ -204,7 +204,7 @@ func TestCallbackEndpoint(t *testing.T) {
wantDownstreamPKCEChallenge string
wantDownstreamPKCEChallengeMethod string
wantDownstreamCustomSessionData *psession.CustomSessionData
wantDownstreamAdditionalClaims map[string]interface{}
wantDownstreamAdditionalClaims map[string]any
wantAuthcodeExchangeCall *expectedAuthcodeExchange
}{
@@ -277,7 +277,7 @@ func TestCallbackEndpoint(t *testing.T) {
performedByUpstreamName: happyUpstreamIDPName,
args: happyExchangeAndValidateTokensArgs,
},
wantDownstreamAdditionalClaims: map[string]interface{}{
wantDownstreamAdditionalClaims: map[string]any{
"downstreamCustomClaim": "i am a claim value",
"downstreamOtherClaim": "other claim value",
},
@@ -720,7 +720,7 @@ func TestCallbackEndpoint(t *testing.T) {
{
name: "upstream IDP's configured groups claim in the ID token is a slice of interfaces",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
happyUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"group1", "group2"}).Build(),
happyUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"group1", "group2"}).Build(),
),
method: http.MethodGet,
path: newRequestPath().WithState(happyState).String(),
@@ -813,8 +813,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -856,8 +856,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1092,8 +1092,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1121,8 +1121,8 @@ func TestCallbackEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1482,7 +1482,7 @@ func TestCallbackEndpoint(t *testing.T) {
{
name: "upstream ID token contains groups claim where one element is invalid",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
happyUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []interface{}{"foo", 7}).Build(),
happyUpstream().WithIDTokenClaim(oidcUpstreamGroupsClaim, []any{"foo", 7}).Build(),
),
method: http.MethodGet,
path: newRequestPath().WithState(happyState).String(),
@@ -17,7 +17,7 @@ import (
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/kubernetes/fake"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/celtransformer"
@@ -613,8 +613,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -647,8 +647,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -691,8 +691,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1051,8 +1051,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude username scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1071,8 +1071,8 @@ func TestPostLoginEndpoint(t *testing.T) {
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.OIDCClientAndStorageSecret(t,
"some-namespace", downstreamDynamicClientID, downstreamDynamicClientUID,
[]configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
[]supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
[]supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
downstreamRedirectURI, nil, []string{testutil.HashedPassword1AtGoMinCost}, oidcclientvalidator.Validate)
require.NoError(t, supervisorClient.Tracker().Add(oidcClient))
require.NoError(t, kubeClient.Tracker().Add(secret))
@@ -1185,7 +1185,7 @@ func TestPostLoginEndpoint(t *testing.T) {
tt.wantDownstreamClient,
tt.wantDownstreamRedirectURI,
tt.wantDownstreamCustomSessionData,
map[string]interface{}{},
map[string]any{},
)
case tt.wantRedirectToLoginPageError != "":
// Expecting an error redirect to the login UI page.
@@ -1221,7 +1221,7 @@ func TestPostLoginEndpoint(t *testing.T) {
tt.wantDownstreamClient,
tt.wantDownstreamRedirectURI,
tt.wantDownstreamCustomSessionData,
map[string]interface{}{},
map[string]any{},
)
default:
require.Failf(t, "test should have expected a redirect or form body",
@@ -298,7 +298,7 @@ func validateAndGetDownstreamGroupsFromSession(session *psession.PinnipedSession
if downstreamGroupsInterface == nil {
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
}
downstreamGroupsInterfaceList, ok := downstreamGroupsInterface.([]interface{})
downstreamGroupsInterfaceList, ok := downstreamGroupsInterface.([]any)
if !ok {
return nil, errorsx.WithStack(errMissingUpstreamSessionInternalError())
}
@@ -41,7 +41,7 @@ import (
"k8s.io/utils/ptr"
"k8s.io/utils/strings/slices"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/celtransformer"
"go.pinniped.dev/internal/crud"
@@ -291,7 +291,7 @@ type tokenEndpointResponseExpectedValues struct {
wantUpstreamOIDCValidateTokenCall *expectedUpstreamValidateTokens
wantCustomSessionDataStored *psession.CustomSessionData
wantWarnings []RecordedWarning
wantAdditionalClaims map[string]interface{}
wantAdditionalClaims map[string]any
// The expected lifetime of the ID tokens issued by authcode exchange and refresh, but not token exchange.
// When zero, will assume that the test wants the default value for ID token lifetime.
wantIDTokenLifetimeSeconds int
@@ -377,10 +377,10 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
authcodeExchange: authcodeExchangeInputs{
modifyAuthRequest: func(r *http.Request) { r.Form.Set("scope", "openid profile email username groups") },
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -396,13 +396,13 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
wantGrantedScopes: []string{"openid", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -460,10 +460,10 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
},
modifyTokenRequest: modifyAuthcodeTokenRequestWithDynamicClientAuth,
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -479,13 +479,13 @@ func TestTokenEndpointAuthcodeExchange(t *testing.T) {
wantGrantedScopes: []string{"openid", "pinniped:request-audience", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -967,7 +967,7 @@ func TestTokenEndpointWhenAuthcodeIsUsedTwice(t *testing.T) {
// Authcode exchange doesn't use the upstream provider cache, so just pass an empty cache.
subject, rsp, authCode, _, secrets, oauthStore := exchangeAuthcodeForTokens(t,
test.authcodeExchange, testidplister.NewUpstreamIDPListerBuilder().BuildFederationDomainIdentityProvidersListerFinder(), test.kubeResources)
var parsedResponseBody map[string]interface{}
var parsedResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedResponseBody))
// Second call - should be unsuccessful since auth code was already used.
@@ -1074,10 +1074,10 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
authRequest.Form.Set("scope", "openid pinniped:request-audience username groups")
},
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -1093,13 +1093,13 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
wantGrantedScopes: []string{"openid", "pinniped:request-audience", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -1169,10 +1169,10 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
authRequest.Form.Set("scope", "openid pinniped:request-audience username groups")
},
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -1189,13 +1189,13 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
wantGrantedScopes: []string{"openid", "pinniped:request-audience", "username", "groups"},
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -1242,12 +1242,12 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
name: "dynamic client lacks the required urn:ietf:params:oauth:grant-type:token-exchange grant type",
kubeResources: func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
namespace, clientID, clientUID, redirectURI := "some-namespace", dynamicClientID, dynamicClientUID, goodRedirectURI
oidcClient := &configv1alpha1.OIDCClient{
oidcClient := &supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: clientID, Generation: 1, UID: types.UID(clientUID)},
Spec: configv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // does not have the grant type
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"}, // would be invalid if it also asked for pinniped:request-audience since it lacks the grant type
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(redirectURI)},
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // does not have the grant type
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"}, // would be invalid if it also asked for pinniped:request-audience since it lacks the grant type
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(redirectURI)},
},
}
secret := testutil.OIDCClientSecretStorageSecretForUID(t, namespace, clientUID, []string{testutil.HashedPassword1AtGoMinCost, testutil.HashedPassword2AtGoMinCost})
@@ -1645,7 +1645,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
// Authcode exchange doesn't use the upstream provider cache, so just pass an empty cache.
subject, rsp, _, _, secrets, storage := exchangeAuthcodeForTokens(t,
test.authcodeExchange, testidplister.NewUpstreamIDPListerBuilder().BuildFederationDomainIdentityProvidersListerFinder(), test.kubeResources)
var parsedAuthcodeExchangeResponseBody map[string]interface{}
var parsedAuthcodeExchangeResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedAuthcodeExchangeResponseBody))
request := happyTokenExchangeRequest(test.requestedAudience, parsedAuthcodeExchangeResponseBody["access_token"].(string))
@@ -1681,7 +1681,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
require.Equal(t, test.wantStatus, rsp.Code)
testutil.RequireEqualContentType(t, rsp.Header().Get("Content-Type"), "application/json")
var parsedResponseBody map[string]interface{}
var parsedResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedResponseBody))
if rsp.Code != http.StatusOK {
@@ -1700,7 +1700,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
return
}
claimsOfFirstIDToken := map[string]interface{}{}
claimsOfFirstIDToken := map[string]any{}
originalIDToken := parsedAuthcodeExchangeResponseBody["id_token"].(string)
firstIDTokenDecoded, _ := josejwt.ParseSigned(originalIDToken)
err = firstIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfFirstIDToken)
@@ -1713,7 +1713,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
// Parse the returned token.
parsedJWT, err := jose.ParseSigned(parsedResponseBody["access_token"].(string))
require.NoError(t, err)
var tokenClaims map[string]interface{}
var tokenClaims map[string]any
require.NoError(t, json.Unmarshal(parsedJWT.UnsafePayloadWithoutVerification(), &tokenClaims))
// Make sure that these are the only fields in the token.
@@ -1751,7 +1751,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
if len(test.authcodeExchange.want.wantAdditionalClaims) > 0 {
require.Equal(t, test.authcodeExchange.want.wantAdditionalClaims, tokenClaims["additionalClaims"])
}
additionalClaims, ok := tokenClaims["additionalClaims"].(map[string]interface{})
additionalClaims, ok := tokenClaims["additionalClaims"].(map[string]any)
if ok && tokenClaims["additionalClaims"] != nil {
require.True(t, len(additionalClaims) > 0, "additionalClaims may never be present and empty in the id token")
}
@@ -1995,7 +1995,7 @@ func TestRefreshGrant(t *testing.T) {
return want
}
happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims := func(wantCustomSessionDataStored *psession.CustomSessionData, expectToValidateToken *oauth2.Token, wantAdditionalClaims map[string]interface{}) tokenEndpointResponseExpectedValues {
happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims := func(wantCustomSessionDataStored *psession.CustomSessionData, expectToValidateToken *oauth2.Token, wantAdditionalClaims map[string]any) tokenEndpointResponseExpectedValues {
want := happyRefreshTokenResponseForOpenIDAndOfflineAccess(wantCustomSessionDataStored, expectToValidateToken)
want.wantAdditionalClaims = wantAdditionalClaims
return want
@@ -2030,7 +2030,7 @@ func TestRefreshGrant(t *testing.T) {
refreshedUpstreamTokensWithIDAndRefreshTokens := func() *oauth2.Token {
return refreshedUpstreamTokensWithRefreshTokenWithoutIDToken().
WithExtra(map[string]interface{}{"id_token": oidcUpstreamRefreshedIDToken})
WithExtra(map[string]any{"id_token": oidcUpstreamRefreshedIDToken})
}
refreshedUpstreamTokensWithIDTokenWithoutRefreshToken := func() *oauth2.Token {
@@ -2103,7 +2103,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2121,7 +2121,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2156,7 +2156,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithRefreshTokenWithoutIDToken()).
WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()),
@@ -2195,7 +2195,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2235,7 +2235,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2275,7 +2275,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2284,10 +2284,10 @@ func TestRefreshGrant(t *testing.T) {
customSessionData: initialUpstreamOIDCRefreshTokenCustomSessionData(),
modifyAuthRequest: func(r *http.Request) { r.Form.Set("scope", "openid offline_access username groups") },
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -2304,13 +2304,13 @@ func TestRefreshGrant(t *testing.T) {
wantCustomSessionDataStored: initialUpstreamOIDCRefreshTokenCustomSessionData(),
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2320,13 +2320,13 @@ func TestRefreshGrant(t *testing.T) {
want: happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims(
upstreamOIDCCustomSessionDataWithNewRefreshToken(oidcUpstreamRefreshedRefreshToken),
refreshedUpstreamTokensWithIDAndRefreshTokens(),
map[string]interface{}{
map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2338,7 +2338,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2366,7 +2366,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2402,7 +2402,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -2415,10 +2415,10 @@ func TestRefreshGrant(t *testing.T) {
r.Form.Set("scope", "openid offline_access username groups")
},
modifySession: func(session *psession.PinnipedSession) {
session.IDTokenClaims().Extra["additionalClaims"] = map[string]interface{}{
session.IDTokenClaims().Extra["additionalClaims"] = map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999,
"upstreamObj": map[string]string{
@@ -2436,13 +2436,13 @@ func TestRefreshGrant(t *testing.T) {
wantCustomSessionDataStored: initialUpstreamOIDCRefreshTokenCustomSessionData(),
wantUsername: goodUsername,
wantGroups: goodGroups,
wantAdditionalClaims: map[string]interface{}{
wantAdditionalClaims: map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2453,13 +2453,13 @@ func TestRefreshGrant(t *testing.T) {
want: withWantDynamicClientID(happyRefreshTokenResponseForOpenIDAndOfflineAccessWithAdditionalClaims(
upstreamOIDCCustomSessionDataWithNewRefreshToken(oidcUpstreamRefreshedRefreshToken),
refreshedUpstreamTokensWithIDAndRefreshTokens(),
map[string]interface{}{
map[string]any{
"upstreamString": "string value",
"upstreamBool": true,
"upstreamArray": []interface{}{"hello", true},
"upstreamArray": []any{"hello", true},
"upstreamFloat": 42.0,
"upstreamInt": 999.0, // note: this is deserialized as float64
"upstreamObj": map[string]interface{}{
"upstreamObj": map[string]any{
"name": "value",
},
},
@@ -2471,7 +2471,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": goodUsername,
@@ -2518,7 +2518,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": goodUsername,
@@ -2539,7 +2539,7 @@ func TestRefreshGrant(t *testing.T) {
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").
WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": goodUsername,
@@ -2582,7 +2582,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithRefreshTokenWithoutIDToken()).Build()),
authcodeExchange: authcodeExchangeInputs{
@@ -2619,7 +2619,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithRefreshTokenWithoutIDToken()).Build()),
authcodeExchange: happyAuthcodeExchangeInputsForOIDCUpstream,
@@ -2643,7 +2643,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -2674,7 +2674,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -2708,13 +2708,13 @@ func TestRefreshGrant(t *testing.T) {
},
},
{
name: "happy path refresh grant when the upstream refresh returns new group memberships (as interface{} types) from the merged ID token and userinfo results, it updates groups",
name: "happy path refresh grant when the upstream refresh returns new group memberships (as any types) from the merged ID token and userinfo results, it updates groups",
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []interface{}{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
"my-groups-claim": []any{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
},
}).WithRefreshedTokens(refreshedUpstreamTokensWithIDAndRefreshTokens()).Build()),
@@ -2743,7 +2743,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{}, // refreshed groups claims is updated to be an empty list
},
@@ -2773,7 +2773,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
// "my-groups-claim" is omitted from the refreshed claims
},
@@ -2934,7 +2934,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -2981,7 +2981,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -3031,7 +3031,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": []string{"new-group1", "new-group2", "new-group3"}, // refreshed claims includes updated groups
},
@@ -3134,7 +3134,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithGroupsClaim("my-groups-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
"my-groups-claim": nil,
},
@@ -3155,7 +3155,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3173,7 +3173,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3194,7 +3194,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3238,7 +3238,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3389,7 +3389,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3410,7 +3410,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3441,7 +3441,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": goodUpstreamSubject,
},
},
@@ -3765,7 +3765,7 @@ func TestRefreshGrant(t *testing.T) {
// This is the current format of the errors returned by the production code version of ValidateTokenAndMergeWithUserInfo, see ValidateTokenAndMergeWithUserInfo in upstreamoidc.go
WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": "something-different",
},
},
@@ -3791,7 +3791,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
},
},
@@ -3816,7 +3816,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"username-claim": "some-changed-username",
@@ -3843,7 +3843,7 @@ func TestRefreshGrant(t *testing.T) {
idps: testidplister.NewUpstreamIDPListerBuilder().WithOIDC(
upstreamOIDCIdentityProviderBuilder().WithUsernameClaim("username-claim").WithValidatedAndMergedWithUserInfoTokens(&oidctypes.Token{
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{
Claims: map[string]any{
"some-claim": "some-value",
"sub": goodUpstreamSubject,
"iss": "some-changed-issuer",
@@ -4529,7 +4529,7 @@ func TestRefreshGrant(t *testing.T) {
// just populating a secret in storage.
subject, rsp, authCode, jwtSigningKey, secrets, oauthStore := exchangeAuthcodeForTokens(t,
test.authcodeExchange, test.idps.BuildFederationDomainIdentityProvidersListerFinder(), test.kubeResources)
var parsedAuthcodeExchangeResponseBody map[string]interface{}
var parsedAuthcodeExchangeResponseBody map[string]any
require.NoError(t, json.Unmarshal(rsp.Body.Bytes(), &parsedAuthcodeExchangeResponseBody))
// Performing an authcode exchange should not have caused any upstream refresh, which should only
@@ -4614,7 +4614,7 @@ func TestRefreshGrant(t *testing.T) {
if test.refreshRequest.want.wantStatus == http.StatusOK {
wantIDToken := slices.Contains(test.refreshRequest.want.wantSuccessBodyFields, "id_token")
var parsedRefreshResponseBody map[string]interface{}
var parsedRefreshResponseBody map[string]any
require.NoError(t, json.Unmarshal(refreshResponse.Body.Bytes(), &parsedRefreshResponseBody))
// Check that we got back new tokens.
@@ -4630,12 +4630,12 @@ func TestRefreshGrant(t *testing.T) {
require.Equal(t, parsedAuthcodeExchangeResponseBody["scope"].(string), parsedRefreshResponseBody["scope"].(string))
if wantIDToken {
var claimsOfFirstIDToken map[string]interface{}
var claimsOfFirstIDToken map[string]any
firstIDTokenDecoded, _ := josejwt.ParseSigned(parsedAuthcodeExchangeResponseBody["id_token"].(string))
err := firstIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfFirstIDToken)
require.NoError(t, err)
var claimsOfSecondIDToken map[string]interface{}
var claimsOfSecondIDToken map[string]any
secondIDTokenDecoded, _ := josejwt.ParseSigned(parsedRefreshResponseBody["id_token"].(string))
err = secondIDTokenDecoded.UnsafeClaimsWithoutVerification(&claimsOfSecondIDToken)
require.NoError(t, err)
@@ -4658,13 +4658,13 @@ func TestRefreshGrant(t *testing.T) {
}
}
func requireClaimsAreNotEqual(t *testing.T, claimName string, claimsOfTokenA map[string]interface{}, claimsOfTokenB map[string]interface{}) {
func requireClaimsAreNotEqual(t *testing.T, claimName string, claimsOfTokenA map[string]any, claimsOfTokenB map[string]any) {
require.NotEmpty(t, claimsOfTokenA[claimName])
require.NotEmpty(t, claimsOfTokenB[claimName])
require.NotEqual(t, claimsOfTokenA[claimName], claimsOfTokenB[claimName])
}
func requireClaimsAreEqual(t *testing.T, claimName string, claimsOfTokenA map[string]interface{}, claimsOfTokenB map[string]interface{}) {
func requireClaimsAreEqual(t *testing.T, claimName string, claimsOfTokenA map[string]any, claimsOfTokenB map[string]any) {
require.NotEmpty(t, claimsOfTokenA[claimName])
require.NotEmpty(t, claimsOfTokenB[claimName])
require.Equal(t, claimsOfTokenA[claimName], claimsOfTokenB[claimName])
@@ -4776,7 +4776,7 @@ func requireTokenEndpointBehavior(
if test.wantStatus == http.StatusOK {
require.NotNil(t, test.wantSuccessBodyFields, "problem with test table setup: wanted success but did not specify expected response body")
var parsedResponseBody map[string]interface{}
var parsedResponseBody map[string]any
require.NoError(t, json.Unmarshal(tokenEndpointResponse.Body.Bytes(), &parsedResponseBody))
require.ElementsMatch(t, test.wantSuccessBodyFields, getMapKeys(parsedResponseBody))
@@ -4949,7 +4949,7 @@ func simulateAuthEndpointHavingAlreadyRun(
Subject: goodSubject,
RequestedAt: goodRequestedAtTime,
AuthTime: goodAuthTime,
Extra: map[string]interface{}{},
Extra: map[string]any{},
},
Subject: "", // not used, note that the authorization and callback endpoints do not set this
Username: "", // not used, note that the authorization and callback endpoints do not set this
@@ -5033,7 +5033,7 @@ func requireInvalidAuthCodeStorage(
func requireValidRefreshTokenStorage(
t *testing.T,
body map[string]interface{},
body map[string]any,
storage fositeoauth2.CoreStorage,
wantClientID string,
wantRequestedScopes []string,
@@ -5041,7 +5041,7 @@ func requireValidRefreshTokenStorage(
wantUsername string,
wantGroups []string,
wantCustomSessionData *psession.CustomSessionData,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
secrets v1.SecretInterface,
requestTime time.Time,
) {
@@ -5080,7 +5080,7 @@ func requireValidRefreshTokenStorage(
func requireValidAccessTokenStorage(
t *testing.T,
body map[string]interface{},
body map[string]any,
storage fositeoauth2.CoreStorage,
wantClientID string,
wantRequestedScopes []string,
@@ -5088,7 +5088,7 @@ func requireValidAccessTokenStorage(
wantUsername string,
wantGroups []string,
wantCustomSessionData *psession.CustomSessionData,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
secrets v1.SecretInterface,
requestTime time.Time,
) {
@@ -5146,7 +5146,7 @@ func requireValidAccessTokenStorage(
func requireInvalidAccessTokenStorage(
t *testing.T,
body map[string]interface{},
body map[string]any,
storage fositeoauth2.CoreStorage,
) {
t.Helper()
@@ -5191,7 +5191,7 @@ func requireValidStoredRequest(
wantUsername string,
wantGroups []string,
wantCustomSessionData *psession.CustomSessionData,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
requestTime time.Time,
) {
t.Helper()
@@ -5216,7 +5216,7 @@ func requireValidStoredRequest(
require.Equal(t, goodSubject, claims.Subject)
// Our custom claims from the authorize endpoint should still be set.
expectedExtra := map[string]interface{}{}
expectedExtra := map[string]any{}
if wantUsername != "" {
expectedExtra["username"] = wantUsername
}
@@ -5310,13 +5310,13 @@ func requireGarbageCollectTimeInDelta(t *testing.T, tokenString string, typeLabe
func requireValidIDToken(
t *testing.T,
body map[string]interface{},
body map[string]any,
jwtSigningKey *ecdsa.PrivateKey,
wantClientID string,
wantNonceValueInIDToken bool,
wantUsernameInIDToken string,
wantGroupsInIDToken []string,
wantAdditionalClaims map[string]interface{},
wantAdditionalClaims map[string]any,
wantIDTokenLifetimeSeconds int,
actualAccessToken string,
requestTime time.Time,
@@ -5332,19 +5332,19 @@ func requireValidIDToken(
token := oidctestutil.VerifyECDSAIDToken(t, goodIssuer, wantClientID, jwtSigningKey, idTokenString)
var claims struct {
Subject string `json:"sub"`
Audience []string `json:"aud"`
Issuer string `json:"iss"`
JTI string `json:"jti"`
Nonce string `json:"nonce"`
AccessTokenHash string `json:"at_hash"`
ExpiresAt int64 `json:"exp"`
IssuedAt int64 `json:"iat"`
RequestedAt int64 `json:"rat"`
AuthTime int64 `json:"auth_time"`
Groups []string `json:"groups"`
Username string `json:"username"`
AdditionalClaims map[string]interface{} `json:"additionalClaims"`
Subject string `json:"sub"`
Audience []string `json:"aud"`
Issuer string `json:"iss"`
JTI string `json:"jti"`
Nonce string `json:"nonce"`
AccessTokenHash string `json:"at_hash"`
ExpiresAt int64 `json:"exp"`
IssuedAt int64 `json:"iat"`
RequestedAt int64 `json:"rat"`
AuthTime int64 `json:"auth_time"`
Groups []string `json:"groups"`
Username string `json:"username"`
AdditionalClaims map[string]any `json:"additionalClaims"`
}
idTokenFields := []string{"sub", "aud", "iss", "jti", "auth_time", "exp", "iat", "rat", "azp", "at_hash"}
@@ -5362,7 +5362,7 @@ func requireValidIDToken(
}
// make sure that these are the only fields in the token
var m map[string]interface{}
var m map[string]any
require.NoError(t, token.Claims(&m))
require.ElementsMatch(t, idTokenFields, getMapKeys(m))
@@ -5378,7 +5378,7 @@ func requireValidIDToken(
require.Equal(t, goodIssuer, claims.Issuer)
require.NotEmpty(t, claims.JTI)
require.Equal(t, wantAdditionalClaims, claims.AdditionalClaims)
require.NotEqual(t, map[string]interface{}{}, claims.AdditionalClaims, "additionalClaims may never be present and empty in the id token")
require.NotEqual(t, map[string]any{}, claims.AdditionalClaims, "additionalClaims may never be present and empty in the id token")
if wantNonceValueInIDToken {
require.Equal(t, goodNonce, claims.Nonce)
@@ -5415,7 +5415,7 @@ func deepCopyRequestForm(r *http.Request) *http.Request {
return &http.Request{Form: copied}
}
func getMapKeys(m map[string]interface{}) []string {
func getMapKeys(m map[string]any) []string {
keys := make([]string, 0)
for key := range m {
keys = append(keys, key)
@@ -5423,8 +5423,8 @@ func getMapKeys(m map[string]interface{}) []string {
return keys
}
func toSliceOfInterface(s []string) []interface{} {
r := make([]interface{}, len(s))
func toSliceOfInterface(s []string) []any {
r := make([]any, len(s))
for i := range s {
r[i] = s[i]
}
@@ -27,7 +27,7 @@ type stsParams struct {
requestedAudience string
}
func HandlerFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{} {
func HandlerFactory(config fosite.Configurator, storage any, strategy any) any {
return &tokenExchangeHandler{
idTokenStrategy: strategy.(openid.OpenIDConnectTokenStrategy),
accessTokenStrategy: strategy.(fositeoauth2.AccessTokenStrategy),
@@ -247,7 +247,7 @@ func TestManager(t *testing.T) {
// Minimal check to ensure that the right endpoint was called
r.Equal(http.StatusOK, recorder.Code, "unexpected response:", recorder)
var body map[string]interface{}
var body map[string]any
r.NoError(json.Unmarshal(recorder.Body.Bytes(), &body))
r.Contains(body, "id_token")
r.Contains(body, "access_token")
@@ -19,7 +19,7 @@ const idTokenLifetimeOverrideKey contextKey = iota
// OpenIDConnectExplicitFactory is similar to the function of the same name in the fosite compose package,
// except it allows wrapping the IDTokenLifespanProvider.
func OpenIDConnectExplicitFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{} {
func OpenIDConnectExplicitFactory(config fosite.Configurator, storage any, strategy any) any {
openIDConnectExplicitHandler := compose.OpenIDConnectExplicitFactory(config, storage, strategy).(*openid.OpenIDConnectExplicitHandler)
// Overwrite the config with a wrapper around the fosite.IDTokenLifespanProvider.
openIDConnectExplicitHandler.Config = &contextAwareIDTokenLifespanProvider{DelegateConfig: config}
@@ -28,7 +28,7 @@ func OpenIDConnectExplicitFactory(config fosite.Configurator, storage interface{
// OpenIDConnectRefreshFactory is similar to the function of the same name in the fosite compose package,
// except it allows wrapping the IDTokenLifespanProvider.
func OpenIDConnectRefreshFactory(config fosite.Configurator, _ interface{}, strategy interface{}) interface{} {
func OpenIDConnectRefreshFactory(config fosite.Configurator, _ any, strategy any) any {
openIDConnectRefreshHandler := compose.OpenIDConnectRefreshFactory(config, nil, strategy).(*openid.OpenIDConnectRefreshHandler)
// Overwrite the config with a wrapper around the fosite.IDTokenLifespanProvider.
openIDConnectRefreshHandler.Config = &contextAwareIDTokenLifespanProvider{DelegateConfig: config}
+5 -5
View File
@@ -76,12 +76,12 @@ const (
// Encoder is the encoding side of the securecookie.Codec interface.
type Encoder interface {
Encode(name string, value interface{}) (string, error)
Encode(name string, value any) (string, error)
}
// Decoder is the decoding side of the securecookie.Codec interface.
type Decoder interface {
Decode(name, value string, into interface{}) error
Decode(name, value string, into any) error
}
// Codec is both the encoding and decoding sides of the securecookie.Codec interface. It is
@@ -225,7 +225,7 @@ func DefaultOIDCTimeoutsConfiguration() timeouts.Configuration {
}
func FositeOauth2Helper(
oauthStore interface{},
oauthStore any,
issuer string,
hmacSecretOfLengthAtLeast32Func func() []byte,
jwksProvider jwks.DynamicJWKSProvider,
@@ -293,9 +293,9 @@ func FositeOauth2Helper(
// plog.Info("some error", FositeErrorForLog(err)...)
// ...
// }
func FositeErrorForLog(err error) []interface{} {
func FositeErrorForLog(err error) []any {
rfc6749Error := fosite.ErrorToRFC6749Error(err)
keysAndValues := make([]interface{}, 0)
keysAndValues := make([]any, 0)
keysAndValues = append(keysAndValues, "name")
keysAndValues = append(keysAndValues, rfc6749Error.Error()) // Error() returns the ErrorField
keysAndValues = append(keysAndValues, "status")
@@ -1,4 +1,4 @@
// Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2022-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidcclientvalidator
@@ -11,7 +11,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/oidcclientsecretstorage"
)
@@ -37,7 +37,7 @@ const (
// get the validation error for that case. It returns a bool to indicate if the client is valid,
// along with a slice of conditions containing more details, and the list of client secrets in the
// case that the client was valid.
func Validate(oidcClient *v1alpha1.OIDCClient, secret *corev1.Secret, minBcryptCost int) (bool, []*metav1.Condition, []string) {
func Validate(oidcClient *supervisorconfigv1alpha1.OIDCClient, secret *corev1.Secret, minBcryptCost int) (bool, []*metav1.Condition, []string) {
conds := make([]*metav1.Condition, 0, 3)
conds, clientSecrets := validateSecret(secret, conds, minBcryptCost)
@@ -55,7 +55,7 @@ func Validate(oidcClient *v1alpha1.OIDCClient, secret *corev1.Secret, minBcryptC
}
// validateAllowedScopes checks if allowedScopes is valid on the OIDCClient.
func validateAllowedScopes(oidcClient *v1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
func validateAllowedScopes(oidcClient *supervisorconfigv1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
m := make([]string, 0, 4)
if !allowedScopesContains(oidcClient, oidcapi.ScopeOpenID) {
@@ -95,7 +95,7 @@ func validateAllowedScopes(oidcClient *v1alpha1.OIDCClient, conditions []*metav1
}
// validateAllowedGrantTypes checks if allowedGrantTypes is valid on the OIDCClient.
func validateAllowedGrantTypes(oidcClient *v1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
func validateAllowedGrantTypes(oidcClient *supervisorconfigv1alpha1.OIDCClient, conditions []*metav1.Condition) []*metav1.Condition {
m := make([]string, 0, 3)
if !allowedGrantTypesContains(oidcClient, oidcapi.GrantTypeAuthorizationCode) {
@@ -207,18 +207,18 @@ func validateSecret(secret *corev1.Secret, conditions []*metav1.Condition, minBc
return conditions, storedClientSecrets
}
func allowedGrantTypesContains(haystack *v1alpha1.OIDCClient, needle string) bool {
func allowedGrantTypesContains(haystack *supervisorconfigv1alpha1.OIDCClient, needle string) bool {
for _, hay := range haystack.Spec.AllowedGrantTypes {
if hay == v1alpha1.GrantType(needle) {
if hay == supervisorconfigv1alpha1.GrantType(needle) {
return true
}
}
return false
}
func allowedScopesContains(haystack *v1alpha1.OIDCClient, needle string) bool {
func allowedScopesContains(haystack *supervisorconfigv1alpha1.OIDCClient, needle string) bool {
for _, hay := range haystack.Spec.AllowedScopes {
if hay == v1alpha1.Scope(needle) {
if hay == supervisorconfigv1alpha1.Scope(needle) {
return true
}
}
@@ -40,7 +40,7 @@ type Identity struct {
// The portion of the user's session data which is specific to the upstream identity provider type.
// Refer to the fields of psession.CustomSessionData whose types are specific to an identity provider type.
// Must not be nil.
IDPSpecificSessionData interface{}
IDPSpecificSessionData any
}
// IdentityLoginExtras are additional information that an identity provider may choose to determine
@@ -49,7 +49,7 @@ type Identity struct {
// refreshes. Its fields are optional and may be nil.
type IdentityLoginExtras struct {
// The downstream additional claims determined for this user in an identity provider-specific way, if any.
DownstreamAdditionalClaims map[string]interface{}
DownstreamAdditionalClaims map[string]any
// Login warnings to show the user after they exchange their downstream authcode, if any.
Warnings []string
@@ -76,7 +76,7 @@ type RefreshedIdentity struct {
// Refer to the fields of psession.CustomSessionData whose types are specific to an identity provider type.
// Set this to be the potentially updated IDP-specific session data. If no updates were required, then
// set this to nil.
IDPSpecificSessionData interface{}
IDPSpecificSessionData any
}
// UpstreamAuthorizeRequestState is the state capturing the downstream authorization request, used as a parameter to
@@ -117,7 +117,7 @@ type FederationDomainResolvedIdentityProvider interface {
// of the field which is specific to the upstream identity provider type. If the session's field is
// nil, then return nil.
// Refer to the fields of psession.CustomSessionData whose types are specific to an identity provider type.
CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{}
CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any
// ApplyIDPSpecificSessionDataToSession assigns the IDP-specific portion of the session data into a session.
// The IDP-specific session data provided to this function will be from an Identity that was returned by
@@ -125,7 +125,7 @@ type FederationDomainResolvedIdentityProvider interface {
// assumptions about the type of idpSpecificSessionData for casting, based upon how it chooses to return
// IDPSpecificSessionData in Identity structs. If the given session already has any IDP-specific session
// data, it should be overwritten by this function.
ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{})
ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any)
// UpstreamAuthorizeRedirectURL returns the URL to which the user's browser can be redirected to continue
// the downstream browser-based authorization flow. Returned errors should be of type fosite.RFC6749Error.
@@ -64,7 +64,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) GetTransforms() *idtransf
return p.Transforms
}
func (p *FederationDomainResolvedLDAPIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{} {
func (p *FederationDomainResolvedLDAPIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any {
switch p.GetSessionProviderType() {
case psession.ProviderTypeLDAP:
if session.LDAP == nil {
@@ -83,7 +83,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) CloneIDPSpecificSessionDa
}
}
func (p *FederationDomainResolvedLDAPIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{}) {
func (p *FederationDomainResolvedLDAPIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any) {
if p.GetSessionProviderType() == psession.ProviderTypeActiveDirectory {
session.ActiveDirectory = idpSpecificSessionData.(*psession.ActiveDirectorySessionData)
return
@@ -139,7 +139,7 @@ func (p *FederationDomainResolvedLDAPIdentityProvider) Login(
upstreamUsername := authenticateResponse.User.GetName()
upstreamGroups := authenticateResponse.User.GetGroups()
var sessionData interface{}
var sessionData any
switch p.GetSessionProviderType() {
case psession.ProviderTypeLDAP:
sessionData = &psession.LDAPSessionData{
@@ -86,14 +86,14 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) GetTransforms() *idtransf
return p.Transforms
}
func (p *FederationDomainResolvedOIDCIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) interface{} {
func (p *FederationDomainResolvedOIDCIdentityProvider) CloneIDPSpecificSessionDataFromSession(session *psession.CustomSessionData) any {
if session.OIDC == nil {
return nil
}
return session.OIDC.Clone()
}
func (p *FederationDomainResolvedOIDCIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData interface{}) {
func (p *FederationDomainResolvedOIDCIdentityProvider) ApplyIDPSpecificSessionDataToSession(session *psession.CustomSessionData, idpSpecificSessionData any) {
session.OIDC = idpSpecificSessionData.(*psession.OIDCSessionData)
}
@@ -325,7 +325,7 @@ func (p *FederationDomainResolvedOIDCIdentityProvider) UpstreamRefresh(
}
func validateUpstreamSubjectAndIssuerUnchangedSinceInitialLogin(
mergedClaims map[string]interface{},
mergedClaims map[string]any,
s *psession.OIDCSessionData,
providerName string,
providerType psession.ProviderType,
@@ -361,7 +361,7 @@ func validateUpstreamSubjectAndIssuerUnchangedSinceInitialLogin(
return nil
}
func getString(m map[string]interface{}, key string) (string, bool) {
func getString(m map[string]any, key string) (string, bool) {
val, ok := m[key].(string)
return val, ok
}
@@ -386,7 +386,7 @@ func makeDownstreamOIDCSessionData(
const pleaseCheck = "please check configuration of OIDCIdentityProvider and the client in the " +
"upstream provider's API/UI and try to get a refresh token if possible"
logKV := []interface{}{
logKV := []any{
"upstreamName", oidcUpstream.GetName(),
"scopes", oidcUpstream.GetScopes(),
"additionalParams", oidcUpstream.GetAdditionalAuthcodeParams(),
@@ -425,7 +425,7 @@ func makeDownstreamOIDCSessionData(
// getIdentityFromUpstreamIDToken returns the mapped subject, username, and group names, in that order.
func getIdentityFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
idTokenClaims map[string]any,
idpDisplayName string,
) (string, string, []string, error) {
subject, username, err := getDownstreamSubjectAndUpstreamUsernameFromUpstreamIDToken(upstreamIDPConfig, idTokenClaims, idpDisplayName)
@@ -444,9 +444,9 @@ func getIdentityFromUpstreamIDToken(
// mapAdditionalClaimsFromUpstreamIDToken returns the additionalClaims mapped from the upstream token, if any.
func mapAdditionalClaimsFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
) map[string]interface{} {
mapped := make(map[string]interface{}, len(upstreamIDPConfig.GetAdditionalClaimMappings()))
idTokenClaims map[string]any,
) map[string]any {
mapped := make(map[string]any, len(upstreamIDPConfig.GetAdditionalClaimMappings()))
for downstreamClaimName, upstreamClaimName := range upstreamIDPConfig.GetAdditionalClaimMappings() {
upstreamClaimValue, ok := idTokenClaims[upstreamClaimName]
if !ok {
@@ -464,7 +464,7 @@ func mapAdditionalClaimsFromUpstreamIDToken(
func getDownstreamSubjectAndUpstreamUsernameFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
idTokenClaims map[string]any,
idpDisplayName string,
) (string, string, error) {
// The spec says the "sub" claim is only unique per issuer,
@@ -516,7 +516,7 @@ func getDownstreamSubjectAndUpstreamUsernameFromUpstreamIDToken(
return subject, username, nil
}
func extractStringClaimValue(claimName string, upstreamIDPName string, idTokenClaims map[string]interface{}) (string, error) {
func extractStringClaimValue(claimName string, upstreamIDPName string, idTokenClaims map[string]any) (string, error) {
value, ok := idTokenClaims[claimName]
if !ok {
plog.Warning(
@@ -560,7 +560,7 @@ func mappedUsernameFromUpstreamOIDCSubject(upstreamIssuerAsString string, upstre
// in the provided map of claims. It returns an error when the claim exists but its value cannot be parsed.
func getGroupsFromUpstreamIDToken(
upstreamIDPConfig upstreamprovider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{},
idTokenClaims map[string]any,
) ([]string, error) {
groupsClaimName := upstreamIDPConfig.GetGroupsClaim()
if groupsClaimName == "" {
@@ -590,7 +590,7 @@ func getGroupsFromUpstreamIDToken(
return groupsAsArray, nil
}
func extractGroups(groupsAsInterface interface{}) ([]string, bool) {
func extractGroups(groupsAsInterface any) ([]string, bool) {
groupsAsString, okAsString := groupsAsInterface.(string)
if okAsString {
return []string{groupsAsString}, true
@@ -601,7 +601,7 @@ func extractGroups(groupsAsInterface interface{}) ([]string, bool) {
return groupsAsStringArray, true
}
groupsAsInterfaceArray, okAsArray := groupsAsInterface.([]interface{})
groupsAsInterfaceArray, okAsArray := groupsAsInterface.([]any)
if !okAsArray {
return nil, false
}
@@ -15,18 +15,18 @@ func TestMapAdditionalClaimsFromUpstreamIDToken(t *testing.T) {
tests := []struct {
name string
additionalClaimMappings map[string]string
upstreamClaims map[string]interface{}
wantClaims map[string]interface{}
upstreamClaims map[string]any
wantClaims map[string]any
}{
{
name: "happy path",
additionalClaimMappings: map[string]string{
"email": "notification_email",
},
upstreamClaims: map[string]interface{}{
upstreamClaims: map[string]any{
"notification_email": "test@example.com",
},
wantClaims: map[string]interface{}{
wantClaims: map[string]any{
"email": "test@example.com",
},
},
@@ -35,20 +35,20 @@ func TestMapAdditionalClaimsFromUpstreamIDToken(t *testing.T) {
additionalClaimMappings: map[string]string{
"email": "email",
},
upstreamClaims: map[string]interface{}{},
wantClaims: map[string]interface{}{},
upstreamClaims: map[string]any{},
wantClaims: map[string]any{},
},
{
name: "complex",
additionalClaimMappings: map[string]string{
"complex": "complex",
},
upstreamClaims: map[string]interface{}{
upstreamClaims: map[string]any{
"complex": map[string]string{
"subClaim": "subValue",
},
},
wantClaims: map[string]interface{}{
wantClaims: map[string]any{
"complex": map[string]string{
"subClaim": "subValue",
},
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package strategy
@@ -69,7 +69,7 @@ func (s *DynamicOpenIDConnectECDSAStrategy) GenerateIDToken(
return "", fosite.ErrServerError.WithWrap(constable.Error("JWK must be of type ecdsa"))
}
keyGetter := func(context.Context) (interface{}, error) {
keyGetter := func(context.Context) (any, error) {
return key, nil
}
strategy := compose.NewOpenIDConnectStrategy(keyGetter, s.fositeConfig)
@@ -335,7 +335,7 @@ func TestReadFromSecret(t *testing.T) {
Username: "snorlax",
Subject: "panda",
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}},
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
},
Custom: &psession.CustomSessionData{
Username: "fake-username",
@@ -324,24 +324,24 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) {
*fs = pinnipedSession
},
// these types contain an interface{} that we need to handle
// these types contain an any that we need to handle
// this is safe because we explicitly provide the PinnipedSession concrete type
func(value *map[string]interface{}, c fuzz.Continue) {
func(value *map[string]any, c fuzz.Continue) {
// cover all the JSON data types just in case
*value = map[string]interface{}{
*value = map[string]any{
randString(c): float64(c.Intn(1 << 32)),
randString(c): map[string]interface{}{
randString(c): []interface{}{float64(c.Intn(1 << 32))},
randString(c): map[string]interface{}{
randString(c): map[string]any{
randString(c): []any{float64(c.Intn(1 << 32))},
randString(c): map[string]any{
randString(c): nil,
randString(c): map[string]interface{}{
randString(c): map[string]any{
randString(c): c.RandBool(),
},
},
},
}
},
// JWK contains an interface{} Key that we need to handle
// JWK contains an any Key that we need to handle
// this is safe because JWK explicitly implements JSON marshalling and unmarshalling
func(jwk *jose.JSONWebKey, c fuzz.Continue) {
key, _, err := ed25519.GenerateKey(c)
@@ -471,7 +471,7 @@ func TestReadFromSecret(t *testing.T) {
Username: "snorlax",
Subject: "panda",
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}},
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
},
Custom: &psession.CustomSessionData{
Username: "fake-username",
@@ -392,7 +392,7 @@ func TestReadFromSecret(t *testing.T) {
Username: "snorlax",
Subject: "panda",
Claims: &jwt.IDTokenClaims{JTI: "xyz"},
Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}},
Headers: &jwt.Headers{Extra: map[string]any{"myheader": "foo"}},
},
Custom: &psession.CustomSessionData{
Username: "fake-username",
+12 -12
View File
@@ -16,7 +16,7 @@ import (
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
"go.pinniped.dev/internal/kubeclient"
"go.pinniped.dev/internal/testutil"
)
@@ -66,14 +66,14 @@ func TestMiddlware(t *testing.T) {
}
var ok bool
pinnipedOwner := &configv1alpha1.FederationDomain{
pinnipedOwner := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "some-name",
UID: "some-uid",
},
}
pinnipedOwnerGVK := configv1alpha1.SchemeGroupVersion.WithKind("FederationDomain")
pinnipedOwnerWithNewGroupGVK := configv1alpha1.SchemeGroupVersion.WithKind("FederationDomain")
pinnipedOwnerGVK := supervisorconfigv1alpha1.SchemeGroupVersion.WithKind("FederationDomain")
pinnipedOwnerWithNewGroupGVK := supervisorconfigv1alpha1.SchemeGroupVersion.WithKind("FederationDomain")
pinnipedOwnerWithNewGroupGVK.Group, ok = Replace(pinnipedOwnerWithNewGroupGVK.Group, newSuffix)
require.True(t, ok)
podWithPinnipedOwner := &corev1.Pod{
@@ -105,9 +105,9 @@ func TestMiddlware(t *testing.T) {
},
}
federationDomainWithPinnipedOwner := &configv1alpha1.FederationDomain{
federationDomainWithPinnipedOwner := &supervisorconfigv1alpha1.FederationDomain{
TypeMeta: metav1.TypeMeta{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "FederationDomain",
},
ObjectMeta: metav1.ObjectMeta{
@@ -119,9 +119,9 @@ func TestMiddlware(t *testing.T) {
},
},
}
federationDomainWithNewGroupAndPinnipedOwner := &configv1alpha1.FederationDomain{
federationDomainWithNewGroupAndPinnipedOwner := &supervisorconfigv1alpha1.FederationDomain{
TypeMeta: metav1.TypeMeta{
APIVersion: replaceGV(t, configv1alpha1.SchemeGroupVersion, newSuffix).String(),
APIVersion: replaceGV(t, supervisorconfigv1alpha1.SchemeGroupVersion, newSuffix).String(),
Kind: "FederationDomain",
},
ObjectMeta: metav1.ObjectMeta{
@@ -133,9 +133,9 @@ func TestMiddlware(t *testing.T) {
},
},
}
federationDomainWithNewGroupAndPinnipedOwnerWithNewGroup := &configv1alpha1.FederationDomain{
federationDomainWithNewGroupAndPinnipedOwnerWithNewGroup := &supervisorconfigv1alpha1.FederationDomain{
TypeMeta: metav1.TypeMeta{
APIVersion: replaceGV(t, configv1alpha1.SchemeGroupVersion, newSuffix).String(),
APIVersion: replaceGV(t, supervisorconfigv1alpha1.SchemeGroupVersion, newSuffix).String(),
Kind: "FederationDomain",
},
ObjectMeta: metav1.ObjectMeta{
@@ -308,7 +308,7 @@ func TestMiddlware(t *testing.T) {
rt: (&testutil.RoundTrip{}).
WithVerb(kubeclient.VerbCreate).
WithNamespace("some-namespace").
WithResource(configv1alpha1.SchemeGroupVersion.WithResource("federationdomains")),
WithResource(supervisorconfigv1alpha1.SchemeGroupVersion.WithResource("federationdomains")),
requestObj: federationDomainWithPinnipedOwner,
responseObj: federationDomainWithNewGroupAndPinnipedOwnerWithNewGroup,
wantMutateRequests: 2,
@@ -323,7 +323,7 @@ func TestMiddlware(t *testing.T) {
rt: (&testutil.RoundTrip{}).
WithVerb(kubeclient.VerbUpdate).
WithNamespace("some-namespace").
WithResource(configv1alpha1.SchemeGroupVersion.WithResource("federationdomains")),
WithResource(supervisorconfigv1alpha1.SchemeGroupVersion.WithResource("federationdomains")),
requestObj: federationDomainWithPinnipedOwner,
responseObj: federationDomainWithNewGroupAndPinnipedOwnerWithNewGroup,
wantMutateRequests: 2,
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package here
@@ -18,6 +18,6 @@ func Doc(s string) string {
return strings.ReplaceAll(heredoc.Doc(s), tab, fourSpaces)
}
func Docf(raw string, args ...interface{}) string {
func Docf(raw string, args ...any) string {
return strings.ReplaceAll(heredoc.Docf(raw, args...), tab, fourSpaces)
}
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package httperr contains some helpers for nicer error handling in http.Handler implementations.
@@ -21,7 +21,7 @@ func New(code int, msg string) error {
}
// Newf returns a Responder that emits the given HTTP status code and fmt.Sprintf formatted message.
func Newf(code int, format string, args ...interface{}) error {
func Newf(code int, format string, args ...any) error {
return httpErr{code: code, msg: fmt.Sprintf(format, args...)}
}
@@ -1,4 +1,4 @@
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package idtransform defines upstream-to-downstream identity transformations which could be
@@ -28,7 +28,7 @@ type IdentityTransformation interface {
// Source returns some representation of the original source code of the transformation, which is
// useful for tests to be able to check that a compiled transformation came from the right source.
Source() interface{}
Source() any
}
// TransformationPipeline is a list of identity transforms, which can be evaluated in order against some given input
@@ -89,8 +89,8 @@ func (p *TransformationPipeline) Evaluate(ctx context.Context, username string,
return accumulatedResult, nil
}
func (p *TransformationPipeline) Source() []interface{} {
result := []interface{}{}
func (p *TransformationPipeline) Source() []any {
result := []any{}
for _, transform := range p.transforms {
result = append(result, transform.Source())
}
@@ -22,7 +22,7 @@ func (a fakeNoopTransformer) Evaluate(_ctx context.Context, username string, gro
}, nil
}
func (a fakeNoopTransformer) Source() interface{} {
func (a fakeNoopTransformer) Source() any {
return nil // not needed for this test
}
@@ -37,7 +37,7 @@ func (a fakeNilGroupTransformer) Evaluate(_ctx context.Context, username string,
}, nil
}
func (a fakeNilGroupTransformer) Source() interface{} {
func (a fakeNilGroupTransformer) Source() any {
return nil // not needed for this test
}
@@ -56,7 +56,7 @@ func (a fakeAppendStringTransformer) Evaluate(_ctx context.Context, username str
}, nil
}
func (a fakeAppendStringTransformer) Source() interface{} {
func (a fakeAppendStringTransformer) Source() any {
return nil // not needed for this test
}
@@ -71,7 +71,7 @@ func (a fakeDeleteUsernameAndGroupsTransformer) Evaluate(_ctx context.Context, _
}, nil
}
func (a fakeDeleteUsernameAndGroupsTransformer) Source() interface{} {
func (a fakeDeleteUsernameAndGroupsTransformer) Source() any {
return nil // not needed for this test
}
@@ -90,7 +90,7 @@ func (a fakeAuthenticationDisallowedTransformer) Evaluate(_ctx context.Context,
}, nil
}
func (a fakeAuthenticationDisallowedTransformer) Source() interface{} {
func (a fakeAuthenticationDisallowedTransformer) Source() any {
return nil // not needed for this test
}
@@ -100,7 +100,7 @@ func (a fakeErrorTransformer) Evaluate(_ctx context.Context, _username string, _
return &TransformationResult{}, errors.New("unexpected catastrophic error")
}
func (a fakeErrorTransformer) Source() interface{} {
func (a fakeErrorTransformer) Source() any {
return nil // not needed for this test
}
@@ -112,7 +112,7 @@ func (a fakeTransformerWithSource) Evaluate(_ctx context.Context, _username stri
return nil, nil // not needed for this test
}
func (a fakeTransformerWithSource) Source() interface{} {
func (a fakeTransformerWithSource) Source() any {
return a.source
}
@@ -334,6 +334,6 @@ func TestTransformationSource(t *testing.T) {
pipeline.AppendTransformation(transform)
}
require.Equal(t, []interface{}{"foo", "bar", "baz"}, pipeline.Source())
require.NotEqual(t, []interface{}{"foo", "something-else", "baz"}, pipeline.Source())
require.Equal(t, []any{"foo", "bar", "baz"}, pipeline.Source())
require.NotEqual(t, []any{"foo", "something-else", "baz"}, pipeline.Source())
}
+7 -7
View File
@@ -17,7 +17,7 @@ import (
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
)
func Test_updatePathNewGVK(t *testing.T) {
@@ -92,12 +92,12 @@ func Test_updatePathNewGVK(t *testing.T) {
{
name: "namespace-scoped list path",
args: args{
reqURL: mustParse(t, "https://walrus.tld/apis/"+configv1alpha1.SchemeGroupVersion.String()+"/namespaces/default/federationdomains"),
reqURL: mustParse(t, "https://walrus.tld/apis/"+supervisorconfigv1alpha1.SchemeGroupVersion.String()+"/namespaces/default/federationdomains"),
result: &mutationResult{
origGVK: configv1alpha1.SchemeGroupVersion.WithKind("FederationDomain"),
origGVK: supervisorconfigv1alpha1.SchemeGroupVersion.WithKind("FederationDomain"),
newGVK: schema.GroupVersionKind{
Group: "config.supervisor.tuna.io",
Version: configv1alpha1.SchemeGroupVersion.Version,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
},
gvkChanged: true,
@@ -110,12 +110,12 @@ func Test_updatePathNewGVK(t *testing.T) {
{
name: "namespace-scoped get path",
args: args{
reqURL: mustParse(t, "https://walrus.tld/apis/"+configv1alpha1.SchemeGroupVersion.String()+"/namespaces/default/federationdomains/some-name"),
reqURL: mustParse(t, "https://walrus.tld/apis/"+supervisorconfigv1alpha1.SchemeGroupVersion.String()+"/namespaces/default/federationdomains/some-name"),
result: &mutationResult{
origGVK: configv1alpha1.SchemeGroupVersion.WithKind("FederationDomain"),
origGVK: supervisorconfigv1alpha1.SchemeGroupVersion.WithKind("FederationDomain"),
newGVK: schema.GroupVersionKind{
Group: "config.supervisor.tuna.io",
Version: configv1alpha1.SchemeGroupVersion.Version,
Version: supervisorconfigv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
},
gvkChanged: true,
@@ -14,7 +14,7 @@ import (
"k8s.io/apimachinery/pkg/types"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
"go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/crud"
)
@@ -84,7 +84,7 @@ func (s *OIDCClientSecretStorage) Set(ctx context.Context, resourceVersion, oidc
// Setup an owner reference for garbage collection purposes. When the OIDCClient is deleted, then this
// corresponding client secret storage secret should also be automatically deleted (by Kube garbage collection).
ownerReferences := []metav1.OwnerReference{{
APIVersion: configv1alpha1.SchemeGroupVersion.String(),
APIVersion: supervisorconfigv1alpha1.SchemeGroupVersion.String(),
Kind: "OIDCClient",
Name: oidcClientName,
UID: oidcClientUID,
+47 -47
View File
@@ -39,18 +39,18 @@ const errorKey = "error" // this matches zapr's default for .Error calls (which
// If test assertions are desired, Logger should be passed in as an input. New should be used as the
// production implementation and TestLogger should be used to write test assertions.
type Logger interface {
Error(msg string, err error, keysAndValues ...interface{})
Warning(msg string, keysAndValues ...interface{})
WarningErr(msg string, err error, keysAndValues ...interface{})
Info(msg string, keysAndValues ...interface{})
InfoErr(msg string, err error, keysAndValues ...interface{})
Debug(msg string, keysAndValues ...interface{})
DebugErr(msg string, err error, keysAndValues ...interface{})
Trace(msg string, keysAndValues ...interface{})
TraceErr(msg string, err error, keysAndValues ...interface{})
All(msg string, keysAndValues ...interface{})
Always(msg string, keysAndValues ...interface{})
WithValues(keysAndValues ...interface{}) Logger
Error(msg string, err error, keysAndValues ...any)
Warning(msg string, keysAndValues ...any)
WarningErr(msg string, err error, keysAndValues ...any)
Info(msg string, keysAndValues ...any)
InfoErr(msg string, err error, keysAndValues ...any)
Debug(msg string, keysAndValues ...any)
DebugErr(msg string, err error, keysAndValues ...any)
Trace(msg string, keysAndValues ...any)
TraceErr(msg string, err error, keysAndValues ...any)
All(msg string, keysAndValues ...any)
Always(msg string, keysAndValues ...any)
WithValues(keysAndValues ...any) Logger
WithName(name string) Logger
// does not include Fatal on purpose because that is not a method you should be using
@@ -62,7 +62,7 @@ type Logger interface {
// MinLogger is the overlap between Logger and logr.Logger.
type MinLogger interface {
Info(msg string, keysAndValues ...interface{})
Info(msg string, keysAndValues ...any)
}
var _ Logger = pLogger{}
@@ -77,82 +77,82 @@ func New() Logger {
return pLogger{}
}
func (p pLogger) Error(msg string, err error, keysAndValues ...interface{}) {
func (p pLogger) Error(msg string, err error, keysAndValues ...any) {
p.logr().WithCallDepth(p.depth+1).Error(err, msg, keysAndValues...)
}
func (p pLogger) warningDepth(msg string, depth int, keysAndValues ...interface{}) {
func (p pLogger) warningDepth(msg string, depth int, keysAndValues ...any) {
if p.logr().V(klogLevelWarning).Enabled() {
// klog's structured logging has no concept of a warning (i.e. no WarningS function)
// Thus we use info at log level zero as a proxy
// klog's info logs have an I prefix and its warning logs have a W prefix
// Since we lose the W prefix by using InfoS, just add a key to make these easier to find
keysAndValues = append([]interface{}{"warning", true}, keysAndValues...)
keysAndValues = append([]any{"warning", true}, keysAndValues...)
p.logr().V(klogLevelWarning).WithCallDepth(depth+1).Info(msg, keysAndValues...)
}
}
func (p pLogger) Warning(msg string, keysAndValues ...interface{}) {
func (p pLogger) Warning(msg string, keysAndValues ...any) {
p.warningDepth(msg, p.depth+1, keysAndValues...)
}
func (p pLogger) WarningErr(msg string, err error, keysAndValues ...interface{}) {
p.warningDepth(msg, p.depth+1, append([]interface{}{errorKey, err}, keysAndValues...)...)
func (p pLogger) WarningErr(msg string, err error, keysAndValues ...any) {
p.warningDepth(msg, p.depth+1, append([]any{errorKey, err}, keysAndValues...)...)
}
func (p pLogger) infoDepth(msg string, depth int, keysAndValues ...interface{}) {
func (p pLogger) infoDepth(msg string, depth int, keysAndValues ...any) {
if p.logr().V(KlogLevelInfo).Enabled() {
p.logr().V(KlogLevelInfo).WithCallDepth(depth+1).Info(msg, keysAndValues...)
}
}
func (p pLogger) Info(msg string, keysAndValues ...interface{}) {
func (p pLogger) Info(msg string, keysAndValues ...any) {
p.infoDepth(msg, p.depth+1, keysAndValues...)
}
func (p pLogger) InfoErr(msg string, err error, keysAndValues ...interface{}) {
p.infoDepth(msg, p.depth+1, append([]interface{}{errorKey, err}, keysAndValues...)...)
func (p pLogger) InfoErr(msg string, err error, keysAndValues ...any) {
p.infoDepth(msg, p.depth+1, append([]any{errorKey, err}, keysAndValues...)...)
}
func (p pLogger) debugDepth(msg string, depth int, keysAndValues ...interface{}) {
func (p pLogger) debugDepth(msg string, depth int, keysAndValues ...any) {
if p.logr().V(KlogLevelDebug).Enabled() {
p.logr().V(KlogLevelDebug).WithCallDepth(depth+1).Info(msg, keysAndValues...)
}
}
func (p pLogger) Debug(msg string, keysAndValues ...interface{}) {
func (p pLogger) Debug(msg string, keysAndValues ...any) {
p.debugDepth(msg, p.depth+1, keysAndValues...)
}
func (p pLogger) DebugErr(msg string, err error, keysAndValues ...interface{}) {
p.debugDepth(msg, p.depth+1, append([]interface{}{errorKey, err}, keysAndValues...)...)
func (p pLogger) DebugErr(msg string, err error, keysAndValues ...any) {
p.debugDepth(msg, p.depth+1, append([]any{errorKey, err}, keysAndValues...)...)
}
func (p pLogger) traceDepth(msg string, depth int, keysAndValues ...interface{}) {
func (p pLogger) traceDepth(msg string, depth int, keysAndValues ...any) {
if p.logr().V(KlogLevelTrace).Enabled() {
p.logr().V(KlogLevelTrace).WithCallDepth(depth+1).Info(msg, keysAndValues...)
}
}
func (p pLogger) Trace(msg string, keysAndValues ...interface{}) {
func (p pLogger) Trace(msg string, keysAndValues ...any) {
p.traceDepth(msg, p.depth+1, keysAndValues...)
}
func (p pLogger) TraceErr(msg string, err error, keysAndValues ...interface{}) {
p.traceDepth(msg, p.depth+1, append([]interface{}{errorKey, err}, keysAndValues...)...)
func (p pLogger) TraceErr(msg string, err error, keysAndValues ...any) {
p.traceDepth(msg, p.depth+1, append([]any{errorKey, err}, keysAndValues...)...)
}
func (p pLogger) All(msg string, keysAndValues ...interface{}) {
func (p pLogger) All(msg string, keysAndValues ...any) {
if p.logr().V(klogLevelAll).Enabled() {
p.logr().V(klogLevelAll).WithCallDepth(p.depth+1).Info(msg, keysAndValues...)
}
}
func (p pLogger) Always(msg string, keysAndValues ...interface{}) {
func (p pLogger) Always(msg string, keysAndValues ...any) {
p.logr().WithCallDepth(p.depth+1).Info(msg, keysAndValues...)
}
func (p pLogger) WithValues(keysAndValues ...interface{}) Logger {
func (p pLogger) WithValues(keysAndValues ...any) Logger {
if len(keysAndValues) == 0 {
return p
}
@@ -197,51 +197,51 @@ func (p pLogger) logr() logr.Logger {
var logger = New().withDepth(1) //nolint:gochecknoglobals
func Error(msg string, err error, keysAndValues ...interface{}) {
func Error(msg string, err error, keysAndValues ...any) {
logger.Error(msg, err, keysAndValues...)
}
func Warning(msg string, keysAndValues ...interface{}) {
func Warning(msg string, keysAndValues ...any) {
logger.Warning(msg, keysAndValues...)
}
func WarningErr(msg string, err error, keysAndValues ...interface{}) {
func WarningErr(msg string, err error, keysAndValues ...any) {
logger.WarningErr(msg, err, keysAndValues...)
}
func Info(msg string, keysAndValues ...interface{}) {
func Info(msg string, keysAndValues ...any) {
logger.Info(msg, keysAndValues...)
}
func InfoErr(msg string, err error, keysAndValues ...interface{}) {
func InfoErr(msg string, err error, keysAndValues ...any) {
logger.InfoErr(msg, err, keysAndValues...)
}
func Debug(msg string, keysAndValues ...interface{}) {
func Debug(msg string, keysAndValues ...any) {
logger.Debug(msg, keysAndValues...)
}
func DebugErr(msg string, err error, keysAndValues ...interface{}) {
func DebugErr(msg string, err error, keysAndValues ...any) {
logger.DebugErr(msg, err, keysAndValues...)
}
func Trace(msg string, keysAndValues ...interface{}) {
func Trace(msg string, keysAndValues ...any) {
logger.Trace(msg, keysAndValues...)
}
func TraceErr(msg string, err error, keysAndValues ...interface{}) {
func TraceErr(msg string, err error, keysAndValues ...any) {
logger.TraceErr(msg, err, keysAndValues...)
}
func All(msg string, keysAndValues ...interface{}) {
func All(msg string, keysAndValues ...any) {
logger.All(msg, keysAndValues...)
}
func Always(msg string, keysAndValues ...interface{}) {
func Always(msg string, keysAndValues ...any) {
logger.Always(msg, keysAndValues...)
}
func WithValues(keysAndValues ...interface{}) Logger {
func WithValues(keysAndValues ...any) Logger {
// this looks weird but it is the same as New().WithValues(keysAndValues...) because it returns a new logger rooted at the call site
return logger.withDepth(-1).WithValues(keysAndValues...)
}
@@ -251,7 +251,7 @@ func WithName(name string) Logger {
return logger.withDepth(-1).WithName(name)
}
func Fatal(err error, keysAndValues ...interface{}) {
func Fatal(err error, keysAndValues ...any) {
logger.Error("unrecoverable error encountered", err, keysAndValues...)
globalFlush()
os.Exit(1)
@@ -29,7 +29,7 @@ import (
"k8s.io/klog/v2"
clientsecretapi "go.pinniped.dev/generated/latest/apis/supervisor/clientsecret"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/oidcclientsecretstorage"
"go.pinniped.dev/internal/plog"
@@ -113,7 +113,7 @@ func TestCreate(t *testing.T) {
tests := []struct {
name string
args args
seedOIDCClients []*v1alpha1.OIDCClient
seedOIDCClients []*supervisorconfigv1alpha1.OIDCClient
seedHashes func(storage *oidcclientsecretstorage.OIDCClientSecretStorage)
addReactors func(*kubefake.Clientset, *supervisorfake.Clientset)
fakeByteGenerator io.Reader
@@ -548,7 +548,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-no-secret-for-oidcclient",
Namespace: namespace,
@@ -593,7 +593,7 @@ func TestCreate(t *testing.T) {
},
},
fakeByteGenerator: readerAlwaysErrors{},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-fail-to-generate-secret",
Namespace: namespace,
@@ -636,7 +636,7 @@ func TestCreate(t *testing.T) {
fakeHasher: func(password []byte, cost int) ([]byte, error) {
return nil, errors.New("can't hash stuff")
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-fail-to-hash-secret",
Namespace: namespace,
@@ -677,7 +677,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-happy-new-secret",
Namespace: namespace,
@@ -745,7 +745,7 @@ func TestCreate(t *testing.T) {
),
)
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-append-new-secret-hash",
Namespace: namespace,
@@ -813,7 +813,7 @@ func TestCreate(t *testing.T) {
},
))
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-append-new-secret-hash",
Namespace: namespace,
@@ -879,7 +879,7 @@ func TestCreate(t *testing.T) {
},
))
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -946,7 +946,7 @@ func TestCreate(t *testing.T) {
},
))
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1012,7 +1012,7 @@ func TestCreate(t *testing.T) {
},
))
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1061,7 +1061,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1111,7 +1111,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1165,7 +1165,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1213,7 +1213,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-happy-new-secret",
Namespace: namespace,
@@ -1257,7 +1257,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1301,7 +1301,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1365,7 +1365,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1430,7 +1430,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1499,7 +1499,7 @@ func TestCreate(t *testing.T) {
},
},
},
seedOIDCClients: []*v1alpha1.OIDCClient{{
seedOIDCClients: []*supervisorconfigv1alpha1.OIDCClient{{
ObjectMeta: metav1.ObjectMeta{
Name: "client.oauth.pinniped.dev-some-client",
Namespace: namespace,
@@ -1664,7 +1664,7 @@ func requireLogLinesContain(t *testing.T, fullLog string, wantLines []string) {
require.Empty(t, fullLog)
return
}
var jsonLog map[string]interface{}
var jsonLog map[string]any
err := json.Unmarshal([]byte(fullLog), &jsonLog)
require.NoError(t, err)
require.Contains(t, jsonLog, "message")
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package secret
@@ -63,7 +63,7 @@ func (c *Cache) getFederationDomainCache(oidcIssuer string) *federationDomainCac
return value.(*federationDomainCache)
}
func bytesOrNil(b interface{}) []byte {
func bytesOrNil(b any) []byte {
if b == nil {
return nil
}
+4 -4
View File
@@ -38,7 +38,7 @@ import (
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
"k8s.io/utils/clock"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedsupervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
"go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
@@ -238,7 +238,7 @@ func prepareControllers(
secretCache.SetTokenHMACKey(federationDomainIssuer, symmetricKey)
},
),
func(fd *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
func(fd *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
return &fd.Secrets.TokenSigningKey
},
kubeClient,
@@ -261,7 +261,7 @@ func prepareControllers(
secretCache.SetStateEncoderHashKey(federationDomainIssuer, symmetricKey)
},
),
func(fd *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
func(fd *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
return &fd.Secrets.StateSigningKey
},
kubeClient,
@@ -284,7 +284,7 @@ func prepareControllers(
secretCache.SetStateEncoderBlockKey(federationDomainIssuer, symmetricKey)
},
),
func(fd *configv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
func(fd *supervisorconfigv1alpha1.FederationDomainStatus) *corev1.LocalObjectReference {
return &fd.Secrets.StateEncryptionKey
},
kubeClient,
+1 -1
View File
@@ -163,7 +163,7 @@ func WantExactErrorString(wantErrStr string) RequireErrorStringFunc {
// WantSprintfErrorString can be used to set up an expected value for an error string in a test table.
// Use when you want to express that an expected string built using fmt.Sprintf semantics must be an exact match.
func WantSprintfErrorString(wantErrSprintfSpecifier string, a ...interface{}) RequireErrorStringFunc {
func WantSprintfErrorString(wantErrSprintfSpecifier string, a ...any) RequireErrorStringFunc {
wantErrStr := fmt.Sprintf(wantErrSprintfSpecifier, a...)
return func(t *testing.T, actualErrorStr string) {
require.Equal(t, wantErrStr, actualErrorStr)
+17 -17
View File
@@ -13,7 +13,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
)
const (
@@ -35,10 +35,10 @@ const (
)
// allDynamicClientScopes returns a slice of all scopes that are supported by the Supervisor for dynamic clients.
func allDynamicClientScopes() []configv1alpha1.Scope {
scopes := []configv1alpha1.Scope{}
func allDynamicClientScopes() []supervisorconfigv1alpha1.Scope {
scopes := []supervisorconfigv1alpha1.Scope{}
for _, s := range strings.Split(AllDynamicClientScopesSpaceSep, " ") {
scopes = append(scopes, configv1alpha1.Scope(s))
scopes = append(scopes, supervisorconfigv1alpha1.Scope(s))
}
return scopes
}
@@ -48,24 +48,24 @@ func newOIDCClient(
clientID string,
clientUID string,
redirectURI string,
allowedGrantTypes []configv1alpha1.GrantType,
allowedScopes []configv1alpha1.Scope,
allowedGrantTypes []supervisorconfigv1alpha1.GrantType,
allowedScopes []supervisorconfigv1alpha1.Scope,
tokenLifetimesIDTokenSeconds *int32,
) *configv1alpha1.OIDCClient {
return &configv1alpha1.OIDCClient{
) *supervisorconfigv1alpha1.OIDCClient {
return &supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: clientID, Generation: 1, UID: types.UID(clientUID)},
Spec: configv1alpha1.OIDCClientSpec{
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
AllowedGrantTypes: allowedGrantTypes,
AllowedScopes: allowedScopes,
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(redirectURI)},
TokenLifetimes: configv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: tokenLifetimesIDTokenSeconds},
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(redirectURI)},
TokenLifetimes: supervisorconfigv1alpha1.OIDCClientTokenLifetimes{IDTokenSeconds: tokenLifetimesIDTokenSeconds},
},
}
}
// OIDCClientValidatorFunc is an interface-like type that allows these test helpers to avoid having a direct dependency
// on the production code, to avoid circular module dependencies. Implemented by oidcclientvalidator.Validate.
type OIDCClientValidatorFunc func(oidcClient *configv1alpha1.OIDCClient, secret *corev1.Secret, minBcryptCost int) (bool, []*metav1.Condition, []string)
type OIDCClientValidatorFunc func(oidcClient *supervisorconfigv1alpha1.OIDCClient, secret *corev1.Secret, minBcryptCost int) (bool, []*metav1.Condition, []string)
// FullyCapableOIDCClientAndStorageSecret returns an OIDC client which is allowed to use all grant types and all scopes
// that are supported by the Supervisor for dynamic clients, along with a corresponding client secret storage Secret.
@@ -78,10 +78,10 @@ func FullyCapableOIDCClientAndStorageSecret(
tokenLifetimesIDTokenSeconds *int32,
hashes []string,
validateFunc OIDCClientValidatorFunc,
) (*configv1alpha1.OIDCClient, *corev1.Secret) {
) (*supervisorconfigv1alpha1.OIDCClient, *corev1.Secret) {
allScopes := allDynamicClientScopes()
allGrantTypes := []configv1alpha1.GrantType{
allGrantTypes := []supervisorconfigv1alpha1.GrantType{
"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token",
}
@@ -96,13 +96,13 @@ func OIDCClientAndStorageSecret(
namespace string,
clientID string,
clientUID string,
allowedGrantTypes []configv1alpha1.GrantType,
allowedScopes []configv1alpha1.Scope,
allowedGrantTypes []supervisorconfigv1alpha1.GrantType,
allowedScopes []supervisorconfigv1alpha1.Scope,
redirectURI string,
tokenLifetimesIDTokenSeconds *int32,
hashes []string,
validateFunc OIDCClientValidatorFunc,
) (*configv1alpha1.OIDCClient, *corev1.Secret) {
) (*supervisorconfigv1alpha1.OIDCClient, *corev1.Secret) {
oidcClient := newOIDCClient(namespace, clientID, clientUID, redirectURI, allowedGrantTypes, allowedScopes, tokenLifetimesIDTokenSeconds)
secret := OIDCClientSecretStorageSecretForUID(t, namespace, clientUID, hashes)
@@ -46,7 +46,7 @@ func RequireAuthCodeRegexpMatch(
wantDownstreamClientID string,
wantDownstreamRedirectURI string,
wantCustomSessionData *psession.CustomSessionData,
wantDownstreamAdditionalClaims map[string]interface{},
wantDownstreamAdditionalClaims map[string]any,
) {
t.Helper()
@@ -138,7 +138,7 @@ func validateAuthcodeStorage(
wantDownstreamClientID string,
wantDownstreamRedirectURI string,
wantCustomSessionData *psession.CustomSessionData,
wantDownstreamAdditionalClaims map[string]interface{},
wantDownstreamAdditionalClaims map[string]any,
) (*fosite.Request, *psession.PinnipedSession) {
t.Helper()
@@ -221,8 +221,8 @@ func validateAuthcodeStorage(
require.Nil(t, actualDownstreamIDTokenGroups)
}
if len(wantDownstreamAdditionalClaims) > 0 {
actualAdditionalClaims, ok := actualClaims.Get("additionalClaims").(map[string]interface{})
require.True(t, ok, "expected additionalClaims to be a map[string]interface{}")
actualAdditionalClaims, ok := actualClaims.Get("additionalClaims").(map[string]any)
require.True(t, ok, "expected additionalClaims to be a map[string]any")
require.Equal(t, wantDownstreamAdditionalClaims, actualAdditionalClaims)
} else {
require.NotContains(t, actualClaims.Extra, "additionalClaims", "additionalClaims must not be present when there are no wanted additional claims")
@@ -293,7 +293,7 @@ type TestUpstreamOIDCIdentityProviderBuilder struct {
resourceUID types.UID
clientID string
scopes []string
idToken map[string]interface{}
idToken map[string]any
refreshToken *oidctypes.RefreshToken
accessToken *oidctypes.AccessToken
usernameClaim string
@@ -374,9 +374,9 @@ func (u *TestUpstreamOIDCIdentityProviderBuilder) WithoutGroupsClaim() *TestUpst
return u
}
func (u *TestUpstreamOIDCIdentityProviderBuilder) WithIDTokenClaim(name string, value interface{}) *TestUpstreamOIDCIdentityProviderBuilder {
func (u *TestUpstreamOIDCIdentityProviderBuilder) WithIDTokenClaim(name string, value any) *TestUpstreamOIDCIdentityProviderBuilder {
if u.idToken == nil {
u.idToken = map[string]interface{}{}
u.idToken = map[string]any{}
}
u.idToken[name] = value
return u
+14 -14
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package testlogger
@@ -28,7 +28,7 @@ func newStdLogger(std stdr.StdLogger) logr.Logger {
type logger struct {
std stdr.StdLogger
prefix string
values []interface{}
values []any
}
func (l logger) clone() logger {
@@ -37,8 +37,8 @@ func (l logger) clone() logger {
return out
}
func copySlice(in []interface{}) []interface{} {
out := make([]interface{}, len(in))
func copySlice(in []any) []any {
out := make([]any, len(in))
copy(out, in)
return out
}
@@ -60,15 +60,15 @@ func framesToCaller() int {
return 1 // something went wrong, this is safe
}
func flatten(kvList ...interface{}) string {
func flatten(kvList ...any) string {
keys := make([]string, 0, len(kvList))
vals := make(map[string]interface{}, len(kvList))
vals := make(map[string]any, len(kvList))
for i := 0; i < len(kvList); i += 2 {
k, ok := kvList[i].(string)
if !ok {
panic(fmt.Sprintf("key is not a string: %s", pretty(kvList[i])))
}
var v interface{}
var v any
if i+1 < len(kvList) {
v = kvList[i+1]
}
@@ -89,14 +89,14 @@ func flatten(kvList ...interface{}) string {
return buf.String()
}
func pretty(value interface{}) string {
func pretty(value any) string {
jb, _ := json.Marshal(value)
return string(jb)
}
func (l logger) Info(level int, msg string, kvList ...interface{}) {
func (l logger) Info(level int, msg string, kvList ...any) {
if l.Enabled(level) {
builtin := make([]interface{}, 0, 4)
builtin := make([]any, 0, 4)
builtin = append(builtin, "level", level, "msg", msg)
builtinStr := flatten(builtin...)
fixedStr := flatten(l.values...)
@@ -109,11 +109,11 @@ func (l logger) Enabled(_level int) bool {
return true
}
func (l logger) Error(err error, msg string, kvList ...interface{}) {
builtin := make([]interface{}, 0, 4)
func (l logger) Error(err error, msg string, kvList ...any) {
builtin := make([]any, 0, 4)
builtin = append(builtin, "msg", msg)
builtinStr := flatten(builtin...)
var loggableErr interface{}
var loggableErr any
if err != nil {
loggableErr = err.Error()
}
@@ -152,7 +152,7 @@ func (l logger) WithName(name string) logr.LogSink {
// WithValues returns a new logr.Logger with the specified key-and-values
// saved.
func (l logger) WithValues(kvList ...interface{}) logr.LogSink {
func (l logger) WithValues(kvList ...any) logr.LogSink {
lgr := l.clone()
lgr.values = append(lgr.values, kvList...)
return lgr
+4 -4
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package testutil
@@ -37,7 +37,7 @@ func (log *TranscriptLogger) Transcript() []TranscriptLogMessage {
return result
}
func (log *TranscriptLogger) Info(_level int, msg string, keysAndValues ...interface{}) {
func (log *TranscriptLogger) Info(_level int, msg string, keysAndValues ...any) {
log.lock.Lock()
defer log.lock.Unlock()
log.transcript = append(log.transcript, TranscriptLogMessage{
@@ -46,7 +46,7 @@ func (log *TranscriptLogger) Info(_level int, msg string, keysAndValues ...inter
})
}
func (log *TranscriptLogger) Error(_ error, msg string, _ ...interface{}) {
func (log *TranscriptLogger) Error(_ error, msg string, _ ...any) {
log.lock.Lock()
defer log.lock.Unlock()
log.transcript = append(log.transcript, TranscriptLogMessage{
@@ -67,7 +67,7 @@ func (log *TranscriptLogger) WithName(_ string) logr.LogSink {
return log
}
func (log *TranscriptLogger) WithValues(_ ...interface{}) logr.LogSink {
func (log *TranscriptLogger) WithValues(_ ...any) logr.LogSink {
return log
}
+6 -6
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package upstreamoidc implements an abstraction of upstream OIDC provider interactions.
@@ -48,7 +48,7 @@ type ProviderConfig struct {
RevocationURL *url.URL // will commonly be nil: many providers do not offer this
Provider interface {
Verifier(*coreosoidc.Config) *coreosoidc.IDTokenVerifier
Claims(v interface{}) error
Claims(v any) error
UserInfo(ctx context.Context, tokenSource oauth2.TokenSource) (*coreosoidc.UserInfo, error)
}
}
@@ -282,7 +282,7 @@ func (p *ProviderConfig) tryRevokeToken(
// ValidateTokenAndMergeWithUserInfo will validate the ID token. It will also merge the claims from the userinfo endpoint response,
// if the provider offers the userinfo endpoint.
func (p *ProviderConfig) ValidateTokenAndMergeWithUserInfo(ctx context.Context, tok *oauth2.Token, expectedIDTokenNonce nonce.Nonce, requireIDToken bool, requireUserInfo bool) (*oidctypes.Token, error) {
var validatedClaims = make(map[string]interface{})
var validatedClaims = make(map[string]any)
var idTokenExpiry time.Time
// if we require the id token, make sure we have it.
@@ -319,7 +319,7 @@ func (p *ProviderConfig) ValidateTokenAndMergeWithUserInfo(ctx context.Context,
}, nil
}
func (p *ProviderConfig) validateIDToken(ctx context.Context, tok *oauth2.Token, expectedIDTokenNonce nonce.Nonce, validatedClaims map[string]interface{}, requireIDToken bool) (time.Time, string, error) {
func (p *ProviderConfig) validateIDToken(ctx context.Context, tok *oauth2.Token, expectedIDTokenNonce nonce.Nonce, validatedClaims map[string]any, requireIDToken bool) (time.Time, string, error) {
idTok, hasIDTok := tok.Extra("id_token").(string)
if !hasIDTok && !requireIDToken {
return time.Time{}, "", nil // exit early
@@ -351,7 +351,7 @@ func (p *ProviderConfig) validateIDToken(ctx context.Context, tok *oauth2.Token,
return idTokenExpiry, idTok, nil
}
func (p *ProviderConfig) maybeFetchUserInfoAndMergeClaims(ctx context.Context, tok *oauth2.Token, claims map[string]interface{}, requireIDToken bool, requireUserInfo bool) error {
func (p *ProviderConfig) maybeFetchUserInfoAndMergeClaims(ctx context.Context, tok *oauth2.Token, claims map[string]any, requireIDToken bool, requireUserInfo bool) error {
idTokenSubject, _ := claims[oidcapi.IDTokenClaimSubject].(string)
userInfo, err := p.maybeFetchUserInfo(ctx, tok, requireUserInfo)
@@ -414,7 +414,7 @@ func (p *ProviderConfig) maybeFetchUserInfo(ctx context.Context, tok *oauth2.Tok
return userInfo, nil
}
func maybeLogClaims(msg, name string, claims map[string]interface{}) {
func maybeLogClaims(msg, name string, claims map[string]any) {
if plog.Enabled(plog.LevelAll) { // log keys and values at all level
data, _ := json.Marshal(claims) // nothing we can do if it fails, but it really never should
plog.All(msg, "providerName", name, "claims", string(data))
+35 -35
View File
@@ -126,7 +126,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: validIDToken,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "bar",
"bat": "baz",
"aud": "test-client-id",
@@ -154,7 +154,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: validIDToken,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "awesomeness", // overwrite existing claim
"bat": "baz",
"aud": "test-client-id",
@@ -227,7 +227,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: invalidSubClaim,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "bar",
"bat": "baz",
"aud": "test-client-id",
@@ -328,7 +328,7 @@ func TestProviderConfig(t *testing.T) {
wantErr string
wantToken *oauth2.Token
wantTokenExtras map[string]interface{}
wantTokenExtras map[string]any
}{
{
name: "success when the server returns all tokens in the refresh result",
@@ -344,7 +344,7 @@ func TestProviderConfig(t *testing.T) {
TokenType: "test-token-type",
Expiry: time.Now().Add(42 * time.Second),
},
wantTokenExtras: map[string]interface{}{
wantTokenExtras: map[string]any{
// the ID token only appears in the extras map
"id_token": "test-id-token",
// the library also repeats all the other keys/values returned by the server in the raw extras map
@@ -371,7 +371,7 @@ func TestProviderConfig(t *testing.T) {
TokenType: "test-token-type",
Expiry: time.Now().Add(42 * time.Second),
},
wantTokenExtras: map[string]interface{}{
wantTokenExtras: map[string]any{
// the ID token only appears in the extras map
"id_token": "test-id-token",
// the library also repeats all the other keys/values returned by the server in the raw extras map
@@ -396,7 +396,7 @@ func TestProviderConfig(t *testing.T) {
TokenType: "test-token-type",
Expiry: time.Now().Add(42 * time.Second),
},
wantTokenExtras: map[string]interface{}{
wantTokenExtras: map[string]any{
// the library also repeats all the other keys/values returned by the server in the raw extras map
"access_token": "test-access-token",
"refresh_token": "test-refresh-token",
@@ -754,7 +754,7 @@ func TestProviderConfig(t *testing.T) {
}{
{
name: "token with id, access and refresh tokens, valid nonce, and no userinfo",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -769,7 +769,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: goodIDToken,
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer",
"nonce": "some-nonce",
"sub": "some-subject",
@@ -779,7 +779,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "id token not required but is provided",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: false,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -795,7 +795,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: goodIDToken,
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer",
"nonce": "some-nonce",
"sub": "some-subject",
@@ -806,7 +806,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "token with id, access and refresh tokens, valid nonce, and userinfo with a value that doesn't exist in the id token",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -822,7 +822,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: goodIDToken,
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer",
"nonce": "some-nonce",
"sub": "some-subject",
@@ -833,7 +833,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "userinfo is required, token with id, access and refresh tokens, valid nonce, and userinfo with a value that doesn't exist in the id token",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: true,
requireUserInfo: true,
@@ -850,7 +850,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: goodIDToken,
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer",
"nonce": "some-nonce",
"sub": "some-subject",
@@ -861,7 +861,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "claims from userinfo override id token claims",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzb21lLXN1YmplY3QiLCJuYW1lIjoiSm9obiBEb2UiLCJpc3MiOiJzb21lLWlzc3VlciIsIm5vbmNlIjoic29tZS1ub25jZSJ9.sBWi3_4cfGwrmMFZWkCghw4uvCnHN35h9xNX1gkwOtj6Oz_yKqpj7wfO4AqeWsRyrDGnkmIZbVuhAAJqPSi4GlNzN4NU8zh53PGDUpFlpDI1dvqDjIRb9iIEJpRIj34--Sz41H0ooxviIzvUdZFvQlaSzLOqgjR3ddHe2urhbtUuz_DsabP84AWo2DSg0y3ull6DRvk_DvzC6HNN8JwVi08fFvvV9BVq8kjdVeob7gajJkuGSTjsxNZGs5rbBuxBx0MZTQ8boR1fDNdG70GoIb4SsCoBSs7pZxtmGZPHInteY1SilHDDDmpQuE-LvSmvvPN_Cyk1d3eS-IR7hBbCAA"}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzb21lLXN1YmplY3QiLCJuYW1lIjoiSm9obiBEb2UiLCJpc3MiOiJzb21lLWlzc3VlciIsIm5vbmNlIjoic29tZS1ub25jZSJ9.sBWi3_4cfGwrmMFZWkCghw4uvCnHN35h9xNX1gkwOtj6Oz_yKqpj7wfO4AqeWsRyrDGnkmIZbVuhAAJqPSi4GlNzN4NU8zh53PGDUpFlpDI1dvqDjIRb9iIEJpRIj34--Sz41H0ooxviIzvUdZFvQlaSzLOqgjR3ddHe2urhbtUuz_DsabP84AWo2DSg0y3ull6DRvk_DvzC6HNN8JwVi08fFvvV9BVq8kjdVeob7gajJkuGSTjsxNZGs5rbBuxBx0MZTQ8boR1fDNdG70GoIb4SsCoBSs7pZxtmGZPHInteY1SilHDDDmpQuE-LvSmvvPN_Cyk1d3eS-IR7hBbCAA"}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -877,7 +877,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzb21lLXN1YmplY3QiLCJuYW1lIjoiSm9obiBEb2UiLCJpc3MiOiJzb21lLWlzc3VlciIsIm5vbmNlIjoic29tZS1ub25jZSJ9.sBWi3_4cfGwrmMFZWkCghw4uvCnHN35h9xNX1gkwOtj6Oz_yKqpj7wfO4AqeWsRyrDGnkmIZbVuhAAJqPSi4GlNzN4NU8zh53PGDUpFlpDI1dvqDjIRb9iIEJpRIj34--Sz41H0ooxviIzvUdZFvQlaSzLOqgjR3ddHe2urhbtUuz_DsabP84AWo2DSg0y3ull6DRvk_DvzC6HNN8JwVi08fFvvV9BVq8kjdVeob7gajJkuGSTjsxNZGs5rbBuxBx0MZTQ8boR1fDNdG70GoIb4SsCoBSs7pZxtmGZPHInteY1SilHDDDmpQuE-LvSmvvPN_Cyk1d3eS-IR7hBbCAA",
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer", // takes the issuer from the ID token, since the userinfo one is unreliable.
"nonce": "some-nonce",
"sub": "some-subject",
@@ -888,7 +888,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "token with id, access and refresh tokens and valid nonce, but userinfo has a different issuer",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -904,7 +904,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: goodIDToken,
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer", // takes the issuer from the ID token, since the userinfo one is unreliable.
"nonce": "some-nonce",
"sub": "some-subject",
@@ -915,7 +915,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "token with id, access and refresh tokens and valid nonce, but no userinfo endpoint from discovery and it's not required",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: true,
requireUserInfo: false,
@@ -931,7 +931,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: goodIDToken,
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer",
"nonce": "some-nonce",
"sub": "some-subject",
@@ -957,7 +957,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: "",
Claims: map[string]interface{}{
Claims: map[string]any{
"sub": "some-subject",
"name": "Pinny TheSeal",
},
@@ -980,13 +980,13 @@ func TestProviderConfig(t *testing.T) {
Token: "test-initial-refresh-token",
},
IDToken: &oidctypes.IDToken{
Claims: map[string]interface{}{},
Claims: map[string]any{},
},
},
},
{
name: "token with id, access and refresh tokens, valid nonce, and userinfo subject that doesn't match",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -995,7 +995,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "id token not required but is provided, and subjects don't match",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-nonce",
requireIDToken: false,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -1004,7 +1004,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "invalid id token",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": "not-an-id-token"}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": "not-an-id-token"}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -1013,7 +1013,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "invalid nonce",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": goodIDToken}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": goodIDToken}),
nonce: "some-other-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -1057,7 +1057,7 @@ func TestProviderConfig(t *testing.T) {
},
{
name: "id token missing subject, skip userinfo check",
tok: testTokenWithoutIDToken.WithExtra(map[string]interface{}{"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJpc3MiOiJzb21lLWlzc3VlciIsIm5vbmNlIjoic29tZS1ub25jZSJ9.aIhrhikAnQ4Mb1g6RAT08qqflT2LLLi2yj4F2S4zud8nYad4tfEd2ITVJ4Njdjf70ubqyzZ6XxojtC4OqaWbDaQOcd95sd3PW58SYrf4NMvEStFkcMG0HMhJEZLVGnuJQstuq3G9h5Z5bFCkx4mFNo5ho_isBWyHpk-uF14duXXlIDB10SnyZ9dRbcmu-3mMOq0g4oCUPEDiHWkv-Rf70Mk0harL2xvcpxlSMLK4glDfiiki5gl6IReIo4rTVosXAqv3JmjLDeVLtJQRG6F8YcIlDCIfUEUfk0GeYacBVjoDIO570ywVJy1LGvyUuvgXNQUjq2JgzCfb8HWGp7iJdQ"}),
tok: testTokenWithoutIDToken.WithExtra(map[string]any{"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJpc3MiOiJzb21lLWlzc3VlciIsIm5vbmNlIjoic29tZS1ub25jZSJ9.aIhrhikAnQ4Mb1g6RAT08qqflT2LLLi2yj4F2S4zud8nYad4tfEd2ITVJ4Njdjf70ubqyzZ6XxojtC4OqaWbDaQOcd95sd3PW58SYrf4NMvEStFkcMG0HMhJEZLVGnuJQstuq3G9h5Z5bFCkx4mFNo5ho_isBWyHpk-uF14duXXlIDB10SnyZ9dRbcmu-3mMOq0g4oCUPEDiHWkv-Rf70Mk0harL2xvcpxlSMLK4glDfiiki5gl6IReIo4rTVosXAqv3JmjLDeVLtJQRG6F8YcIlDCIfUEUfk0GeYacBVjoDIO570ywVJy1LGvyUuvgXNQUjq2JgzCfb8HWGp7iJdQ"}),
nonce: "some-nonce",
requireIDToken: true,
rawClaims: []byte(`{"userinfo_endpoint": "not-empty"}`),
@@ -1073,7 +1073,7 @@ func TestProviderConfig(t *testing.T) {
},
IDToken: &oidctypes.IDToken{
Token: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJpc3MiOiJzb21lLWlzc3VlciIsIm5vbmNlIjoic29tZS1ub25jZSJ9.aIhrhikAnQ4Mb1g6RAT08qqflT2LLLi2yj4F2S4zud8nYad4tfEd2ITVJ4Njdjf70ubqyzZ6XxojtC4OqaWbDaQOcd95sd3PW58SYrf4NMvEStFkcMG0HMhJEZLVGnuJQstuq3G9h5Z5bFCkx4mFNo5ho_isBWyHpk-uF14duXXlIDB10SnyZ9dRbcmu-3mMOq0g4oCUPEDiHWkv-Rf70Mk0harL2xvcpxlSMLK4glDfiiki5gl6IReIo4rTVosXAqv3JmjLDeVLtJQRG6F8YcIlDCIfUEUfk0GeYacBVjoDIO570ywVJy1LGvyUuvgXNQUjq2JgzCfb8HWGp7iJdQ",
Claims: map[string]interface{}{
Claims: map[string]any{
"iss": "some-issuer",
"name": "John Doe",
"nonce": "some-nonce",
@@ -1176,7 +1176,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: invalidNonceIDToken,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"aud": "test-client-id",
"iat": 1.602283741e+09,
"jti": "test-jti",
@@ -1204,7 +1204,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: validIDToken,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "bar",
"bat": "baz",
"aud": "test-client-id",
@@ -1234,7 +1234,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: validIDToken,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "bar",
"bat": "baz",
"aud": "test-client-id",
@@ -1285,7 +1285,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: validIDToken,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "awesomeness", // overwrite existing claim
"bat": "baz",
"aud": "test-client-id",
@@ -1316,7 +1316,7 @@ func TestProviderConfig(t *testing.T) {
IDToken: &oidctypes.IDToken{
Token: invalidSubClaim,
Expiry: metav1.Time{},
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "bar",
"bat": "baz",
"aud": "test-client-id",
@@ -1438,7 +1438,7 @@ func (m *mockProvider) Verifier(_ *coreosoidc.Config) *coreosoidc.IDTokenVerifie
return mockVerifier()
}
func (m *mockProvider) Claims(v interface{}) error {
func (m *mockProvider) Claims(v any) error {
return json.Unmarshal(m.rawClaims, v)
}
@@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package valuelesscontext
@@ -11,4 +11,4 @@ func New(ctx context.Context) context.Context {
type valuelessContext struct{ context.Context }
func (valuelessContext) Value(interface{}) interface{} { return nil }
func (valuelessContext) Value(any) any { return nil }
+2 -2
View File
@@ -37,9 +37,9 @@ var validSession = sessionCache{
IDToken: &oidctypes.IDToken{
Token: "test-id-token",
Expiry: metav1.NewTime(time.Date(2020, 10, 20, 19, 42, 07, 0, time.UTC).Local()),
Claims: map[string]interface{}{
Claims: map[string]any{
"foo": "bar",
"nested": map[string]interface{}{
"nested": map[string]any{
"key1": "value1",
"key2": "value2",
},
+8 -8
View File
@@ -2629,7 +2629,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
IDToken: &oidctypes.IDToken{
Token: testToken.IDToken.Token,
Expiry: testToken.IDToken.Expiry,
Claims: map[string]interface{}{"aud": "request-this-test-audience"},
Claims: map[string]any{"aud": "request-this-test-audience"},
},
RefreshToken: testToken.RefreshToken,
}}
@@ -2659,7 +2659,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
IDToken: &oidctypes.IDToken{
Token: testToken.IDToken.Token,
Expiry: testToken.IDToken.Expiry,
Claims: map[string]interface{}{"aud": "request-this-test-audience"},
Claims: map[string]any{"aud": "request-this-test-audience"},
},
RefreshToken: testToken.RefreshToken,
},
@@ -2675,7 +2675,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
IDToken: &oidctypes.IDToken{
Token: testToken.IDToken.Token,
Expiry: metav1.NewTime(time.Now().Add(9 * time.Minute)), // less than Now() + minIDTokenValidity
Claims: map[string]interface{}{"aud": "test-custom-request-audience"},
Claims: map[string]any{"aud": "test-custom-request-audience"},
},
RefreshToken: testToken.RefreshToken,
}}
@@ -2691,7 +2691,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
require.Equal(t, &oidctypes.IDToken{
Token: testToken.IDToken.Token,
Expiry: metav1.NewTime(fakeUniqueTime),
Claims: map[string]interface{}{"aud": "test-custom-request-audience"},
Claims: map[string]any{"aud": "test-custom-request-audience"},
}, cache.sawPutTokens[0].IDToken)
})
require.NoError(t, WithClient(buildHTTPClientForPEM(successServerCA))(h))
@@ -2707,7 +2707,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
IDToken: &oidctypes.IDToken{
Token: testToken.IDToken.Token,
Expiry: metav1.NewTime(fakeUniqueTime), // less than Now() + minIDTokenValidity but does not matter because this is a freshly refreshed ID token
Claims: map[string]interface{}{"aud": "test-custom-request-audience"},
Claims: map[string]any{"aud": "test-custom-request-audience"},
},
RefreshToken: testToken.RefreshToken,
}, nil)
@@ -2732,7 +2732,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo
IDToken: &oidctypes.IDToken{
Token: testToken.IDToken.Token,
Expiry: metav1.NewTime(fakeUniqueTime),
Claims: map[string]interface{}{"aud": "test-custom-request-audience"},
Claims: map[string]any{"aud": "test-custom-request-audience"},
},
RefreshToken: testToken.RefreshToken,
},
@@ -3452,11 +3452,11 @@ func mockUpstream(t *testing.T) *mockupstreamoidcidentityprovider.MockUpstreamOI
// hasAccessTokenMatcher is a gomock.Matcher that expects an *oauth2.Token with a particular access token.
type hasAccessTokenMatcher struct{ expected string }
func (m hasAccessTokenMatcher) Matches(arg interface{}) bool {
func (m hasAccessTokenMatcher) Matches(arg any) bool {
return arg.(*oauth2.Token).AccessToken == m.expected
}
func (m hasAccessTokenMatcher) Got(got interface{}) string {
func (m hasAccessTokenMatcher) Got(got any) string {
return got.(*oauth2.Token).AccessToken
}
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Package oidctypes provides core data types for OIDC token structures.
@@ -33,7 +33,7 @@ type IDToken struct {
Expiry metav1.Time `json:"expiryTimestamp,omitempty"`
// Claims are the claims expressed by the Token.
Claims map[string]interface{} `json:"claims,omitempty"`
Claims map[string]any `json:"claims,omitempty"`
}
// Token contains the elements of an OIDC session.
+3 -3
View File
@@ -106,9 +106,9 @@ func TestCLIGetKubeconfigStaticToken_Parallel(t *testing.T) {
type testingT interface {
Helper()
Errorf(format string, args ...interface{})
Errorf(format string, args ...any)
FailNow()
Logf(format string, args ...interface{})
Logf(format string, args ...any)
}
func runPinnipedCLI(t testingT, envVars []string, pinnipedExe string, args ...string) (string, string) {
@@ -194,7 +194,7 @@ func TestCLILoginOIDC_Browser(t *testing.T) {
require.NotEmpty(t, credOutput.Status.Token)
jws, err := jose.ParseSigned(credOutput.Status.Token)
require.NoError(t, err)
claims := map[string]interface{}{}
claims := map[string]any{}
require.NoError(t, json.Unmarshal(jws.UnsafePayloadWithoutVerification(), &claims))
require.Equal(t, env.CLIUpstreamOIDC.Issuer, claims["iss"])
require.Equal(t, env.CLIUpstreamOIDC.ClientID, claims["aud"])
+38 -38
View File
@@ -35,7 +35,7 @@ import (
"k8s.io/utils/ptr"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorclient "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/certauthority"
@@ -105,11 +105,11 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
// Create the downstream FederationDomain and expect it to go into the success status condition.
federationDomain := testlib.CreateTestFederationDomain(topSetupCtx, t,
configv1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuerURL.String(),
TLS: &configv1alpha1.FederationDomainTLSSpec{SecretName: certSecret.Name},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecret.Name},
},
configv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created
supervisorconfigv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created
)
// Create a JWTAuthenticator that will validate the tokens from the downstream issuer.
@@ -163,7 +163,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -249,7 +249,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -337,7 +337,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -461,7 +461,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -592,7 +592,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -665,7 +665,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -729,7 +729,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
createdProvider := setupClusterForEndToEndLDAPTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -788,7 +788,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
createdProvider := setupClusterForEndToEndLDAPTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -851,7 +851,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
createdProvider := setupClusterForEndToEndLDAPTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -922,7 +922,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames
createdProvider := setupClusterForEndToEndActiveDirectoryTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -981,7 +981,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames
createdProvider := setupClusterForEndToEndActiveDirectoryTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -1054,7 +1054,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
createdProvider := setupClusterForEndToEndLDAPTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -1109,7 +1109,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames
createdProvider := setupClusterForEndToEndActiveDirectoryTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -1164,7 +1164,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
expectedGroups := env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs
createdProvider := setupClusterForEndToEndLDAPTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -1241,7 +1241,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
createdLDAPProvider := setupClusterForEndToEndLDAPTest(t, expectedDownstreamLDAPUsername, env)
// Having one IDP should put the FederationDomain into a ready state.
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Create a ClusterRoleBinding to give our test user from the upstream read-only access to the cluster.
@@ -1275,7 +1275,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
}, idpv1alpha1.PhaseReady)
// Having a second IDP should put the FederationDomain back into an error state until we tell it which one to use.
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Update the FederationDomain to use the two IDPs.
@@ -1290,7 +1290,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
ldapIDPDisplayName := "My LDAP IDP 💾"
oidcIDPDisplayName := "My OIDC IDP 🚀"
gotFederationDomain.Spec.IdentityProviders = []configv1alpha1.FederationDomainIdentityProvider{
gotFederationDomain.Spec.IdentityProviders = []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: ldapIDPDisplayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -1298,21 +1298,21 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
Kind: "LDAPIdentityProvider",
Name: createdLDAPProvider.Name,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Constants: []configv1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "allowedUser", Type: "string", StringValue: expectedUpstreamLDAPUsername},
{Name: "allowedUsers", Type: "stringList", StringListValue: []string{"someone else", expectedUpstreamLDAPUsername, "someone else"}},
},
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "policy/v1", Expression: `username == strConst.allowedUser && username in strListConst.allowedUsers`, Message: "only special users allowed"},
{Type: "username/v1", Expression: fmt.Sprintf(`"%s" + username`, downstreamPrefix)},
{Type: "groups/v1", Expression: fmt.Sprintf(`groups.map(g, "%s" + g)`, downstreamPrefix)},
},
Examples: []configv1alpha1.FederationDomainTransformsExample{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{
Username: expectedUpstreamLDAPUsername,
Groups: []string{"a", "b"},
Expects: configv1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: expectedDownstreamLDAPUsername,
Groups: []string{downstreamPrefix + "a", downstreamPrefix + "b"},
},
@@ -1320,7 +1320,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
{
Username: "someone other user",
Groups: []string{"a", "b"},
Expects: configv1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
Message: "only special users allowed",
},
@@ -1335,21 +1335,21 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
Kind: "OIDCIdentityProvider",
Name: createdOIDCProvider.Name,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Constants: []configv1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "allowedUser", Type: "string", StringValue: expectedUpstreamOIDCUsername},
{Name: "allowedUsers", Type: "stringList", StringListValue: []string{"someone else", expectedUpstreamOIDCUsername, "someone else"}},
},
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "policy/v1", Expression: `username == strConst.allowedUser && username in strListConst.allowedUsers`, Message: "only special users allowed"},
{Type: "username/v1", Expression: fmt.Sprintf(`"%s" + username`, downstreamPrefix)},
{Type: "groups/v1", Expression: fmt.Sprintf(`groups.map(g, "%s" + g)`, downstreamPrefix)},
},
Examples: []configv1alpha1.FederationDomainTransformsExample{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{
Username: expectedUpstreamOIDCUsername,
Groups: []string{"a", "b"},
Expects: configv1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: expectedDownstreamOIDCUsername,
Groups: []string{downstreamPrefix + "a", downstreamPrefix + "b"},
},
@@ -1357,7 +1357,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
{
Username: "someone other user",
Groups: []string{"a", "b"},
Expects: configv1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
Message: "only special users allowed",
},
@@ -1370,7 +1370,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
require.NoError(t, err)
// The FederationDomain should be valid after the above update.
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -1504,7 +1504,7 @@ func TestE2EFullIntegration_Browser(t *testing.T) {
requireEventually.Equal(fd.Generation, fd.Status.Conditions[0].ObservedGeneration)
}, 20*time.Second, 250*time.Millisecond)
// The FederationDomain should be valid after the above update.
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(testCtx, t, federationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(testCtx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Log out so we can try fresh logins again.
@@ -1968,7 +1968,7 @@ func requireUserCanUseKubectlWithoutAuthenticatingAgain(
ctx context.Context,
t *testing.T,
env *testlib.TestEnv,
downstream *configv1alpha1.FederationDomain,
downstream *supervisorconfigv1alpha1.FederationDomain,
upstreamProviderName string,
kubeconfigPath string,
sessionCachePath string,
@@ -2009,8 +2009,8 @@ func requireUserCanUseKubectlWithoutAuthenticatingAgain(
if expectedGroups == nil {
require.Nil(t, idTokenClaims["groups"])
} else {
// The groups claim in the file ends up as an []interface{}, so adjust our expectation to match.
expectedGroupsAsEmptyInterfaces := make([]interface{}, 0, len(expectedGroups))
// The groups claim in the file ends up as an []any, so adjust our expectation to match.
expectedGroupsAsEmptyInterfaces := make([]any, 0, len(expectedGroups))
for _, g := range expectedGroups {
expectedGroupsAsEmptyInterfaces = append(expectedGroupsAsEmptyInterfaces, g)
}
+1 -1
View File
@@ -147,7 +147,7 @@ func (t *fakeT) FailNow() {
t.Errorf("fakeT ignored FailNow")
}
func (t *fakeT) Errorf(format string, args ...interface{}) {
func (t *fakeT) Errorf(format string, args ...any) {
t.Cleanup(func() {
if !t.Failed() {
return
+30 -30
View File
@@ -25,7 +25,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/utils/strings/slices"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
supervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
"go.pinniped.dev/internal/certauthority"
@@ -131,15 +131,15 @@ func TestSupervisorOIDCDiscovery_Disruptive(t *testing.T) {
// When the same issuer is added twice, both issuers are marked as duplicates, and neither provider is serving.
config6Duplicate1, _ := requireCreatingFederationDomainCausesDiscoveryEndpointsToAppear(ctx, t, scheme, addr, caBundle, issuer6, client)
config6Duplicate2 := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{Issuer: issuer6}, v1alpha1.FederationDomainPhaseError)
requireStatus(t, client, ns, config6Duplicate1.Name, v1alpha1.FederationDomainPhaseError, withFalseConditions([]string{"Ready", "IssuerIsUnique"}))
requireStatus(t, client, ns, config6Duplicate2.Name, v1alpha1.FederationDomainPhaseError, withFalseConditions([]string{"Ready", "IssuerIsUnique"}))
config6Duplicate2 := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{Issuer: issuer6}, supervisorconfigv1alpha1.FederationDomainPhaseError)
requireStatus(t, client, ns, config6Duplicate1.Name, supervisorconfigv1alpha1.FederationDomainPhaseError, withFalseConditions([]string{"Ready", "IssuerIsUnique"}))
requireStatus(t, client, ns, config6Duplicate2.Name, supervisorconfigv1alpha1.FederationDomainPhaseError, withFalseConditions([]string{"Ready", "IssuerIsUnique"}))
requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, issuer6)
// If we delete the first duplicate issuer, the second duplicate issuer starts serving.
requireDelete(t, client, ns, config6Duplicate1.Name)
requireWellKnownEndpointIsWorking(t, scheme, addr, caBundle, issuer6, nil)
requireStatus(t, client, ns, config6Duplicate2.Name, v1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
requireStatus(t, client, ns, config6Duplicate2.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
// When we finally delete all issuers, the endpoint should be down.
requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(t, config6Duplicate2, client, ns, scheme, addr, caBundle, issuer6)
@@ -150,8 +150,8 @@ func TestSupervisorOIDCDiscovery_Disruptive(t *testing.T) {
requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(t, config7, client, ns, scheme, addr, caBundle, issuer7)
// When we create a provider with an invalid issuer, the status is set to invalid.
badConfig := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{Issuer: badIssuer}, v1alpha1.FederationDomainPhaseError)
requireStatus(t, client, ns, badConfig.Name, v1alpha1.FederationDomainPhaseError, withFalseConditions([]string{"Ready", "IssuerURLValid"}))
badConfig := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{Issuer: badIssuer}, supervisorconfigv1alpha1.FederationDomainPhaseError)
requireStatus(t, client, ns, badConfig.Name, supervisorconfigv1alpha1.FederationDomainPhaseError, withFalseConditions([]string{"Ready", "IssuerURLValid"}))
requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, badIssuer)
requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(t, badConfig, client, ns, scheme, addr, caBundle, badIssuer)
})
@@ -185,11 +185,11 @@ func TestSupervisorTLSTerminationWithSNI_Disruptive(t *testing.T) {
// Create an FederationDomain with a spec.tls.secretName.
federationDomain1 := testlib.CreateTestFederationDomain(ctx, t,
v1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuer1,
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: certSecretName1},
}, v1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, v1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecretName1},
}, supervisorconfigv1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
// The spec.tls.secretName Secret does not exist, so the endpoints should fail with TLS errors.
requireEndpointHasBootstrapTLSErrorBecauseCertificatesAreNotReady(t, issuer1)
@@ -207,7 +207,7 @@ func TestSupervisorTLSTerminationWithSNI_Disruptive(t *testing.T) {
if err != nil {
return err
}
federationDomain1LatestVersion.Spec.TLS = &v1alpha1.FederationDomainTLSSpec{SecretName: certSecretName1update}
federationDomain1LatestVersion.Spec.TLS = &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecretName1update}
_, err = pinnipedClient.ConfigV1alpha1().FederationDomains(ns).Update(ctx, federationDomain1LatestVersion, metav1.UpdateOptions{})
return err
}))
@@ -229,11 +229,11 @@ func TestSupervisorTLSTerminationWithSNI_Disruptive(t *testing.T) {
// Create an FederationDomain with a spec.tls.secretName.
federationDomain2 := testlib.CreateTestFederationDomain(ctx, t,
v1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuer2,
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: certSecretName2},
}, v1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, v1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecretName2},
}, supervisorconfigv1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
// Create the Secret.
ca2 := createTLSCertificateSecret(ctx, t, ns, hostname2, nil, certSecretName2, kubeClient)
@@ -282,8 +282,8 @@ func TestSupervisorTLSTerminationWithDefaultCerts_Disruptive(t *testing.T) {
issuerUsingHostname := fmt.Sprintf("%s://%s/issuer1", scheme, address)
// Create an FederationDomain without a spec.tls.secretName.
federationDomain1 := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{Issuer: issuerUsingIPAddress}, v1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, v1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
federationDomain1 := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{Issuer: issuerUsingIPAddress}, supervisorconfigv1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain1.Namespace, federationDomain1.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
// There is no default TLS cert and the spec.tls.secretName was not set, so the endpoints should fail with TLS errors.
requireEndpointHasBootstrapTLSErrorBecauseCertificatesAreNotReady(t, issuerUsingIPAddress)
@@ -297,11 +297,11 @@ func TestSupervisorTLSTerminationWithDefaultCerts_Disruptive(t *testing.T) {
// Create an FederationDomain with a spec.tls.secretName.
certSecretName := "integration-test-cert-1"
federationDomain2 := testlib.CreateTestFederationDomain(ctx, t,
v1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuerUsingHostname,
TLS: &v1alpha1.FederationDomainTLSSpec{SecretName: certSecretName},
}, v1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, v1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecretName},
}, supervisorconfigv1alpha1.FederationDomainPhaseReady)
requireStatus(t, pinnipedClient, federationDomain2.Namespace, federationDomain2.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
// Create the Secret.
certCA := createTLSCertificateSecret(ctx, t, ns, hostname, nil, certSecretName, kubeClient)
@@ -485,11 +485,11 @@ func requireCreatingFederationDomainCausesDiscoveryEndpointsToAppear(
supervisorScheme, supervisorAddress, supervisorCABundle string,
issuerName string,
client supervisorclientset.Interface,
) (*v1alpha1.FederationDomain, *ExpectedJWKSResponseFormat) {
) (*supervisorconfigv1alpha1.FederationDomain, *ExpectedJWKSResponseFormat) {
t.Helper()
newFederationDomain := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{Issuer: issuerName}, v1alpha1.FederationDomainPhaseReady)
newFederationDomain := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{Issuer: issuerName}, supervisorconfigv1alpha1.FederationDomainPhaseReady)
jwksResult := requireDiscoveryEndpointsAreWorking(t, supervisorScheme, supervisorAddress, supervisorCABundle, issuerName, nil)
requireStatus(t, client, newFederationDomain.Namespace, newFederationDomain.Name, v1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
requireStatus(t, client, newFederationDomain.Namespace, newFederationDomain.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady, withAllSuccessfulConditions())
return newFederationDomain, jwksResult
}
@@ -501,7 +501,7 @@ func requireDiscoveryEndpointsAreWorking(t *testing.T, supervisorScheme, supervi
func requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(
t *testing.T,
existingFederationDomain *v1alpha1.FederationDomain,
existingFederationDomain *supervisorconfigv1alpha1.FederationDomain,
client supervisorclientset.Interface,
ns string,
supervisorScheme, supervisorAddress, supervisorCABundle string,
@@ -626,16 +626,16 @@ func requireSuccessEndpointResponse(t *testing.T, endpointURL, issuer, caBundle
func editFederationDomainIssuerName(
t *testing.T,
existingFederationDomain *v1alpha1.FederationDomain,
existingFederationDomain *supervisorconfigv1alpha1.FederationDomain,
client supervisorclientset.Interface,
ns string,
newIssuerName string,
) *v1alpha1.FederationDomain {
) *supervisorconfigv1alpha1.FederationDomain {
t.Helper()
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
var updated *v1alpha1.FederationDomain
var updated *supervisorconfigv1alpha1.FederationDomain
require.NoError(t, retry.RetryOnConflict(retry.DefaultRetry, func() error {
mostRecentVersion, err := client.ConfigV1alpha1().FederationDomains(ns).Get(ctx, existingFederationDomain.Name, metav1.GetOptions{})
if err != nil {
@@ -684,7 +684,7 @@ func withFalseConditions(falseConditionTypes []string) map[string]metav1.Conditi
return c
}
func requireStatus(t *testing.T, client supervisorclientset.Interface, ns, name string, wantPhase v1alpha1.FederationDomainPhase, wantConditionTypeToStatus map[string]metav1.ConditionStatus) {
func requireStatus(t *testing.T, client supervisorclientset.Interface, ns, name string, wantPhase supervisorconfigv1alpha1.FederationDomainPhase, wantConditionTypeToStatus map[string]metav1.ConditionStatus) {
t.Helper()
testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
@@ -17,7 +17,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/utils/ptr"
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/testutil"
@@ -43,9 +43,9 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
name: "valid spec in without explicit identity providers makes status error unless there is exactly one identity provider",
run: func(t *testing.T) {
// Creating FederationDomain without any explicit IDPs should put the FederationDomain into an error status.
fd := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{
fd := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com/fake",
}, v1alpha1.FederationDomainPhaseError)
}, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, replaceSomeConditions(
allSuccessfulLegacyFederationDomainConditions("", fd.Spec),
[]metav1.Condition{
@@ -65,7 +65,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Issuer: "https://example.cluster.local/fake-issuer-url-does-not-matter",
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, idpv1alpha1.PhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, v1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name,
allSuccessfulLegacyFederationDomainConditions(oidcIdentityProvider1.Name, fd.Spec))
@@ -74,7 +74,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Issuer: "https://example.cluster.local/fake-issuer-url-does-not-matter",
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, idpv1alpha1.PhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, v1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, replaceSomeConditions(
allSuccessfulLegacyFederationDomainConditions(oidcIdentityProvider2.Name, fd.Spec),
[]metav1.Condition{
@@ -98,9 +98,9 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
oidcIDP1Meta := testlib.ObjectMetaWithRandomName(t, "upstream-oidc-idp")
oidcIDP2Meta := testlib.ObjectMetaWithRandomName(t, "upstream-oidc-idp")
// Creating FederationDomain with explicit IDPs that don't exist should put the FederationDomain into an error status.
fd := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{
fd := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com/fake",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "idp1",
ObjectRef: corev1.TypedLocalObjectReference{
@@ -108,7 +108,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Kind: "OIDCIdentityProvider",
Name: oidcIDP1Meta.Name,
},
Transforms: v1alpha1.FederationDomainTransforms{},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{},
},
{
DisplayName: "idp2",
@@ -117,10 +117,10 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Kind: "OIDCIdentityProvider",
Name: oidcIDP2Meta.Name,
},
Transforms: v1alpha1.FederationDomainTransforms{},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{},
},
},
}, v1alpha1.FederationDomainPhaseError)
}, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, replaceSomeConditions(
allSuccessfulFederationDomainConditions(fd.Spec),
[]metav1.Condition{
@@ -144,7 +144,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Issuer: "https://example.cluster.local/fake-issuer-url-does-not-matter",
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, oidcIDP1Meta, idpv1alpha1.PhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, v1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, replaceSomeConditions(
allSuccessfulFederationDomainConditions(fd.Spec),
[]metav1.Condition{
@@ -164,7 +164,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Issuer: "https://example.cluster.local/fake-issuer-url-does-not-matter",
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, oidcIDP2Meta, idpv1alpha1.PhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, v1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name,
allSuccessfulFederationDomainConditions(fd.Spec))
@@ -172,7 +172,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
oidcIDPClient := supervisorClient.IDPV1alpha1().OIDCIdentityProviders(env.SupervisorNamespace)
err := oidcIDPClient.Delete(ctx, oidcIdentityProvider1.Name, metav1.DeleteOptions{})
require.NoError(t, err)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, v1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, replaceSomeConditions(
allSuccessfulFederationDomainConditions(fd.Spec),
[]metav1.Condition{
@@ -198,9 +198,9 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Client: idpv1alpha1.OIDCClient{SecretName: "this-will-not-exist-but-does-not-matter"},
}, idpv1alpha1.PhaseError)
fd := testlib.CreateTestFederationDomain(ctx, t, v1alpha1.FederationDomainSpec{
fd := testlib.CreateTestFederationDomain(ctx, t, supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com/fake",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "not unique",
ObjectRef: corev1.TypedLocalObjectReference{
@@ -208,17 +208,17 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Kind: "OIDCIdentityProvider",
Name: "will not be found",
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "foo", Type: "string", StringValue: "bar"},
},
Expressions: []v1alpha1.FederationDomainTransformsExpression{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: "this is not a valid cel expression"},
{Type: "groups/v1", Expression: "this is also not a valid cel expression"},
{Type: "username/v1", Expression: "username"}, // valid
{Type: "policy/v1", Expression: "still not a valid cel expression"},
},
Examples: []v1alpha1.FederationDomainTransformsExample{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{
Username: "does not matter because expressions did not compile",
},
@@ -240,23 +240,23 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Kind: "this is the wrong kind",
Name: "also will not be found",
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "ryan", Type: "string", StringValue: "ryan"},
{Name: "unused", Type: "stringList", StringListValue: []string{"foo", "bar"}},
{Name: "rejectMe", Type: "string", StringValue: "rejectMeWithDefaultMessage"},
},
Expressions: []v1alpha1.FederationDomainTransformsExpression{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "policy/v1", Expression: `username == strConst.ryan || username == strConst.rejectMe`, Message: "only special users allowed"},
{Type: "policy/v1", Expression: `username != "rejectMeWithDefaultMessage"`}, // no message specified
{Type: "username/v1", Expression: `"pre:" + username`},
{Type: "groups/v1", Expression: `groups.map(g, "pre:" + g)`},
},
Examples: []v1alpha1.FederationDomainTransformsExample{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{ // this example should pass
Username: "ryan",
Groups: []string{"a", "b"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "pre:ryan",
Groups: []string{"pre:b", "pre:a", "pre:b", "pre:a"}, // order and repeats don't matter, treated like a set
Rejected: false,
@@ -264,7 +264,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
},
{ // this example should pass
Username: "other",
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
Message: "only special users allowed",
},
@@ -272,7 +272,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
{ // this example should fail because it expects the user to be rejected but the user was actually not rejected
Username: "ryan",
Groups: []string{"a", "b"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
Message: "this input is ignored in this case",
},
@@ -280,7 +280,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
{ // this example should fail because it expects the user not to be rejected but they were actually rejected
Username: "other",
Groups: []string{"a", "b"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "pre:other",
Groups: []string{"pre:a", "pre:b"},
Rejected: false,
@@ -289,7 +289,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
{ // this example should fail because it expects the wrong rejection message
Username: "other",
Groups: []string{"a", "b"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
Message: "wrong message",
},
@@ -298,14 +298,14 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
// because the message assertions defaults to asserting the default rejection message
Username: "rejectMeWithDefaultMessage",
Groups: []string{"a", "b"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
},
},
{ // this example should fail because it expects both the wrong username and groups
Username: "ryan",
Groups: []string{"b", "a"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "wrong",
Groups: []string{},
Rejected: false,
@@ -314,7 +314,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
{ // this example should fail because it expects the wrong username only
Username: "ryan",
Groups: []string{"a", "b"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "wrong",
Groups: []string{"pre:b", "pre:a"},
Rejected: false,
@@ -323,7 +323,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
{ // this example should fail because it expects the wrong groups only
Username: "ryan",
Groups: []string{"b", "a"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "pre:ryan",
Groups: []string{"wrong2", "wrong1"},
Rejected: false,
@@ -332,13 +332,13 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
{ // this example should fail because it does not expect anything but the auth actually was successful
Username: "ryan",
Groups: []string{"b", "a"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{},
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{},
},
},
},
},
},
}, v1alpha1.FederationDomainPhaseError)
}, supervisorconfigv1alpha1.FederationDomainPhaseError)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, replaceSomeConditions(
allSuccessfulFederationDomainConditions(fd.Spec),
@@ -437,7 +437,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
gotFD, err := federationDomainsClient.Get(ctx, fd.Name, metav1.GetOptions{})
require.NoError(t, err)
gotFD.Spec.IdentityProviders[0] = v1alpha1.FederationDomainIdentityProvider{
gotFD.Spec.IdentityProviders[0] = supervisorconfigv1alpha1.FederationDomainIdentityProvider{
// Fix the display name.
DisplayName: "now made unique",
// Fix the objectRef.
@@ -446,19 +446,19 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Kind: "OIDCIdentityProvider",
Name: oidcIdentityProvider.Name,
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "foo", Type: "string", StringValue: "bar"},
},
Expressions: []v1alpha1.FederationDomainTransformsExpression{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
// Fix the compile errors.
{Type: "username/v1", Expression: `"pre:" + username`},
},
Examples: []v1alpha1.FederationDomainTransformsExample{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{ // this example should fail because it expects both the wrong username and groups
Username: "ryan",
Groups: []string{"b", "a"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "wrong",
Groups: []string{},
Rejected: false,
@@ -468,10 +468,10 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
},
}
gotFD.Spec.IdentityProviders[2].Transforms.Examples = []v1alpha1.FederationDomainTransformsExample{
gotFD.Spec.IdentityProviders[2].Transforms.Examples = []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{ // this example should pass
Username: "other",
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Rejected: true,
Message: "only special users allowed",
},
@@ -525,11 +525,11 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
Name: oidcIdentityProvider.Name,
}
gotFD.Spec.IdentityProviders[0].Transforms.Examples = []v1alpha1.FederationDomainTransformsExample{
gotFD.Spec.IdentityProviders[0].Transforms.Examples = []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{ // this example should pass
Username: "ryan",
Groups: []string{"b", "a"},
Expects: v1alpha1.FederationDomainTransformsExampleExpects{
Expects: supervisorconfigv1alpha1.FederationDomainTransformsExampleExpects{
Username: "pre:ryan",
Groups: []string{"a", "b"},
},
@@ -541,7 +541,7 @@ func TestSupervisorFederationDomainStatus_Disruptive(t *testing.T) {
})
require.NoError(t, err)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, v1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, fd.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusConditions(ctx, t, fd.Name, allSuccessfulFederationDomainConditions(fd.Spec))
},
},
@@ -570,16 +570,16 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
tests := []struct {
name string
fd *v1alpha1.FederationDomain
fd *supervisorconfigv1alpha1.FederationDomain
wantErr string
wantOldKubeErr string
wantReallyOldKubeErr string
}{
{
name: "issuer cannot be empty",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "",
},
},
@@ -589,11 +589,11 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP display names cannot be empty",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "",
ObjectRef: corev1.TypedLocalObjectReference{
@@ -610,18 +610,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform constants must have unique names",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "notUnique", Type: "string", StringValue: "foo"},
{Name: "notUnique", Type: "string", StringValue: "bar"},
},
@@ -639,18 +639,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform constant names cannot be empty",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "", Type: "string"},
},
},
@@ -665,18 +665,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform constant names cannot be more than 64 characters",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "12345678901234567890123456789012345678901234567890123456789012345", Type: "string"},
},
},
@@ -698,18 +698,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform constant names must be a legal CEL variable name",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "cannot have spaces", Type: "string"},
{Name: "1mustStartWithLetter", Type: "string"},
{Name: "_mustStartWithLetter", Type: "string"},
@@ -740,18 +740,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform constant types must be one of the allowed enum strings",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "a", Type: "this is invalid"},
{Name: "b", Type: "string"},
{Name: "c", Type: "stringList"},
@@ -768,18 +768,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform expression types must be one of the allowed enum strings",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Expressions: []v1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "this is invalid", Expression: "foo"},
{Type: "policy/v1", Expression: "foo"},
{Type: "username/v1", Expression: "foo"},
@@ -797,18 +797,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform expressions cannot be empty",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Expressions: []v1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: ""},
},
},
@@ -823,18 +823,18 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "IDP transform example usernames cannot be empty",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Examples: []v1alpha1.FederationDomainTransformsExample{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{Username: ""},
{Username: "non-empty"},
},
@@ -850,20 +850,20 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "minimum valid",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "fd"),
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
},
},
},
{
name: "minimum valid when IDPs are included",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "fd"),
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
@@ -876,24 +876,24 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "minimum valid when IDP has transform constants, expressions, and examples",
fd: &v1alpha1.FederationDomain{
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "fd"),
Spec: v1alpha1.FederationDomainSpec{
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []v1alpha1.FederationDomainIdentityProvider{
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: v1alpha1.FederationDomainTransforms{
Constants: []v1alpha1.FederationDomainTransformsConstant{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "foo", Type: "string"},
},
Expressions: []v1alpha1.FederationDomainTransformsExpression{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: "foo"},
},
Examples: []v1alpha1.FederationDomainTransformsExample{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{Username: "foo"},
},
},
@@ -964,7 +964,7 @@ func replaceSomeConditions(conditions []metav1.Condition, replaceWithTheseCondit
return cp
}
func allSuccessfulLegacyFederationDomainConditions(idpName string, federationDomainSpec v1alpha1.FederationDomainSpec) []metav1.Condition {
func allSuccessfulLegacyFederationDomainConditions(idpName string, federationDomainSpec supervisorconfigv1alpha1.FederationDomainSpec) []metav1.Condition {
return replaceSomeConditions(
allSuccessfulFederationDomainConditions(federationDomainSpec),
[]metav1.Condition{
@@ -979,7 +979,7 @@ func allSuccessfulLegacyFederationDomainConditions(idpName string, federationDom
)
}
func allSuccessfulFederationDomainConditions(federationDomainSpec v1alpha1.FederationDomainSpec) []metav1.Condition {
func allSuccessfulFederationDomainConditions(federationDomainSpec supervisorconfigv1alpha1.FederationDomainSpec) []metav1.Condition {
return []metav1.Condition{
{
Type: "IdentityProvidersDisplayNamesUnique", Status: "True", Reason: "Success",
+113 -113
View File
@@ -29,7 +29,7 @@ import (
"k8s.io/utils/ptr"
"k8s.io/utils/strings/slices"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/federationdomain/oidc"
@@ -237,7 +237,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
// Optionally specify the identityProviders part of the FederationDomain's spec by returning it from this function.
// Also return the displayName of the IDP that should be used during authentication (or empty string for no IDP name in the auth request).
// This function takes the name of the IDP CR which was returned by createIDP() as as argument.
federationDomainIDPs func(t *testing.T, idpName string) (idps []configv1alpha1.FederationDomainIdentityProvider, useIDPDisplayName string)
federationDomainIDPs func(t *testing.T, idpName string) (idps []supervisorconfigv1alpha1.FederationDomainIdentityProvider, useIDPDisplayName string)
// Optionally create an OIDCClient CR for the test to use. Return the client ID and client secret for the
// test to use. When not set, the test will default to using the "pinniped-cli" static client with no secret.
@@ -280,7 +280,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenGroups []string
// The expected ID token additional claims, which will be nested under claim "additionalClaims",
// for the original ID token and the refreshed ID token.
wantDownstreamIDTokenAdditionalClaims map[string]interface{}
wantDownstreamIDTokenAdditionalClaims map[string]any
// The expected ID token lifetime, as calculated by token claim 'exp' subtracting token claim 'iat'.
// ID tokens issued through authcode exchange or token refresh should have the configured lifetime (or default if not configured).
// ID tokens issued through a token exchange should have the default lifetime.
@@ -454,7 +454,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenSubjectToMatch: expectedIDTokenSubjectRegexForUpstreamOIDC,
// the ID token Username should include the upstream user ID after the upstream issuer name
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Issuer+"?sub=") + ".+" },
wantDownstreamIDTokenAdditionalClaims: wantGroupsInAdditionalClaimsIfGroupsExist(map[string]interface{}{
wantDownstreamIDTokenAdditionalClaims: wantGroupsInAdditionalClaimsIfGroupsExist(map[string]any{
"upstream_issuer✅": env.SupervisorUpstreamOIDC.Issuer,
"upstream_username": env.SupervisorUpstreamOIDC.Username,
}, "upstream_groups", env.SupervisorUpstreamOIDC.ExpectedGroups),
@@ -479,7 +479,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenSubjectToMatch: expectedIDTokenSubjectRegexForUpstreamOIDC,
// the ID token Username should include the upstream user ID after the upstream issuer name
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Issuer+"?sub=") + ".+" },
wantDownstreamIDTokenAdditionalClaims: wantGroupsInAdditionalClaimsIfGroupsExist(map[string]interface{}{
wantDownstreamIDTokenAdditionalClaims: wantGroupsInAdditionalClaimsIfGroupsExist(map[string]any{
"upstream_issuer✅": env.SupervisorUpstreamOIDC.Issuer,
"upstream_username": env.SupervisorUpstreamOIDC.Username,
}, "upstream_groups", env.SupervisorUpstreamOIDC.ExpectedGroups),
@@ -1423,11 +1423,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady).Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
requestAuthorization: requestAuthorizationUsingBrowserAuthcodeFlowOIDC,
wantDownstreamIDTokenSubjectToMatch: expectedIDTokenSubjectRegexForUpstreamOIDC,
@@ -1449,14 +1449,14 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady).Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
TokenLifetimes: configv1alpha1.OIDCClientTokenLifetimes{
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
TokenLifetimes: supervisorconfigv1alpha1.OIDCClientTokenLifetimes{
IDTokenSeconds: ptr.To[int32](1234),
},
}, configv1alpha1.OIDCClientPhaseReady)
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
requestAuthorization: requestAuthorizationUsingBrowserAuthcodeFlowOIDC,
wantDownstreamIDTokenSubjectToMatch: expectedIDTokenSubjectRegexForUpstreamOIDC,
@@ -1478,9 +1478,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
}
return testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady).Name
},
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
federationDomainIDPs: func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string) {
displayName := "my oidc idp"
return []configv1alpha1.FederationDomainIdentityProvider{
return []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: displayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -1494,11 +1494,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
// which should cause the authorize endpoint to show the IDP chooser page
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
requestAuthorization: requestAuthorizationUsingBrowserAuthcodeFlowOIDCWithIDPChooserPage,
wantDownstreamIDTokenSubjectToMatch: "^" +
@@ -1530,17 +1530,17 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady).Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
requestAuthorization: requestAuthorizationUsingBrowserAuthcodeFlowOIDC,
wantDownstreamIDTokenSubjectToMatch: expectedIDTokenSubjectRegexForUpstreamOIDC,
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { return "^" + regexp.QuoteMeta(env.SupervisorUpstreamOIDC.Username) + "$" },
wantDownstreamIDTokenGroups: env.SupervisorUpstreamOIDC.ExpectedGroups,
wantDownstreamIDTokenAdditionalClaims: wantGroupsInAdditionalClaimsIfGroupsExist(map[string]interface{}{
wantDownstreamIDTokenAdditionalClaims: wantGroupsInAdditionalClaimsIfGroupsExist(map[string]any{
"upstream_issuer✅": env.SupervisorUpstreamOIDC.Issuer,
"upstream_username": env.SupervisorUpstreamOIDC.Username,
}, "upstream_groups", env.SupervisorUpstreamOIDC.ExpectedGroups),
@@ -1553,11 +1553,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1580,11 +1580,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange grant type not allowed
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username", "groups"}, // a validation requires that we also disallow the pinniped:request-audience scope
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange grant type not allowed
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username", "groups"}, // a validation requires that we also disallow the pinniped:request-audience scope
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1614,11 +1614,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1648,11 +1648,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "groups"}, // username not allowed
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1674,11 +1674,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"}, // token exchange not allowed (required to exclude groups scope)
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "username"}, // groups not allowed
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1700,11 +1700,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1728,11 +1728,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1762,11 +1762,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access"}, // validations require that when username/groups are excluded, then token exchange must also not be allowed
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access"}, // validations require that when username/groups are excluded, then token exchange must also not be allowed
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1796,11 +1796,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
return testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
return testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
},
testUser: func(t *testing.T) (string, string) {
// return the username and password of the existing user that we want to use for this test
@@ -1823,11 +1823,11 @@ func TestSupervisorLogin_Browser(t *testing.T) {
return idp.Name
},
createOIDCClient: func(t *testing.T, callbackURL string) (string, string) {
clientID, _ := testlib.CreateOIDCClient(t, configv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []configv1alpha1.RedirectURI{configv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []configv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []configv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, configv1alpha1.OIDCClientPhaseReady)
clientID, _ := testlib.CreateOIDCClient(t, supervisorconfigv1alpha1.OIDCClientSpec{
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{supervisorconfigv1alpha1.RedirectURI(callbackURL)},
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{"authorization_code", "urn:ietf:params:oauth:grant-type:token-exchange", "refresh_token"},
AllowedScopes: []supervisorconfigv1alpha1.Scope{"openid", "offline_access", "pinniped:request-audience", "username", "groups"},
}, supervisorconfigv1alpha1.OIDCClientPhaseReady)
return clientID, "wrong-client-secret"
},
testUser: func(t *testing.T) (string, string) {
@@ -1852,9 +1852,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
}
return testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady).Name
},
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
federationDomainIDPs: func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string) {
displayName := "my oidc idp"
return []configv1alpha1.FederationDomainIdentityProvider{
return []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: displayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -1862,8 +1862,8 @@ func TestSupervisorLogin_Browser(t *testing.T) {
Kind: "OIDCIdentityProvider",
Name: idpName,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{
Type: "username/v1",
Expression: fmt.Sprintf(`username == "%s" ? "username-prefix:" + username : username`,
@@ -1913,9 +1913,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
idp, _ := createLDAPIdentityProvider(t, nil)
return idp.Name
},
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
federationDomainIDPs: func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string) {
displayName := "my ldap idp"
return []configv1alpha1.FederationDomainIdentityProvider{
return []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: displayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -1923,8 +1923,8 @@ func TestSupervisorLogin_Browser(t *testing.T) {
Kind: "LDAPIdentityProvider",
Name: idpName,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{
Type: "username/v1",
Expression: fmt.Sprintf(`username == "%s" ? "username-prefix:" + username : username`,
@@ -1980,9 +1980,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
idp, _ := createLDAPIdentityProvider(t, nil)
return idp.Name
},
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
federationDomainIDPs: func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string) {
displayName := "my ldap idp"
return []configv1alpha1.FederationDomainIdentityProvider{
return []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: displayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -1990,8 +1990,8 @@ func TestSupervisorLogin_Browser(t *testing.T) {
Kind: "LDAPIdentityProvider",
Name: idpName,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{
Type: "username/v1",
Expression: fmt.Sprintf(`username == "%s" ? "username-prefix:" + username : username`,
@@ -2044,9 +2044,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
idp, _ := createActiveDirectoryIdentityProvider(t, nil)
return idp.Name
},
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
federationDomainIDPs: func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string) {
displayName := "my ad idp"
return []configv1alpha1.FederationDomainIdentityProvider{
return []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: displayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -2054,8 +2054,8 @@ func TestSupervisorLogin_Browser(t *testing.T) {
Kind: "ActiveDirectoryIdentityProvider",
Name: idpName,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{
Type: "username/v1",
Expression: fmt.Sprintf(`username == "%s" ? "username-prefix:" + username : username`,
@@ -2113,9 +2113,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
idp, _ := createActiveDirectoryIdentityProvider(t, nil)
return idp.Name
},
federationDomainIDPs: func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string) {
federationDomainIDPs: func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string) {
displayName := "my ad idp"
return []configv1alpha1.FederationDomainIdentityProvider{
return []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: displayName,
ObjectRef: corev1.TypedLocalObjectReference{
@@ -2123,8 +2123,8 @@ func TestSupervisorLogin_Browser(t *testing.T) {
Kind: "ActiveDirectoryIdentityProvider",
Name: idpName,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{
Type: "username/v1",
Expression: fmt.Sprintf(`username == "%s" ? "username-prefix:" + username : username`,
@@ -2206,9 +2206,9 @@ func TestSupervisorLogin_Browser(t *testing.T) {
}
}
func wantGroupsInAdditionalClaimsIfGroupsExist(additionalClaims map[string]interface{}, wantGroupsAdditionalClaimName string, wantGroups []string) map[string]interface{} {
func wantGroupsInAdditionalClaimsIfGroupsExist(additionalClaims map[string]any, wantGroupsAdditionalClaimName string, wantGroups []string) map[string]any {
if len(wantGroups) > 0 {
var wantGroupsAnyType []interface{}
var wantGroupsAnyType []any
for _, group := range wantGroups {
wantGroupsAnyType = append(wantGroupsAnyType, group)
}
@@ -2338,7 +2338,7 @@ func requireEventuallySuccessfulActiveDirectoryIdentityProviderConditions(t *tes
func testSupervisorLogin(
t *testing.T,
createIDP func(t *testing.T) string,
federationDomainIDPs func(t *testing.T, idpName string) ([]configv1alpha1.FederationDomainIdentityProvider, string),
federationDomainIDPs func(t *testing.T, idpName string) ([]supervisorconfigv1alpha1.FederationDomainIdentityProvider, string),
requestAuthorization func(t *testing.T, downstreamIssuer string, downstreamAuthorizeURL string, downstreamCallbackURL string, username string, password string, httpClient *http.Client),
editRefreshSessionDataWithoutBreaking func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName string, username string) []string,
breakRefreshSessionData func(t *testing.T, pinnipedSession *psession.PinnipedSession, idpName string, username string),
@@ -2351,7 +2351,7 @@ func testSupervisorLogin(
wantDownstreamIDTokenSubjectToMatch string,
wantDownstreamIDTokenUsernameToMatch func(username string) string,
wantDownstreamIDTokenGroups []string,
wantDownstreamIDTokenAdditionalClaims map[string]interface{},
wantDownstreamIDTokenAdditionalClaims map[string]any,
wantDownstreamIDTokenLifetime *time.Duration,
wantAuthorizationErrorType string,
wantAuthorizationErrorDescription string,
@@ -2420,7 +2420,7 @@ func testSupervisorLogin(
idpName := createIDP(t)
// Determine if and how we should set spec.identityProviders for the FederationDomain.
var fdIDPSpec []configv1alpha1.FederationDomainIdentityProvider
var fdIDPSpec []supervisorconfigv1alpha1.FederationDomainIdentityProvider
useIDPDisplayName := ""
if federationDomainIDPs != nil {
fdIDPSpec, useIDPDisplayName = federationDomainIDPs(t, idpName)
@@ -2428,14 +2428,14 @@ func testSupervisorLogin(
// Create the downstream FederationDomain and expect it to go into the appropriate status condition.
downstream := testlib.CreateTestFederationDomain(ctx, t,
configv1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuerURL.String(),
TLS: &configv1alpha1.FederationDomainTLSSpec{SecretName: certSecret.Name},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecret.Name},
IdentityProviders: fdIDPSpec,
},
// The IDP CR already exists, so even for legacy FederationDomains which do not explicitly list
// the IDPs in the spec, the FederationDomain should be ready.
configv1alpha1.FederationDomainPhaseReady,
supervisorconfigv1alpha1.FederationDomainPhaseReady,
)
// Ensure that the JWKS data is created and ready for the new FederationDomain by waiting for
@@ -2739,9 +2739,9 @@ func verifyTokenResponse(
expectedIDTokenClaims []string,
wantDownstreamIDTokenSubjectToMatch, wantDownstreamIDTokenUsernameToMatch string,
wantDownstreamIDTokenGroups []string,
wantDownstreamIDTokenAdditionalClaims map[string]interface{},
wantDownstreamIDTokenAdditionalClaims map[string]any,
wantDownstreamIDTokenLifetime time.Duration,
) map[string]interface{} {
) map[string]any {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
@@ -2762,7 +2762,7 @@ func verifyTokenResponse(
testutil.RequireTimeInDelta(t, time.Now().UTC().Add(wantDownstreamIDTokenLifetime), idToken.Expiry, time.Second*30)
// Check the full list of claim names of the ID token.
idTokenClaims := map[string]interface{}{}
idTokenClaims := map[string]any{}
err = idToken.Claims(&idTokenClaims)
require.NoError(t, err)
idTokenClaimNames := []string{}
@@ -2819,7 +2819,7 @@ func verifyTokenResponse(
return idTokenClaims
}
func getFloat64Claim(t *testing.T, claims map[string]interface{}, claim string) float64 {
func getFloat64Claim(t *testing.T, claims map[string]any, claim string) float64 {
t.Helper()
v, ok := claims[claim]
@@ -3104,7 +3104,7 @@ func doTokenExchange(
httpClient *http.Client,
provider *coreosoidc.Provider,
wantTokenExchangeResponse func(t *testing.T, status int, body string),
previousIDTokenClaims map[string]interface{},
previousIDTokenClaims map[string]any,
wantIDTokenLifetime time.Duration,
) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
@@ -3154,7 +3154,7 @@ func doTokenExchange(
exchangedToken, err := clusterVerifier.Verify(ctx, respBody.AccessToken)
require.NoError(t, err)
var claims map[string]interface{}
var claims map[string]any
require.NoError(t, exchangedToken.Claims(&claims))
indentedClaims, err := json.MarshalIndent(claims, " ", " ")
require.NoError(t, err)
@@ -104,7 +104,7 @@ func TestKubectlOIDCClientSecretRequest_Parallel(t *testing.T) {
return []string{"create", "-f", filePath, "-o", "yaml"}
},
assertOnStdOut: func(t *testing.T, oidcClientName string, stdOutString string) {
var yamlObj map[string]interface{}
var yamlObj map[string]any
err := yaml.Unmarshal([]byte(stdOutString), &yamlObj)
require.NoError(t, err)
@@ -112,7 +112,7 @@ func TestKubectlOIDCClientSecretRequest_Parallel(t *testing.T) {
require.Equal(t, yamlObj["apiVersion"], fmt.Sprintf("clientsecret.supervisor.%s/v1alpha1", env.APIGroupSuffix))
require.Equal(t, yamlObj["kind"], "OIDCClientSecretRequest")
metadataMap, ok := yamlObj["metadata"].(map[string]interface{})
metadataMap, ok := yamlObj["metadata"].(map[string]any)
require.True(t, ok, "metadata should be a map")
require.Len(t, metadataMap, 3, "metadata should contain only 3 keys (creationTimestamp, name, namespace): %v", metadataMap)
require.Equal(t, metadataMap["name"], oidcClientName)
@@ -124,13 +124,13 @@ func TestKubectlOIDCClientSecretRequest_Parallel(t *testing.T) {
require.NoError(t, err)
testutil.RequireTimeInDelta(t, parsedTime, time.Now(), 1*time.Minute)
specMap, ok := yamlObj["spec"].(map[string]interface{})
specMap, ok := yamlObj["spec"].(map[string]any)
require.True(t, ok, "spec should be a map")
require.Len(t, specMap, 2, "spec should contain only 2 keys (generateNewSecret, revokeOldSecrets): %v", specMap)
require.Equal(t, specMap["generateNewSecret"], true)
require.Equal(t, specMap["revokeOldSecrets"], false)
statusMap, ok := yamlObj["status"].(map[string]interface{})
statusMap, ok := yamlObj["status"].(map[string]any)
require.True(t, ok, "status should be a map")
require.Len(t, specMap, 2, "status should contain only 2 keys (generatedSecret, totalClientSecrets): %v", statusMap)
require.Regexp(t, "^[0-9a-z]{64}$", statusMap["generatedSecret"], "generated secret must be precisely 40 hex encoded characters")
+10 -10
View File
@@ -15,7 +15,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
"go.pinniped.dev/test/testlib"
)
@@ -30,48 +30,48 @@ func TestSupervisorSecrets_Parallel(t *testing.T) {
// Create our FederationDomain under test.
federationDomain := testlib.CreateTestFederationDomain(ctx, t,
configv1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: fmt.Sprintf("http://test-issuer-%s.pinniped.dev", testlib.RandHex(t, 8)),
},
configv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created, but this test does not care
supervisorconfigv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created, but this test does not care
)
tests := []struct {
name string
secretName func(federationDomain *configv1alpha1.FederationDomain) string
secretName func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string
ensureValid func(t *testing.T, secret *corev1.Secret)
}{
{
name: "csrf cookie signing key",
secretName: func(federationDomain *configv1alpha1.FederationDomain) string {
secretName: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return env.SupervisorAppName + "-key"
},
ensureValid: ensureValidSymmetricSecretOfTypeFunc("secrets.pinniped.dev/supervisor-csrf-signing-key"),
},
{
name: "jwks",
secretName: func(federationDomain *configv1alpha1.FederationDomain) string {
secretName: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.JWKS.Name
},
ensureValid: ensureValidJWKS,
},
{
name: "hmac signing secret",
secretName: func(federationDomain *configv1alpha1.FederationDomain) string {
secretName: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.TokenSigningKey.Name
},
ensureValid: ensureValidSymmetricSecretOfTypeFunc("secrets.pinniped.dev/federation-domain-token-signing-key"),
},
{
name: "state signature secret",
secretName: func(federationDomain *configv1alpha1.FederationDomain) string {
secretName: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateSigningKey.Name
},
ensureValid: ensureValidSymmetricSecretOfTypeFunc("secrets.pinniped.dev/federation-domain-state-signing-key"),
},
{
name: "state encryption secret",
secretName: func(federationDomain *configv1alpha1.FederationDomain) string {
secretName: func(federationDomain *supervisorconfigv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateEncryptionKey.Name
},
ensureValid: ensureValidSymmetricSecretOfTypeFunc("secrets.pinniped.dev/federation-domain-state-encryption-key"),
@@ -80,7 +80,7 @@ func TestSupervisorSecrets_Parallel(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// Ensure a secret is created with the FederationDomain's JWKS.
var updatedFederationDomain *configv1alpha1.FederationDomain
var updatedFederationDomain *supervisorconfigv1alpha1.FederationDomain
testlib.RequireEventually(t, func(requireEventually *require.Assertions) {
resp, err := supervisorClient.
ConfigV1alpha1().
+16 -16
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package integration
@@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/test/testlib"
)
@@ -19,13 +19,13 @@ func TestSupervisorUpstreamOIDCDiscovery(t *testing.T) {
t.Run("invalid missing secret and bad issuer", func(t *testing.T) {
t.Parallel()
spec := v1alpha1.OIDCIdentityProviderSpec{
spec := idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: "https://127.0.0.1:444444/invalid-url-that-is-really-really-long-nanananananananannanananan-batman-nanananananananananananananana-batman-lalalalalalalalalal-batman-weeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
Client: v1alpha1.OIDCClient{
Client: idpv1alpha1.OIDCClient{
SecretName: "does-not-exist",
},
}
upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseError)
upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseError)
expectUpstreamConditions(t, upstream, []metav1.Condition{
{
Type: "ClientCredentialsValid",
@@ -51,19 +51,19 @@ Get "https://127.0.0.1:444444/invalid-url-that-is-really-really-long-nananananan
t.Run("invalid issuer with trailing slash", func(t *testing.T) {
t.Parallel()
spec := v1alpha1.OIDCIdentityProviderSpec{
spec := idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: env.SupervisorUpstreamOIDC.Issuer + "/",
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)),
},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: []string{"email", "profile"},
},
Client: v1alpha1.OIDCClient{
Client: idpv1alpha1.OIDCClient{
SecretName: testlib.CreateClientCredsSecret(t, "test-client-id", "test-client-secret").Name,
},
}
upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseError)
upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseError)
expectUpstreamConditions(t, upstream, []metav1.Condition{
{
Type: "ClientCredentialsValid",
@@ -89,19 +89,19 @@ oidc: issuer did not match the issuer returned by provider, expected "` + env.Su
t.Run("valid", func(t *testing.T) {
t.Parallel()
spec := v1alpha1.OIDCIdentityProviderSpec{
spec := idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: env.SupervisorUpstreamOIDC.Issuer,
TLS: &v1alpha1.TLSSpec{
TLS: &idpv1alpha1.TLSSpec{
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamOIDC.CABundle)),
},
AuthorizationConfig: v1alpha1.OIDCAuthorizationConfig{
AuthorizationConfig: idpv1alpha1.OIDCAuthorizationConfig{
AdditionalScopes: []string{"email", "profile"},
},
Client: v1alpha1.OIDCClient{
Client: idpv1alpha1.OIDCClient{
SecretName: testlib.CreateClientCredsSecret(t, "test-client-id", "test-client-secret").Name,
},
}
upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, v1alpha1.PhaseReady)
upstream := testlib.CreateTestOIDCIdentityProvider(t, spec, idpv1alpha1.PhaseReady)
expectUpstreamConditions(t, upstream, []metav1.Condition{
{
Type: "ClientCredentialsValid",
@@ -125,7 +125,7 @@ oidc: issuer did not match the issuer returned by provider, expected "` + env.Su
})
}
func expectUpstreamConditions(t *testing.T, upstream *v1alpha1.OIDCIdentityProvider, expected []metav1.Condition) {
func expectUpstreamConditions(t *testing.T, upstream *idpv1alpha1.OIDCIdentityProvider, expected []metav1.Condition) {
t.Helper()
normalized := make([]metav1.Condition, 0, len(upstream.Status.Conditions))
for _, c := range upstream.Status.Conditions {
+7 -7
View File
@@ -25,7 +25,7 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/federationdomain/oidc"
@@ -83,11 +83,11 @@ func TestSupervisorWarnings_Browser(t *testing.T) {
// Create the downstream FederationDomain and expect it to go into the success status condition.
downstream := testlib.CreateTestFederationDomain(ctx, t,
configv1alpha1.FederationDomainSpec{
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: issuerURL.String(),
TLS: &configv1alpha1.FederationDomainTLSSpec{SecretName: certSecret.Name},
TLS: &supervisorconfigv1alpha1.FederationDomainTLSSpec{SecretName: certSecret.Name},
},
configv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created
supervisorconfigv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created
)
// Create a JWTAuthenticator that will validate the tokens from the downstream issuer.
@@ -110,7 +110,7 @@ func TestSupervisorWarnings_Browser(t *testing.T) {
expectedUsername := env.SupervisorUpstreamLDAP.TestUserMailAttributeValue
createdProvider := setupClusterForEndToEndLDAPTest(t, expectedUsername, env)
testlib.WaitForFederationDomainStatusPhase(ctx, t, downstream.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, downstream.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(ctx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -258,7 +258,7 @@ func TestSupervisorWarnings_Browser(t *testing.T) {
sAMAccountName := expectedUsername + "@" + env.SupervisorUpstreamActiveDirectory.Domain
createdProvider := setupClusterForEndToEndActiveDirectoryTest(t, sAMAccountName, env)
testlib.WaitForFederationDomainStatusPhase(ctx, t, downstream.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, downstream.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(ctx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
@@ -420,7 +420,7 @@ func TestSupervisorWarnings_Browser(t *testing.T) {
SecretName: testlib.CreateClientCredsSecret(t, env.SupervisorUpstreamOIDC.ClientID, env.SupervisorUpstreamOIDC.ClientSecret).Name,
},
}, idpv1alpha1.PhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, downstream.Name, configv1alpha1.FederationDomainPhaseReady)
testlib.WaitForFederationDomainStatusPhase(ctx, t, downstream.Name, supervisorconfigv1alpha1.FederationDomainPhaseReady)
testlib.WaitForJWTAuthenticatorStatusPhase(ctx, t, authenticator.Name, authenticationv1alpha1.JWTAuthenticatorPhaseReady)
// Use a specific session cache for this test.
+6 -6
View File
@@ -25,7 +25,7 @@ type (
// assertionFailure is a single error observed during an iteration of the RequireEventually() loop.
assertionFailure struct {
format string
args []interface{}
args []any
}
)
@@ -33,7 +33,7 @@ type (
var _ require.TestingT = (*loopTestingT)(nil)
// Errorf is called by the assert.Assertions methods to record an error.
func (e *loopTestingT) Errorf(format string, args ...interface{}) {
func (e *loopTestingT) Errorf(format string, args ...any) {
*e = append(*e, assertionFailure{format, args})
}
@@ -62,7 +62,7 @@ func RequireEventuallyf(
waitFor time.Duration,
tick time.Duration,
msg string,
args ...interface{},
args ...any,
) {
t.Helper()
RequireEventually(t, f, waitFor, tick, fmt.Sprintf(msg, args...))
@@ -75,7 +75,7 @@ func RequireEventually(
f func(requireEventually *require.Assertions),
waitFor time.Duration,
tick time.Duration,
msgAndArgs ...interface{},
msgAndArgs ...any,
) {
t.Helper()
@@ -129,7 +129,7 @@ func RequireEventuallyWithoutError(
f func() (bool, error),
waitFor time.Duration,
tick time.Duration,
msgAndArgs ...interface{},
msgAndArgs ...any,
) {
t.Helper()
// This previously used wait.PollImmediate (now deprecated), which did not take a ctx arg in the func.
@@ -146,7 +146,7 @@ func RequireNeverWithoutError(
f func() (bool, error),
waitFor time.Duration,
tick time.Duration,
msgAndArgs ...interface{},
msgAndArgs ...any,
) {
t.Helper()
// This previously used wait.PollImmediate (now deprecated), which did not take a ctx arg in the func.
+1 -1
View File
@@ -104,7 +104,7 @@ func OpenBrowser(t *testing.T) *Browser {
b := &Browser{chromeCtx: chromeCtx}
// Subscribe to console events and exceptions to make them available later.
chromedp.ListenTarget(chromeCtx, func(ev interface{}) {
chromedp.ListenTarget(chromeCtx, func(ev any) {
switch ev := ev.(type) {
case *chromedpruntime.EventConsoleAPICalled:
args := make([]string, len(ev.Args))
+11 -11
View File
@@ -30,7 +30,7 @@ import (
authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
"go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1"
clientsecretv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/clientsecret/v1alpha1"
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
pinnipedsupervisorclientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned"
@@ -357,9 +357,9 @@ func WaitForJWTAuthenticatorStatusConditions(ctx context.Context, t *testing.T,
func CreateTestFederationDomain(
ctx context.Context,
t *testing.T,
spec configv1alpha1.FederationDomainSpec,
expectStatus configv1alpha1.FederationDomainPhase,
) *configv1alpha1.FederationDomain {
spec supervisorconfigv1alpha1.FederationDomainSpec,
expectStatus supervisorconfigv1alpha1.FederationDomainPhase,
) *supervisorconfigv1alpha1.FederationDomain {
t.Helper()
testEnv := IntegrationEnv(t)
@@ -367,7 +367,7 @@ func CreateTestFederationDomain(
defer cancel()
federationDomainsClient := NewSupervisorClientset(t).ConfigV1alpha1().FederationDomains(testEnv.SupervisorNamespace)
federationDomain, err := federationDomainsClient.Create(createContext, &configv1alpha1.FederationDomain{
federationDomain, err := federationDomainsClient.Create(createContext, &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testObjectMeta(t, "oidc-provider"),
Spec: spec,
}, metav1.CreateOptions{})
@@ -393,7 +393,7 @@ func CreateTestFederationDomain(
return federationDomain
}
func WaitForFederationDomainStatusPhase(ctx context.Context, t *testing.T, federationDomainName string, expectPhase configv1alpha1.FederationDomainPhase) {
func WaitForFederationDomainStatusPhase(ctx context.Context, t *testing.T, federationDomainName string, expectPhase supervisorconfigv1alpha1.FederationDomainPhase) {
t.Helper()
testEnv := IntegrationEnv(t)
federationDomainsClient := NewSupervisorClientset(t).ConfigV1alpha1().FederationDomains(testEnv.SupervisorNamespace)
@@ -404,7 +404,7 @@ func WaitForFederationDomainStatusPhase(ctx context.Context, t *testing.T, feder
requireEventually.Equalf(expectPhase, fd.Status.Phase, "actual status conditions were: %#v", fd.Status.Conditions)
// If the FederationDomain was successfully created, ensure all secrets are present before continuing
if expectPhase == configv1alpha1.FederationDomainPhaseReady {
if expectPhase == supervisorconfigv1alpha1.FederationDomainPhaseReady {
requireEventually.NotEmpty(fd.Status.Secrets.JWKS.Name, "expected status.secrets.jwks.name not to be empty")
requireEventually.NotEmpty(fd.Status.Secrets.TokenSigningKey.Name, "expected status.secrets.tokenSigningKey.name not to be empty")
requireEventually.NotEmpty(fd.Status.Secrets.StateSigningKey.Name, "expected status.secrets.stateSigningKey.name not to be empty")
@@ -510,7 +510,7 @@ func CreateClientCredsSecret(t *testing.T, clientID string, clientSecret string)
)
}
func CreateOIDCClient(t *testing.T, spec configv1alpha1.OIDCClientSpec, expectedPhase configv1alpha1.OIDCClientPhase) (string, string) {
func CreateOIDCClient(t *testing.T, spec supervisorconfigv1alpha1.OIDCClientSpec, expectedPhase supervisorconfigv1alpha1.OIDCClientPhase) (string, string) {
t.Helper()
env := IntegrationEnv(t)
client := NewSupervisorClientset(t)
@@ -520,7 +520,7 @@ func CreateOIDCClient(t *testing.T, spec configv1alpha1.OIDCClientSpec, expected
oidcClientClient := client.ConfigV1alpha1().OIDCClients(env.SupervisorNamespace)
// Create the OIDCClient using GenerateName to get a random name.
created, err := oidcClientClient.Create(ctx, &configv1alpha1.OIDCClient{
created, err := oidcClientClient.Create(ctx, &supervisorconfigv1alpha1.OIDCClient{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "client.oauth.pinniped.dev-test-", // use the required name prefix
Labels: map[string]string{"pinniped.dev/test": ""},
@@ -542,7 +542,7 @@ func CreateOIDCClient(t *testing.T, spec configv1alpha1.OIDCClientSpec, expected
clientSecret := createOIDCClientSecret(t, created)
// Wait for the OIDCClient to enter the expected phase (or time out).
var result *configv1alpha1.OIDCClient
var result *supervisorconfigv1alpha1.OIDCClient
RequireEventuallyf(t, func(requireEventually *require.Assertions) {
var err error
result, err = oidcClientClient.Get(ctx, created.Name, metav1.GetOptions{})
@@ -553,7 +553,7 @@ func CreateOIDCClient(t *testing.T, spec configv1alpha1.OIDCClientSpec, expected
return created.Name, clientSecret
}
func createOIDCClientSecret(t *testing.T, forOIDCClient *configv1alpha1.OIDCClient) string {
func createOIDCClientSecret(t *testing.T, forOIDCClient *supervisorconfigv1alpha1.OIDCClient) string {
t.Helper()
env := IntegrationEnv(t)
supervisorClient := NewSupervisorClientset(t)
+2 -2
View File
@@ -1,11 +1,11 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package testlib
import "github.com/davecgh/go-spew/spew"
func Sdump(a ...interface{}) string {
func Sdump(a ...any) string {
config := spew.ConfigState{
Indent: "\t",
MaxDepth: 10, // prevent log explosion