Skip to content

Commit

Permalink
added env. variable for cors refresh interval and refined cors tests
Browse files Browse the repository at this point in the history
  • Loading branch information
angelo.andreussi committed Apr 4, 2024
1 parent 7dc92d8 commit 798c5e2
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 22 deletions.
1 change: 1 addition & 0 deletions assembly/api/docker/Dockerfile
Expand Up @@ -47,6 +47,7 @@ ENV JAVA_OPTS "-Dapi.cors.origins.allowed=\${API_CORS_ORIGINS_ALLOWED} \
-Dcrypto.secret.key=\${CRYPTO_SECRET_KEY} \
-Dauthentication.token.expire.after=\${AUTH_TOKEN_TTL} \
-Dauthentication.refresh.token.expire.after=\${REFRESH_AUTH_TOKEN_TTL} \
-Dapi.cors.refresh.interval=\${CORS_ENDPOINTS_REFRESH_INTERVAL} \
\${JETTY_DEBUG_OPTS} \
\${JETTY_JMX_OPTS}"

Expand Down
1 change: 1 addition & 0 deletions deployment/docker/compose/docker-compose.yml
Expand Up @@ -110,6 +110,7 @@ services:
- SWAGGER=${KAPUA_SWAGGER_ENABLE:-true}
- AUTH_TOKEN_TTL=${AUTH_TOKEN_TTL:-1800000}
- REFRESH_AUTH_TOKEN_TTL=${REFRESH_AUTH_TOKEN_TTL:-18000000}
- CORS_ENDPOINTS_REFRESH_INTERVAL=${CORS_ENDPOINTS_REFRESH_INTERVAL:-60}
job-engine:
container_name: job-engine
image: kapua/kapua-job-engine:${IMAGE_VERSION}
Expand Down
Expand Up @@ -280,8 +280,8 @@ private void startBaseDockerEnvironmentInternal() throws Exception {
}
}

@Given("start rest-API container and dependencies with auth token TTL {string}ms and refresh token TTL {string}ms")
public void startApiDockerEnvironment(String tokenTTL, String refreshTokenTTL) throws Exception {
@Given("start rest-API container and dependencies with auth token TTL {string}ms and refresh token TTL {string}ms and cors endpoint refresh interval {int}s")
public void startApiDockerEnvironment(String tokenTTL, String refreshTokenTTL, int corsEndpointRefreshInterval) throws Exception {
logger.info("Starting rest-api docker environment...");
stopFullDockerEnvironmentInternal();
try {
Expand All @@ -303,7 +303,7 @@ public void startApiDockerEnvironment(String tokenTTL, String refreshTokenTTL) t
this.wait(WAIT_FOR_JOB_ENGINE);
}

startAPIContainer(BasicSteps.API_CONTAINER_NAME, tokenTTL, refreshTokenTTL);
startAPIContainer(BasicSteps.API_CONTAINER_NAME, tokenTTL, refreshTokenTTL, corsEndpointRefreshInterval);
synchronized (this) {
this.wait(WAIT_FOR_JOB_ENGINE);
}
Expand Down Expand Up @@ -519,9 +519,9 @@ public void startDBContainer(String name) throws DockerException, InterruptedExc
}

@And("Start API container with name {string}")
public void startAPIContainer(String name, String tokenTTL, String refreshTokenTTL) throws DockerException, InterruptedException {
public void startAPIContainer(String name, String tokenTTL, String refreshTokenTTL, int corsEndpointRefreshInterval) throws DockerException, InterruptedException {
logger.info("Starting API container...");
ContainerConfig dbConfig = getApiContainerConfig(tokenTTL, refreshTokenTTL);
ContainerConfig dbConfig = getApiContainerConfig(tokenTTL, refreshTokenTTL, corsEndpointRefreshInterval);
ContainerCreation dbContainerCreation = DockerUtil.getDockerClient().createContainer(dbConfig, name);
String containerId = dbContainerCreation.id();

Expand Down Expand Up @@ -820,7 +820,7 @@ private ContainerConfig getDbContainerConfig() {
.build();
}

private ContainerConfig getApiContainerConfig(String tokenTTL, String refreshTokenTTL) {
private ContainerConfig getApiContainerConfig(String tokenTTL, String refreshTokenTTL, int corsEndpointRefreshInterval) {
final Map<String, List<PortBinding>> portBindings = new HashMap<>();
addHostPort(ALL_IP, portBindings, 8080, 8081);
addHostPort(ALL_IP, portBindings, 8443, 8443);
Expand All @@ -840,6 +840,7 @@ private ContainerConfig getApiContainerConfig(String tokenTTL, String refreshTok
//now I set very little TTL access token to help me in the test scenarios
"AUTH_TOKEN_TTL=" + tokenTTL,
"REFRESH_AUTH_TOKEN_TTL=" + refreshTokenTTL,
"CORS_ENDPOINTS_REFRESH_INTERVAL=" + corsEndpointRefreshInterval,
"SWAGGER=true"
)
.image("kapua/" + API_IMAGE + ":" + KAPUA_VERSION)
Expand Down
Expand Up @@ -146,6 +146,13 @@ public void restCall(String method, String resource, String json) throws Excepti
restCallInternal(method, resource, json, true);
}

@When("REST {string} call at {string} with JSON {string} in cross-site mode with origin {string}")
public void restCallCrossSite(String method, String resource, String json, String origin) throws Exception {
restCallInternal(method, resource, json, true,
com.google.common.net.HttpHeaders.ORIGIN, origin,
com.google.common.net.HttpHeaders.SEC_FETCH_SITE, "cross-site");
}

public void restCallInternal(String method, String resource, String json, boolean authenticateCall, String... additionalHeaders) throws Exception {
// Create an instance of HttpClient
HttpClient httpClient = HttpClient.newHttpClient();
Expand Down Expand Up @@ -210,10 +217,10 @@ else if (method.equals("GET")) {
}
}

@When("I try to authenticate with a cross-site call with origin {string}")
public void createCustomCrossSiteCall(String origin) throws Exception {
@When("I try to authenticate with a cross-site call with origin {string} using json {string}")
public void createCustomCrossSiteCall(String origin, String authJson) throws Exception {
restCallInternal("POST", "/v1/authentication/user",
"{\"password\": \"kapua-password\", \"username\": \"kapua-sys\"}", false,
authJson, false,
com.google.common.net.HttpHeaders.ORIGIN, origin,
com.google.common.net.HttpHeaders.SEC_FETCH_SITE, "cross-site");
}
Expand Down
Expand Up @@ -21,7 +21,7 @@ Feature: REST API tests for User
Given Init Jaxb Context
And Init Security Context
#NB: be aware that sub-sequent tests depends on the value of TTL that you set here
And start rest-API container and dependencies with auth token TTL "3000"ms and refresh token TTL "2000"ms
And start rest-API container and dependencies with auth token TTL "3000"ms and refresh token TTL "2000"ms and cors endpoint refresh interval 60s

Scenario: Simple login with username-pw works and I can call another API endpoint without errors
First, the authentication via login-pw is tested.
Expand Down
Expand Up @@ -16,35 +16,96 @@
#NB: this test depends on tests tagged as @endpoint

Feature: REST API tests for User
REST API test of Kapua User API.
REST API tests of Kapua CORS filter logic.

@setup
Scenario: Start event broker for all scenarios
Scenario: Initialize Jaxb and security context, then start rest-api container and dependencies
Given Init Jaxb Context
And Init Security Context
#NB: be aware that sub-sequent tests depends on the value of TTL that you set here
# And start rest-API container and dependencies with auth token TTL "10000"ms and refresh token TTL "20000"ms
#NB: be aware that sub-sequent tests depends on the value of cors endpoint refresh interval that you set here
And start rest-API container and dependencies with auth token TTL "10000000"ms and refresh token TTL "20000"ms and cors endpoint refresh interval 1s

Scenario: The auth from a "same-origin" call
Scenario: The auth from a "same-origin" call should not present, in the response headers fields, the values that represent a "success CORS filter auth. attempt"

Given Server with host "127.0.0.1" on port "8081"
Given I try to authenticate with a same-site call
Then I expect no "Access-Control-Allow-Origin" header in the response
Then I expect no "Access-Control-Allow-Credentials" header in the response
Then REST response code is 200
And REST response containing AccessToken
And I expect no "Access-Control-Allow-Origin" header in the response
And I expect no "Access-Control-Allow-Credentials" header in the response

Scenario: The success of an authentication attempt from a 'Cross-origin' request depends on the presence of the CORS endpoint used in the 'origin' header in the scope

Given Server with host "127.0.0.1" on port "8081"
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io"
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io" using json "{\"password\": \"kapua-password\", \"username\": \"kapua-sys\"}"
#auth is "formally" right (response code 200) but...
Then REST response code is 200
#...CORS headers are not present
Then I expect no "Access-Control-Allow-Origin" header in the response
Then I expect no "Access-Control-Allow-Credentials" header in the response
#now I insert the CORS endpoint, using directly services and not rest-API because here I want to test ONLY CORS logic and not other rest APIs. Also, this 'endpoint service' has been tested previously on @endpoint tests
Given I login as user with name "kapua-sys" and password "kapua-password"
When I create a CORS filter with schema "https", domain "api-sbx.everyware.io" and port 443
Then I wait 3 seconds
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io"
Then I wait 2 seconds
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io" using json "{\"password\": \"kapua-password\", \"username\": \"kapua-sys\"}"
Then REST response code is 200
Then I expect "Access-Control-Allow-Origin" header in the response with value "https://api-sbx.everyware.io"
Then I expect "Access-Control-Allow-Credentials" header in the response with value "true"
When I delete all CORS filters
Then I wait 3 seconds
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io"
Then I wait 2 seconds
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io" using json "{\"password\": \"kapua-password\", \"username\": \"kapua-sys\"}"
Then REST response code is 200
Then I expect no "Access-Control-Allow-Credentials" header in the response
Then I expect no "Access-Control-Allow-Origin" header in the response


Scenario: Trying to define CORS endpoints in child account and seeing if they mask the ones defined in the father

Given Server with host "127.0.0.1" on port "8081"
Given I login as user with name "kapua-sys" and password "kapua-password"
When I create a CORS filter with schema "https", domain "api-sbx.everyware.io" and port 443
Then I wait 2 seconds
Then I create an account with name "acc1", organization name "acc1" and email address "acc1@org.com"
And I configure user service
| type | name | value |
| boolean | infiniteChildEntities | true |
| integer | maxNumberChildEntities | 0 |
When A generic user
| name | displayName | email | phoneNumber | status | userType |
| user1 | Test User A | kapua_a@kapua.com | +386 31 323 444 | ENABLED | INTERNAL |
And I add credentials
| name | password | enabled |
| user1 | ToManySecrets123# | true |
And Add permissions to the last created user
| domain | action |
| endpoint_info | read |
| endpoint_info | write |
| user | read |
Then I logout
When REST POST call at "/v1/authentication/user" with JSON "{\"password\": \"ToManySecrets123#\", \"username\": \"user1\"}"
Then REST response code is 200
Then REST response containing AccessToken
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io" using json "{\"password\": \"ToManySecrets123#\", \"username\": \"user1\"}"
Then REST response code is 200
Then I expect "Access-Control-Allow-Origin" header in the response with value "https://api-sbx.everyware.io"
Then I expect "Access-Control-Allow-Credentials" header in the response with value "true"
#now I mask the parent account CORS endpoints creating a new one in this child account
Given I login as user with name "user1" and password "ToManySecrets123#"
When I create a CORS filter with schema "https", domain "api-sbx.asdsadas.io" and port 443
Then I wait 2 seconds
Given I try to authenticate with a cross-site call with origin "https://api-sbx.everyware.io" using json "{\"password\": \"ToManySecrets123#\", \"username\": \"user1\"}"
Then REST response code is 200
And REST response containing AccessToken
#Authentication has no defined scopeID in session so parent CORS is used in CORS filter matching...
And I expect "Access-Control-Allow-Origin" header in the response with value "https://api-sbx.everyware.io"
And I expect "Access-Control-Allow-Credentials" header in the response with value "true"
#...but for this call there is a scopeID in session (after auth) so there is masking of CORS endpoint
When REST "GET" call at "/v1/_/users?offset=0&limit=50" with JSON "" in cross-site mode with origin "https://api-sbx.everyware.io"
Then REST response code is 200
And I expect no "Access-Control-Allow-Origin" header in the response
And I expect no "Access-Control-Allow-Credentials" header in the response





0 comments on commit 798c5e2

Please sign in to comment.