|
5 | 5 | "crypto/tls" |
6 | 6 | "time" |
7 | 7 |
|
| 8 | + "github.com/couchbase/gocbcorex/cbhttpx" |
| 9 | + "github.com/couchbase/gocbcorex/cbmgmtx" |
8 | 10 | "github.com/couchbase/goprotostellar/genproto/admin_query_v1" |
9 | 11 | "github.com/couchbase/goprotostellar/genproto/admin_search_v1" |
10 | 12 | "github.com/couchbase/goprotostellar/genproto/kv_v1" |
@@ -169,12 +171,142 @@ func (s *GatewayOpsTestSuite) TestClientCertAuth() { |
169 | 171 | } |
170 | 172 | requireRpcSuccess(s.T(), resp, err) |
171 | 173 | return true |
172 | | - }, time.Second*30, time.Second) |
| 174 | + }, time.Second*30, time.Second*5) |
173 | 175 | }) |
174 | 176 | }) |
175 | 177 | } |
176 | 178 | } |
177 | 179 |
|
| 180 | +func (s *GatewayOpsTestSuite) TestClientCertAuthConfiguration() { |
| 181 | + testutils.SkipIfNoDinoCluster(s.T()) |
| 182 | + dino := testutils.StartDinoTesting(s.T(), false) |
| 183 | + username := "certConfig" |
| 184 | + conn := s.newClientCertConn(dino, username) |
| 185 | + kvClient := kv_v1.NewKvServiceClient(conn) |
| 186 | + |
| 187 | + getFn := func() (*kv_v1.GetResponse, error) { |
| 188 | + return kvClient.Get(context.Background(), &kv_v1.GetRequest{ |
| 189 | + BucketName: s.bucketName, |
| 190 | + ScopeName: s.scopeName, |
| 191 | + CollectionName: s.collectionName, |
| 192 | + Key: s.testDocId(), |
| 193 | + }) |
| 194 | + } |
| 195 | + |
| 196 | + enableReq := &cbmgmtx.ConfigureClientCertAuthRequest{ |
| 197 | + State: "enable", |
| 198 | + Prefixes: []cbmgmtx.Prefix{ |
| 199 | + { |
| 200 | + Path: "san.email", |
| 201 | + Prefix: "", |
| 202 | + Delimiter: "@", |
| 203 | + }, |
| 204 | + }, |
| 205 | + } |
| 206 | + |
| 207 | + dino.AddWriteUser(username) |
| 208 | + |
| 209 | + // Check that client cert auth is working as expected. |
| 210 | + s.Run("InitialSuccess", func() { |
| 211 | + resp, err := getFn() |
| 212 | + requireRpcSuccess(s.T(), resp, err) |
| 213 | + }) |
| 214 | + |
| 215 | + ep, err := s.testClusterInfo.AdminClient.GetMgmtEndpoint(context.Background()) |
| 216 | + require.NoError(s.T(), err) |
| 217 | + mgmt := cbmgmtx.Management{ |
| 218 | + Transport: ep.RoundTripper, |
| 219 | + UserAgent: "useragent", |
| 220 | + Endpoint: ep.Endpoint, |
| 221 | + Auth: &cbhttpx.BasicAuth{ |
| 222 | + Username: ep.Username, |
| 223 | + Password: ep.Password, |
| 224 | + }, |
| 225 | + } |
| 226 | + |
| 227 | + // Change the path that cbauth will try and get the name from and check |
| 228 | + // that the old cert fails |
| 229 | + err = mgmt.ConfigureClientCertAuth(context.Background(), &cbmgmtx.ConfigureClientCertAuthRequest{ |
| 230 | + State: "enable", |
| 231 | + Prefixes: []cbmgmtx.Prefix{ |
| 232 | + { |
| 233 | + Path: "subject.cn", |
| 234 | + Prefix: "", |
| 235 | + Delimiter: "", |
| 236 | + }, |
| 237 | + }, |
| 238 | + }) |
| 239 | + assert.NoError(s.T(), err) |
| 240 | + |
| 241 | + s.Run("IncorrectUsernamePath", func() { |
| 242 | + require.Eventually(s.T(), func() bool { |
| 243 | + _, err := getFn() |
| 244 | + if err == nil { |
| 245 | + return false |
| 246 | + } |
| 247 | + |
| 248 | + assertRpcStatus(s.T(), err, codes.PermissionDenied) |
| 249 | + return assert.Contains(s.T(), err.Error(), "Your certificate is invalid") |
| 250 | + }, time.Second*30, time.Second*5) |
| 251 | + }) |
| 252 | + |
| 253 | + // Restore intial settings and check that the original cert works again. |
| 254 | + err = mgmt.ConfigureClientCertAuth(context.Background(), enableReq) |
| 255 | + assert.NoError(s.T(), err) |
| 256 | + |
| 257 | + s.Run("SuccessAfterSettingsReset", func() { |
| 258 | + require.Eventually(s.T(), func() bool { |
| 259 | + resp, err := getFn() |
| 260 | + if err != nil { |
| 261 | + return false |
| 262 | + } |
| 263 | + |
| 264 | + requireRpcSuccess(s.T(), resp, err) |
| 265 | + return true |
| 266 | + }, time.Second*30, time.Second*5) |
| 267 | + }) |
| 268 | + |
| 269 | + // Disable client cert auth on the cluster and make sure op fails. |
| 270 | + err = mgmt.ConfigureClientCertAuth(context.Background(), &cbmgmtx.ConfigureClientCertAuthRequest{ |
| 271 | + State: "disable", |
| 272 | + Prefixes: []cbmgmtx.Prefix{ |
| 273 | + { |
| 274 | + Path: "san.email", |
| 275 | + Prefix: "", |
| 276 | + Delimiter: "@", |
| 277 | + }, |
| 278 | + }, |
| 279 | + }) |
| 280 | + assert.NoError(s.T(), err) |
| 281 | + |
| 282 | + s.Run("CertAuthDisabled", func() { |
| 283 | + require.Eventually(s.T(), func() bool { |
| 284 | + _, err := getFn() |
| 285 | + if err == nil { |
| 286 | + return false |
| 287 | + } |
| 288 | + |
| 289 | + assertRpcStatus(s.T(), err, codes.Unauthenticated) |
| 290 | + return assert.Contains(s.T(), err.Error(), "Client cert auth disabled on the cluster") |
| 291 | + }, time.Second*30, time.Second*5) |
| 292 | + }) |
| 293 | + |
| 294 | + err = mgmt.ConfigureClientCertAuth(context.Background(), enableReq) |
| 295 | + assert.NoError(s.T(), err) |
| 296 | + |
| 297 | + // Ensure that client cert auth is full enabled for finishing the test so |
| 298 | + // that we don't impact other cert auth tests. |
| 299 | + require.Eventually(s.T(), func() bool { |
| 300 | + resp, err := getFn() |
| 301 | + if err != nil { |
| 302 | + return false |
| 303 | + } |
| 304 | + |
| 305 | + requireRpcSuccess(s.T(), resp, err) |
| 306 | + return true |
| 307 | + }, time.Second*30, time.Second*5) |
| 308 | +} |
| 309 | + |
178 | 310 | func (s *GatewayOpsTestSuite) newClientCertConn(dino *testutils.DinoController, username string) *grpc.ClientConn { |
179 | 311 | res := dino.GetClientCert(username) |
180 | 312 |
|
|
0 commit comments