|
9 | 9 | package rest |
10 | 10 |
|
11 | 11 | import ( |
| 12 | + "fmt" |
12 | 13 | "net/http" |
13 | 14 | "strconv" |
14 | 15 | "strings" |
@@ -404,6 +405,74 @@ func TestCORSOriginPerDatabase(t *testing.T) { |
404 | 405 | } |
405 | 406 | } |
406 | 407 |
|
| 408 | +func TestCORSLoginOriginPerDatabase(t *testing.T) { |
| 409 | + // Override the default (example.com) CORS configuration in the DbConfig for /db: |
| 410 | + rt := NewRestTesterPersistentConfigNoDB(t) |
| 411 | + defer rt.Close() |
| 412 | + dbConfig := rt.NewDbConfig() |
| 413 | + dbConfig.CORS = &auth.CORSConfig{ |
| 414 | + Origin: []string{"http://couchbase.com", "http://staging.couchbase.com"}, |
| 415 | + LoginOrigin: []string{"http://couchbase.com"}, |
| 416 | + Headers: []string{}, |
| 417 | + } |
| 418 | + RequireStatus(t, rt.CreateDatabase("dbloginorigin", dbConfig), http.StatusCreated) |
| 419 | + |
| 420 | + const username = "alice" |
| 421 | + rt.CreateUser(username, nil) |
| 422 | + |
| 423 | + testCases := []struct { |
| 424 | + name string |
| 425 | + origin string |
| 426 | + responseCode int |
| 427 | + responseErrorBody string |
| 428 | + }{ |
| 429 | + { |
| 430 | + name: "CORS login origin allowed couchbase", |
| 431 | + origin: "http://couchbase.com", |
| 432 | + responseCode: http.StatusOK, |
| 433 | + }, |
| 434 | + { |
| 435 | + name: "CORS login origin not allowed staging", |
| 436 | + origin: "http://staging.couchbase.com", |
| 437 | + responseCode: http.StatusBadRequest, |
| 438 | + responseErrorBody: "No CORS", |
| 439 | + }, |
| 440 | + } |
| 441 | + for _, test := range testCases { |
| 442 | + rt.Run(test.name, func(t *testing.T) { |
| 443 | + reqHeaders := map[string]string{ |
| 444 | + "Origin": test.origin, |
| 445 | + "Authorization": GetBasicAuthHeader(t, username, RestTesterDefaultUserPassword), |
| 446 | + } |
| 447 | + resp := rt.SendRequestWithHeaders(http.MethodPost, "/{{.db}}/_session", "", reqHeaders) |
| 448 | + RequireStatus(t, resp, test.responseCode) |
| 449 | + if test.responseErrorBody != "" { |
| 450 | + require.Contains(t, resp.Body.String(), test.responseErrorBody) |
| 451 | + // the access control headers are returned based on Origin and not LoginOrigin which could be considered a bug |
| 452 | + require.Equal(t, test.origin, resp.Header().Get(accessControlAllowOrigin)) |
| 453 | + } else { |
| 454 | + require.Equal(t, test.origin, resp.Header().Get(accessControlAllowOrigin)) |
| 455 | + } |
| 456 | + if test.responseCode == http.StatusOK { |
| 457 | + cookie, err := http.ParseSetCookie(resp.Header().Get("Set-Cookie")) |
| 458 | + require.NoError(t, err) |
| 459 | + require.NotEmpty(t, cookie.Path) |
| 460 | + reqHeaders["Cookie"] = fmt.Sprintf("%s=%s", cookie.Name, cookie.Value) |
| 461 | + } |
| 462 | + resp = rt.SendRequestWithHeaders(http.MethodDelete, "/{{.db}}/_session", "", reqHeaders) |
| 463 | + RequireStatus(t, resp, test.responseCode) |
| 464 | + if test.responseErrorBody != "" { |
| 465 | + require.Contains(t, resp.Body.String(), test.responseErrorBody) |
| 466 | + // the access control headers are returned based on Origin and not LoginOrigin which could be considered a bug |
| 467 | + require.Equal(t, test.origin, resp.Header().Get(accessControlAllowOrigin)) |
| 468 | + } else { |
| 469 | + require.Equal(t, test.origin, resp.Header().Get(accessControlAllowOrigin)) |
| 470 | + } |
| 471 | + |
| 472 | + }) |
| 473 | + } |
| 474 | +} |
| 475 | + |
407 | 476 | func TestCORSValidation(t *testing.T) { |
408 | 477 | rt := NewRestTester(t, &RestTesterConfig{ |
409 | 478 | PersistentConfig: true, |
|
0 commit comments