@@ -2,17 +2,19 @@ package oauth
2
2
3
3
import (
4
4
"context"
5
+ "crypto/sha256"
5
6
"io/ioutil"
6
7
"os"
7
8
"path"
9
+ "strings"
8
10
9
11
g "github.com/onsi/ginkgo/v2"
10
12
o "github.com/onsi/gomega"
11
13
12
14
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
15
"k8s.io/apiserver/pkg/authentication/user"
14
- "k8s.io/client-go/rest"
15
16
restclient "k8s.io/client-go/rest"
17
+ e2e "k8s.io/kubernetes/test/e2e/framework"
16
18
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
17
19
18
20
configv1 "github.com/openshift/api/config/v1"
@@ -58,9 +60,8 @@ var _ = g.Describe("[sig-auth][Feature:OAuthServer] OAuth server", func() {
58
60
// openssl s_client shows the kube-control-plane-signer CA name sent as one of the acceptable client CAs, so use that.
59
61
realCASecret , err := oc .AsAdmin ().KubeClient ().CoreV1 ().Secrets ("openshift-kube-apiserver-operator" ).Get (context .Background (), "kube-control-plane-signer" , metav1.GetOptions {})
60
62
o .Expect (err ).NotTo (o .HaveOccurred ())
61
-
62
63
realCAPEM , ok := realCASecret .Data ["tls.crt" ]
63
- o .Expect (ok ).NotTo (o .BeFalse ())
64
+ o .Expect (ok ).To (o .BeTrue ())
64
65
65
66
realCA , err := crypto .CertsFromPEM (realCAPEM )
66
67
o .Expect (err ).NotTo (o .HaveOccurred ())
@@ -87,86 +88,128 @@ var _ = g.Describe("[sig-auth][Feature:OAuthServer] OAuth server", func() {
87
88
o .Expect (err ).NotTo (o .HaveOccurred ())
88
89
89
90
fooUserConfig := oc .GetClientConfigForUser (tokenUser )
90
- o .Expect (err ).NotTo (o .HaveOccurred ())
91
+ o .Expect (fooUserConfig ).NotTo (o .BeNil ())
91
92
validToken := fooUserConfig .BearerToken
92
93
o .Expect (validToken ).ToNot (o .BeEmpty ())
93
94
94
95
adminConfig := oc .AdminConfig ()
95
96
validCert := adminConfig .TLSClientConfig
96
97
98
+ // Cache certs in a map
99
+ certs := map [string ]restclient.TLSClientConfig {
100
+ "validCert" : validCert ,
101
+ "invalidCert" : invalidCert ,
102
+ "noCert" : noCert ,
103
+ }
104
+
97
105
for name , test := range map [string ]struct {
98
106
token string
99
- cert rest. TLSClientConfig
107
+ certKey string // use "validCert", "invalidCert", or "noCert"
100
108
expectedUser string
101
109
errorExpected bool
102
110
errorString string
103
111
}{
104
112
"valid token, valid cert" : {
105
113
token : validToken ,
106
- cert : validCert ,
107
- expectedUser : certUser ,
114
+ certKey : " validCert" ,
115
+ expectedUser : certUser , // If cert is valid, it takes precedence over token (because client certs are stronger auth).
108
116
},
117
+
109
118
"valid token, invalid cert" : {
110
119
token : validToken ,
111
- cert : invalidCert ,
120
+ certKey : " invalidCert" ,
112
121
expectedUser : tokenUser ,
113
122
},
123
+
114
124
"valid token, no cert" : {
115
125
token : validToken ,
116
- cert : noCert ,
126
+ certKey : " noCert" ,
117
127
expectedUser : tokenUser ,
118
128
},
129
+
119
130
"invalid token, valid cert" : {
120
131
token : invalidToken ,
121
- cert : validCert ,
132
+ certKey : " validCert" ,
122
133
expectedUser : certUser ,
123
134
},
135
+
124
136
"invalid token, invalid cert" : {
125
137
token : invalidToken ,
126
- cert : invalidCert ,
138
+ certKey : " invalidCert" ,
127
139
errorExpected : true ,
128
140
errorString : unauthorizedError ,
129
141
},
142
+
130
143
"invalid token, no cert" : {
131
144
token : invalidToken ,
132
- cert : noCert ,
145
+ certKey : " noCert" ,
133
146
errorExpected : true ,
134
147
errorString : unauthorizedError ,
135
148
},
149
+
136
150
"no token, valid cert" : {
137
151
token : noToken ,
138
- cert : validCert ,
152
+ certKey : " validCert" ,
139
153
expectedUser : certUser ,
140
154
},
155
+
141
156
"no token, invalid cert" : {
142
157
token : noToken ,
143
- cert : invalidCert ,
158
+ certKey : " invalidCert" ,
144
159
errorExpected : true ,
145
160
errorString : unauthorizedError ,
146
161
},
162
+
147
163
"no token, no cert" : {
148
164
token : noToken ,
149
- cert : noCert ,
165
+ certKey : " noCert" ,
150
166
errorExpected : true ,
151
167
errorString : anonymousError ,
152
168
},
153
169
} {
154
170
g .By (name )
171
+
172
+ // Skip if test requires validCert but kubeconfig doesn't have one
173
+ if test .certKey == "validCert" && len (validCert .CertData ) == 0 && validCert .CertFile == "" {
174
+ e2e .Logf ("Skipping test '%s': no available client certificate in kubeconfig" , name )
175
+ continue
176
+ }
177
+
155
178
adminConfig := restclient .AnonymousClientConfig (oc .AdminConfig ())
179
+ adminConfig .TLSClientConfig = certs [test .certKey ]
156
180
adminConfig .BearerToken = test .token
157
- adminConfig .TLSClientConfig = test .cert
158
181
adminConfig .CAData = oc .AdminConfig ().CAData
159
182
183
+ tokenPrefix := test .token
184
+ if strings .HasPrefix (test .token , "sha256~" ) && len (test .token ) > len ("sha256~" )+ 6 {
185
+ tokenPrefix = test .token [:len ("sha256~" )+ 6 ] + "..."
186
+ }
187
+ e2e .Logf ("Test case '%s': token='%s', using cert='%s'\n " , name , tokenPrefix , test .certKey )
188
+ if len (adminConfig .TLSClientConfig .CertData ) > 0 {
189
+ certs , err := crypto .CertsFromPEM (adminConfig .TLSClientConfig .CertData )
190
+ if err != nil {
191
+ e2e .Logf ("Failed to parse cert: %v\n " , err )
192
+ } else {
193
+ for i , cert := range certs {
194
+ fingerprint := sha256 .Sum256 (cert .Raw )
195
+ e2e .Logf ("Cert[%d]: Subject=%s, Issuer=%s, SHA256=%x%s\n " ,
196
+ i , cert .Subject .String (), cert .Issuer .String (), fingerprint [:3 ], "xxxxxx" )
197
+ }
198
+ }
199
+ } else {
200
+ e2e .Logf ("no available client certificate in kubeconfig\n " )
201
+ }
202
+
160
203
userClient := userv1client .NewForConfigOrDie (adminConfig )
161
204
user , err := userClient .UserV1 ().Users ().Get (context .Background (), "~" , metav1.GetOptions {})
162
205
163
206
if test .errorExpected {
164
207
o .Expect (err ).ToNot (o .BeNil ())
165
208
o .Expect (err .Error ()).To (o .Equal (test .errorString ))
166
209
} else {
210
+ o .Expect (err ).To (o .BeNil ())
167
211
o .Expect (user ).ToNot (o .BeNil ())
168
212
o .Expect (user .Name ).To (o .Equal (test .expectedUser ))
169
- o .Expect (err ).To (o .BeNil ())
170
213
}
171
214
}
172
215
})
0 commit comments