github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/features/API.feature (about)

     1  Feature: Manage proxies wit API.
     2      As an authenticated admin user, I need to be able to manage proxies list.
     3  
     4      Scenario: API list must not be available w/out valid JWT token
     5          Given request JWT token is not set
     6          When I request "/apis" API path with "GET" method
     7          Then I should receive 401 response code
     8  
     9          Given request header "Authorization" is set to "Basic YWRtaW46YWRtaW4="
    10          When I request "/apis" API path with "GET" method
    11          Then I should receive 401 response code
    12  
    13          Given request header "Authorization" is set to "Bearer InvalidJWT"
    14          When I request "/apis" API path with "GET" method
    15          Then I should receive 401 response code
    16  
    17      Scenario: API list must return empty list when no endpoints set
    18          Given request JWT token is valid admin token
    19          When I request "/apis" API path with "GET" method
    20          Then I should receive 200 response code
    21          And response JSON body is an array of length 0
    22  
    23      Scenario: API should be created with defaults
    24          Given request JWT token is valid admin token
    25          And request JSON payload:
    26              """
    27              {
    28                "name":"example",
    29                "proxy":{
    30                  "listen_path":"/example/*",
    31                  "upstreams":{
    32                    "balancing":"roundrobin",
    33                    "targets":[
    34                      {
    35                        "target":"http://localhost:9089/hello-world"
    36                      }
    37                    ]
    38                  }
    39                }
    40              }
    41              """
    42          When I request "/apis" API path with "POST" method
    43          Then I should receive 201 response code
    44          And header "Location" should be "/apis/example"
    45  
    46          When I request "/apis" API path with "GET" method
    47          Then I should receive 200 response code
    48          And response JSON body is an array of length 1
    49          And response JSON body has "0.active" path with value 'true'
    50          And response JSON body has "0.proxy.methods" path and is an array of length 1
    51  
    52      Scenario: APIs list and create must be available for user with correct admin token
    53          Given request JWT token is valid admin token
    54          When I request "/apis" API path with "GET" method
    55          Then I should receive 200 response code
    56          And response JSON body is an array of length 0
    57  
    58          Given request JSON payload:
    59              """
    60              {
    61                "name":"example",
    62                "active":true,
    63                "proxy":{
    64                  "preserve_host":false,
    65                  "listen_path":"/example/*",
    66                  "upstreams":{
    67                    "balancing":"roundrobin",
    68                    "targets":[
    69                      {
    70                        "target":"http://localhost:9089/hello-world"
    71                      }
    72                    ]
    73                  },
    74                  "strip_path":false,
    75                  "append_path":false,
    76                  "methods":[
    77                    "GET"
    78                  ]
    79                },
    80                "health_check":{
    81                  "url":"https://example.com/status"
    82                }
    83              }
    84              """
    85          When I request "/apis" API path with "POST" method
    86          Then I should receive 201 response code
    87          And header "Location" should be "/apis/example"
    88  
    89          When I request "/apis" API path with "GET" method
    90          Then I should receive 200 response code
    91          And response JSON body is an array of length 1
    92          And response JSON body has "0.name" path with value 'example'
    93          And response JSON body has "0.active" path with value 'true'
    94  
    95          Given request JSON payload:
    96              """
    97              {
    98                  "name":"posts",
    99                  "active":true,
   100                  "proxy":{
   101                      "preserve_host":false,
   102                      "listen_path":"/posts/*",
   103                      "upstreams":{
   104                          "balancing":"roundrobin",
   105                          "targets":[
   106                              {
   107                                  "target":"http://localhost:9089/posts"
   108                              }
   109                          ]
   110                      },
   111                      "strip_path":true,
   112                      "append_path":false,
   113                      "methods":[
   114                          "ALL"
   115                      ],
   116                      "hosts":[
   117                          "hellofresh.*"
   118                      ]
   119                  },
   120                  "plugins":[
   121                      {
   122                          "name":"cors",
   123                          "enabled":true,
   124                          "config":{
   125                              "domains":[
   126                                  "*"
   127                              ],
   128                              "methods":[
   129                                  "GET",
   130                                  "POST",
   131                                  "PUT",
   132                                  "PATCH",
   133                                  "DELETE"
   134                              ],
   135                              "request_headers":[
   136                                  "Origin",
   137                                  "Authorization",
   138                                  "Content-Type"
   139                              ],
   140                              "exposed_headers":[
   141                                  "X-Debug-Token",
   142                                  "X-Debug-Token-Link"
   143                              ]
   144                          }
   145                      },
   146                      {
   147                          "name":"rate_limit",
   148                          "enabled":true,
   149                          "config":{
   150                              "limit":"10-S",
   151                              "policy":"local"
   152                          }
   153                      },
   154                      {
   155                          "name":"oauth2",
   156                          "enabled":true,
   157                          "config":{
   158                              "server_name":"local"
   159                          }
   160                      },
   161                      {
   162                          "name":"compression",
   163                          "enabled":true
   164                      }
   165                  ]
   166              }
   167              """
   168          When I request "/apis" API path with "POST" method
   169          Then I should receive 201 response code
   170          And header "Location" should be "/apis/posts"
   171  
   172          When I request "/apis" API path with "GET" method
   173          Then I should receive 200 response code
   174          And response JSON body is an array of length 2
   175  
   176      Scenario: API fails to create routes with invalid fields
   177          Given request JWT token is valid admin token
   178          And request JSON payload:
   179              """
   180              {
   181                  "active":true,
   182                  "proxy":{
   183                      "listen_path":"/example/*",
   184                      "upstreams":{
   185                          "balancing":"roundrobin",
   186                          "targets":[
   187                              {
   188                                  "target":"http://localhost:9089/hello-world"
   189                              }
   190                          ]
   191                      }
   192                  }
   193              }
   194              """
   195          When I request "/apis" API path with "POST" method
   196          Then I should receive 400 response code
   197          And the response should contain "name is required"
   198  
   199          Given request JWT token is valid admin token
   200          And request JSON payload:
   201              """
   202              {
   203                  "name": "example",
   204                  "active":true,
   205                  "proxy":{
   206                      "upstreams":{
   207                          "balancing":"roundrobin",
   208                          "targets":[
   209                              {
   210                                  "target":"http://localhost:9089/hello-world"
   211                              }
   212                          ]
   213                      }
   214                  }
   215              }
   216              """
   217          When I request "/apis" API path with "POST" method
   218          Then I should receive 400 response code
   219          And the response should contain "proxy.listen_path is required"
   220  
   221      Scenario: API fails to create routes with the same name
   222          Given request JWT token is valid admin token
   223          And request JSON payload:
   224              """
   225              {
   226                  "name":"example",
   227                  "active":true,
   228                  "proxy":{
   229                      "preserve_host":false,
   230                      "listen_path":"/example/*",
   231                      "upstreams":{
   232                          "balancing":"roundrobin",
   233                          "targets":[
   234                              {
   235                                  "target":"http://localhost:9089/hello-world"
   236                              }
   237                          ]
   238                      },
   239                      "strip_path":false,
   240                      "append_path":false,
   241                      "methods":[
   242                          "GET"
   243                      ]
   244                  },
   245                  "health_check":{
   246                      "url":"https://example.com/status"
   247                  }
   248              }
   249              """
   250          When I request "/apis" API path with "POST" method
   251          Then I should receive 201 response code
   252          And header "Location" should be "/apis/example"
   253  
   254          Given request JSON payload:
   255              """
   256              {
   257                  "name":"example",
   258                  "active":true,
   259                  "proxy":{
   260                      "preserve_host":false,
   261                      "listen_path":"/example/*",
   262                      "upstreams":{
   263                          "balancing":"roundrobin",
   264                          "targets":[
   265                              {
   266                                  "target":"http://localhost:9089/hello-world"
   267                              }
   268                          ]
   269                      },
   270                      "strip_path":false,
   271                      "append_path":false,
   272                      "methods":[
   273                          "GET"
   274                      ]
   275                  },
   276                  "health_check":{
   277                      "url":"https://example.com/status"
   278                  }
   279              }
   280              """
   281          When I request "/apis" API path with "POST" method
   282          Then I should receive 409 response code
   283          And the response should contain "api name is already registered"
   284  
   285          Given request JSON payload:
   286              """
   287              {
   288                  "name":"example1",
   289                  "active":true,
   290                  "proxy":{
   291                      "preserve_host":false,
   292                      "listen_path":"/example/*",
   293                      "upstreams":{
   294                          "balancing":"roundrobin",
   295                          "targets":[
   296                              {
   297                                  "target":"http://localhost:9089/hello-world"
   298                              }
   299                          ]
   300                      },
   301                      "strip_path":false,
   302                      "append_path":false,
   303                      "methods":[
   304                          "GET"
   305                      ]
   306                  },
   307                  "health_check":{
   308                      "url":"https://example.com/status"
   309                  }
   310              }
   311              """
   312          When I request "/apis" API path with "POST" method
   313          Then I should receive 409 response code
   314          And the response should contain "api listen path is already registered"
   315  
   316      Scenario: API must return existing routes and response with error for non-existent
   317          Given request JWT token is valid admin token
   318          When I request "/apis/example" API path with "GET" method
   319          Then I should receive 404 response code
   320  
   321          Given request JSON payload:
   322              """
   323              {
   324                  "name":"example",
   325                  "active":true,
   326                  "proxy":{
   327                      "preserve_host":false,
   328                      "listen_path":"/example/*",
   329                      "upstreams":{
   330                          "balancing":"roundrobin",
   331                          "targets":[
   332                              {
   333                                  "target":"http://localhost:9089/hello-world"
   334                              }
   335                          ]
   336                      },
   337                      "strip_path":false,
   338                      "append_path":false,
   339                      "methods":[
   340                          "GET"
   341                      ]
   342                  },
   343                  "health_check":{
   344                      "url":"https://example.com/status"
   345                  }
   346              }
   347              """
   348          When I request "/apis" API path with "POST" method
   349          Then I should receive 201 response code
   350  
   351          When I request "/apis/example" API path with "GET" method
   352          Then I should receive 200 response code
   353          And response JSON body has "name" path with value 'example'
   354  
   355          When I request "/apis/example" API path with "DELETE" method
   356          Then I should receive 204 response code
   357  
   358      Scenario: API must update existing routes with new path value
   359          Given request JWT token is valid admin token
   360          And request JSON payload:
   361              """
   362              {
   363                  "name":"example",
   364                  "active":true,
   365                  "proxy":{
   366                      "preserve_host":false,
   367                      "listen_path":"/example/*",
   368                      "upstreams":{
   369                          "balancing":"roundrobin",
   370                          "targets":[
   371                              {
   372                                  "target":"http://localhost:9089/hello-world"
   373                              }
   374                          ]
   375                      },
   376                      "strip_path":false,
   377                      "append_path":false,
   378                      "methods":[
   379                          "GET"
   380                      ]
   381                  },
   382                  "health_check":{
   383                      "url":"https://example.com/status"
   384                  }
   385              }
   386              """
   387          When I request "/apis" API path with "POST" method
   388          Then I should receive 201 response code
   389          And header "Location" should be "/apis/example"
   390  
   391          When I request "/apis/example" API path with "GET" method
   392          Then I should receive 200 response code
   393          And response JSON body has "name" path with value 'example'
   394          And response JSON body has "proxy.listen_path" path with value '/example/*'
   395  
   396          Given request JSON payload:
   397              """
   398              {
   399                  "name":"example",
   400                  "active":true,
   401                  "proxy":{
   402                      "preserve_host":false,
   403                      "listen_path":"/example1/*",
   404                      "upstreams":{
   405                          "balancing":"roundrobin",
   406                          "targets":[
   407                              {
   408                                  "target":"http://localhost:9089/hello-world"
   409                              }
   410                          ]
   411                      },
   412                      "strip_path":false,
   413                      "append_path":false,
   414                      "methods":[
   415                          "GET"
   416                      ]
   417                  },
   418                  "health_check":{
   419                      "url":"https://example.com/status"
   420                  }
   421              }
   422              """
   423          When I request "/apis/example" API path with "PUT" method
   424          Then I should receive 200 response code
   425  
   426          When I request "/apis/example" API path with "GET" method
   427          Then I should receive 200 response code
   428          And response JSON body has "name" path with value 'example'
   429          And response JSON body has "proxy.listen_path" path with value '/example1/*'
   430  
   431          When I request "/apis/foo-bar" API path with "GET" method
   432          Then I should receive 404 response code
   433  
   434      Scenario: API must update existing routes with new forwarding timeouts
   435          Given request JWT token is valid admin token
   436          And request JSON payload:
   437              """
   438              {
   439                  "name":"example",
   440                  "active":true,
   441                  "proxy":{
   442                      "preserve_host":false,
   443                      "listen_path":"/example/*",
   444                      "upstreams":{
   445                          "balancing":"roundrobin",
   446                          "targets":[
   447                              {
   448                                  "target":"http://localhost:9089/hello-world"
   449                              }
   450                          ]
   451                      },
   452                      "strip_path":false,
   453                      "append_path":false,
   454                      "methods":[
   455                          "GET"
   456                      ],
   457                      "forwarding_timeouts": {
   458                          "dial_timeout": "5s",
   459                          "response_header_timeout": "7s"
   460                      }
   461                  },
   462                  "health_check":{
   463                      "url":"https://example.com/status"
   464                  }
   465              }
   466              """
   467          When I request "/apis" API path with "POST" method
   468          Then I should receive 201 response code
   469          And header "Location" should be "/apis/example"
   470  
   471          When I request "/apis/example" API path with "GET" method
   472          Then I should receive 200 response code
   473          And response JSON body has "proxy.forwarding_timeouts.dial_timeout" path with value '5s'
   474          And response JSON body has "proxy.forwarding_timeouts.response_header_timeout" path with value '7s'
   475  
   476          Given request JSON payload:
   477              """
   478              {
   479                  "name":"example",
   480                  "active":true,
   481                  "proxy":{
   482                      "preserve_host":false,
   483                      "listen_path":"/example/*",
   484                      "upstreams":{
   485                          "balancing":"roundrobin",
   486                          "targets":[
   487                              {
   488                                  "target":"http://localhost:9089/hello-world"
   489                              }
   490                          ]
   491                      },
   492                      "strip_path":false,
   493                      "append_path":false,
   494                      "methods":[
   495                          "GET"
   496                      ],
   497                      "forwarding_timeouts": {
   498                          "dial_timeout": "15s",
   499                          "response_header_timeout": "17s"
   500                      }
   501                  },
   502                  "health_check":{
   503                      "url":"https://example.com/status"
   504                  }
   505              }
   506              """
   507          When I request "/apis/example" API path with "PUT" method
   508          Then I should receive 200 response code
   509  
   510          When I request "/apis/example" API path with "GET" method
   511          Then I should receive 200 response code
   512          And response JSON body has "proxy.forwarding_timeouts.dial_timeout" path with value '15s'
   513          And response JSON body has "proxy.forwarding_timeouts.response_header_timeout" path with value '17s'
   514  
   515      Scenario: API must delete existing routes
   516          Given request JWT token is valid admin token
   517          And request JSON payload:
   518              """
   519              {
   520                  "name":"example",
   521                  "active":true,
   522                  "proxy":{
   523                      "preserve_host":false,
   524                      "listen_path":"/example/*",
   525                      "upstreams":{
   526                          "balancing":"roundrobin",
   527                          "targets":[
   528                              {
   529                                  "target":"http://localhost:9089/hello-world"
   530                              }
   531                          ]
   532                      },
   533                      "strip_path":false,
   534                      "append_path":false,
   535                      "methods":[
   536                          "GET"
   537                      ]
   538                  },
   539                  "health_check":{
   540                      "url":"https://example.com/status"
   541                  }
   542              }
   543              """
   544          When I request "/apis" API path with "POST" method
   545          Then I should receive 201 response code
   546          And header "Location" should be "/apis/example"
   547  
   548          Given request JSON payload:
   549              """
   550              {
   551                    "name":"posts",
   552                    "active":true,
   553                    "proxy":{
   554                      "preserve_host":false,
   555                      "listen_path":"/posts/*",
   556                      "upstreams":{
   557                        "balancing":"roundrobin",
   558                        "targets":[
   559                          {
   560                            "target":"http://localhost:9089/posts"
   561                          }
   562                        ]
   563                      },
   564                      "strip_path":true,
   565                      "append_path":false,
   566                      "methods":[
   567                        "ALL"
   568                      ],
   569                      "hosts":[
   570                        "hellofresh.*"
   571                      ]
   572                    },
   573                    "plugins":[
   574                      {
   575                        "name":"cors",
   576                        "enabled":true,
   577                        "config":{
   578                          "domains":[
   579                            "*"
   580                          ],
   581                          "methods":[
   582                            "GET",
   583                            "POST",
   584                            "PUT",
   585                            "PATCH",
   586                            "DELETE"
   587                          ],
   588                          "request_headers":[
   589                            "Origin",
   590                            "Authorization",
   591                            "Content-Type"
   592                          ],
   593                          "exposed_headers":[
   594                            "X-Debug-Token",
   595                            "X-Debug-Token-Link"
   596                          ]
   597                        }
   598                      },
   599                      {
   600                        "name":"rate_limit",
   601                        "enabled":true,
   602                        "config":{
   603                          "limit":"10-S",
   604                          "policy":"local"
   605                        }
   606                      },
   607                      {
   608                        "name":"oauth2",
   609                        "enabled":true,
   610                        "config":{
   611                          "server_name":"local"
   612                        }
   613                      },
   614                      {
   615                        "name":"compression",
   616                        "enabled":true
   617                      }
   618                  ]
   619              }
   620              """
   621          When I request "/apis" API path with "POST" method
   622          Then I should receive 201 response code
   623          And header "Location" should be "/apis/posts"
   624  
   625          When I request "/apis" API path with "GET" method
   626          Then I should receive 200 response code
   627          And response JSON body is an array of length 2
   628  
   629          When I request "/apis/example" API path with "DELETE" method
   630          Then I should receive 204 response code
   631  
   632          When I request "/apis" API path with "GET" method
   633          Then I should receive 200 response code
   634          And response JSON body is an array of length 1
   635  
   636          When I request "/apis/example" API path with "DELETE" method
   637          Then I should receive 404 response code
   638  
   639          When I request "/apis/posts" API path with "DELETE" method
   640          Then I should receive 204 response code
   641  
   642          When I request "/apis" API path with "GET" method
   643          Then I should receive 200 response code
   644          And response JSON body is an array of length 0
   645  
   646          When I request "/apis/posts" API path with "DELETE" method
   647          Then I should receive 404 response code
   648  
   649      Scenario: API fails to create oauth servers with the same name
   650          Given request JWT token is valid admin token
   651          And request JSON payload:
   652              """
   653              {
   654                  "name" : "oauth-server-test",
   655                  "oauth_endpoints" : {
   656                      "authorize" : {
   657                          "listen_path" : "/auth/github/authorize",
   658                          "methods" : [
   659                              "ALL"
   660                          ],
   661                          "preserve_host" : false,
   662                          "strip_path" : false,
   663                          "upstreams":{
   664                              "balancing":"roundrobin",
   665                              "targets":[
   666                                  {
   667                                  "target":"https://github.com/login/oauth/authorize"
   668                                  }
   669                              ]
   670                          }
   671                      },
   672                      "token" : {
   673                          "listen_path" : "/auth/github/token",
   674                          "methods" : [
   675                              "GET",
   676                              "POST"
   677                          ],
   678                          "preserve_host" : false,
   679                          "strip_path" : false,
   680                          "upstreams":{
   681                              "balancing":"roundrobin",
   682                              "targets":[
   683                                  {
   684                                  "target":"https://github.com/login/oauth/access_token"
   685                                  }
   686                              ]
   687                          }
   688                      },
   689                      "introspect" : {
   690                          "listen_path" : "/auth/github/introspect",
   691                          "methods" : [
   692                              "GET"
   693                          ],
   694                          "preserve_host" : false,
   695                          "strip_path" : false,
   696                          "upstreams":{
   697                              "balancing":"roundrobin",
   698                              "targets":[
   699                                  {
   700                                  "target":"https://api.github.com/user"
   701                                  }
   702                              ]
   703                          }
   704                      }
   705                  },
   706                  "secrets" : {
   707                      "admin" : "admin"
   708                  },
   709                  "cors_meta" : {
   710                      "domains" : [
   711                          "*"
   712                      ],
   713                      "methods" : [
   714                          "GET",
   715                          "POST",
   716                          "PUT",
   717                          "PATCH",
   718                          "DELETE"
   719                      ],
   720                      "request_headers" : [
   721                          "Origin",
   722                          "Authorization",
   723                          "Content-Type"
   724                      ],
   725                      "exposed_headers" : [
   726                          "X-Debug-Token",
   727                          "X-Debug-Token-Link"
   728                      ],
   729                      "enabled" : true
   730                  },
   731                  "rate_limit" : {
   732                      "limit" : "200-S"
   733                  },
   734                  "token_strategy" : {
   735                      "name" : "introspection",
   736                      "settings" : {
   737                          "use_auth_header" : true,
   738                          "auth_header_type" : "token"
   739                      }
   740                  }
   741              }
   742              """
   743          When I request "/oauth/servers" API path with "POST" method
   744          Then I should receive 201 response code
   745  
   746          Given request JSON payload:
   747              """
   748              {
   749                  "name" : "oauth-server-test",
   750                  "oauth_endpoints" : {
   751                      "authorize" : {
   752                          "listen_path" : "/auth/github/authorize",
   753                          "methods" : [
   754                              "ALL"
   755                          ],
   756                          "preserve_host" : false,
   757                          "strip_path" : false,
   758                          "upstreams":{
   759                              "balancing":"roundrobin",
   760                              "targets":[
   761                                  {
   762                                  "target":"https://github.com/login/oauth/authorize"
   763                                  }
   764                              ]
   765                          }
   766                      },
   767                      "token" : {
   768                          "listen_path" : "/auth/github/token",
   769                          "methods" : [
   770                              "GET",
   771                              "POST"
   772                          ],
   773                          "preserve_host" : false,
   774                          "strip_path" : false,
   775                          "upstreams":{
   776                              "balancing":"roundrobin",
   777                              "targets":[
   778                                  {
   779                                  "target":"https://github.com/login/oauth/access_token"
   780                                  }
   781                              ]
   782                          }
   783                      },
   784                      "introspect" : {
   785                          "listen_path" : "/auth/github/introspect",
   786                          "methods" : [
   787                              "GET"
   788                          ],
   789                          "preserve_host" : false,
   790                          "strip_path" : false,
   791                          "upstreams":{
   792                              "balancing":"roundrobin",
   793                              "targets":[
   794                                  {
   795                                  "target":"https://api.github.com/user"
   796                                  }
   797                              ]
   798                          }
   799                      }
   800                  },
   801                  "secrets" : {
   802                      "admin" : "admin"
   803                  },
   804                  "cors_meta" : {
   805                      "domains" : [
   806                          "*"
   807                      ],
   808                      "methods" : [
   809                          "GET",
   810                          "POST",
   811                          "PUT",
   812                          "PATCH",
   813                          "DELETE"
   814                      ],
   815                      "request_headers" : [
   816                          "Origin",
   817                          "Authorization",
   818                          "Content-Type"
   819                      ],
   820                      "exposed_headers" : [
   821                          "X-Debug-Token",
   822                          "X-Debug-Token-Link"
   823                      ],
   824                      "enabled" : true
   825                  },
   826                  "rate_limit" : {
   827                      "limit" : "200-S"
   828                  },
   829                  "token_strategy" : {
   830                      "name" : "introspection",
   831                      "settings" : {
   832                          "use_auth_header" : true,
   833                          "auth_header_type" : "token"
   834                      }
   835                  }
   836              }
   837              """
   838          When I request "/oauth/servers" API path with "POST" method
   839          Then I should receive 409 response code
   840          And the response should contain "oauth server name is already registered"