Skip to content

Commit

Permalink
Fix OpenAPI test failure and extend test coverage for security schemes
Browse files Browse the repository at this point in the history
With quarkusio/quarkus#31671 expected behavior of Smallrye OpenAPI has changed (torwards the specification) in regards to expected security scheme for basic authentication. We can't expect any value for 'basic' auth in Spring Data module now, therefore I added additional tests to Keycloak extended modules so that we have tested scenarios when security scheme is not empty.
  • Loading branch information
michalvavrik committed Mar 14, 2023
1 parent fdce469 commit d3012a6
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.FileReader;
Expand Down Expand Up @@ -77,5 +79,38 @@ private void assertContent(JsonObject content) {
"Expected component.schema.Score object.");
assertTrue(content.getJsonObject("paths").containsKey("/rest-ping"), "Missing expected path: /rest-ping");
assertTrue(content.getJsonObject("paths").containsKey("/rest-pong"), "Missing expected path: /rest-pong");

// verify that path /secured/admin is only accessible by user with role 'admin'
var expectedRole = getRequiredRoleForPath(content, "/secured/admin");
assertEquals("admin", expectedRole);

// verify that path /secured/getClaimsFromBeans is accessible by any authenticated user
expectedRole = getRequiredRoleForPath(content, "/secured/getClaimsFromBeans");
// note: '**' is equivalent of @Authenticated and @RolesAllowed("**")
assertEquals("**", expectedRole);

// verify 'oidc' security schema
var securitySchema = content
.getJsonObject("components")
.getJsonObject("securitySchemes")
.getJsonObject("SecurityScheme");
var actual = securitySchema.getString("type");
assertEquals("openIdConnect", actual);
actual = securitySchema.getString("description");
assertEquals("Authentication", actual);
actual = securitySchema.getString("openIdConnectUrl");
assertNotNull(actual);
assertTrue(actual.endsWith("/auth/realms/test-realm/.well-known/openid-configuration"));
}

private static String getRequiredRoleForPath(JsonObject content, String path) {
return content
.getJsonObject("paths")
.getJsonObject(path)
.getJsonObject("get")
.getJsonArray("security")
.getJsonObject(0)
.getJsonArray("SecurityScheme")
.getString(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.FileReader;
Expand Down Expand Up @@ -77,5 +79,38 @@ private void assertContent(JsonObject content) {
"Expected component.schema.Score object.");
assertTrue(content.getJsonObject("paths").containsKey("/rest-ping"), "Missing expected path: /rest-ping");
assertTrue(content.getJsonObject("paths").containsKey("/rest-pong"), "Missing expected path: /rest-pong");

// verify that path /secured/admin is only accessible by user with role 'admin'
var expectedRole = getRequiredRoleForPath(content, "/secured/admin");
assertEquals("admin", expectedRole);

// verify that path /secured/getClaimsFromBeans is accessible by any authenticated user
expectedRole = getRequiredRoleForPath(content, "/secured/getClaimsFromBeans");
// note: '**' is equivalent of @Authenticated and @RolesAllowed("**")
assertEquals("**", expectedRole);

// verify 'oidc' security schema
var securitySchema = content
.getJsonObject("components")
.getJsonObject("securitySchemes")
.getJsonObject("SecurityScheme");
var actual = securitySchema.getString("type");
assertEquals("openIdConnect", actual);
actual = securitySchema.getString("description");
assertEquals("Authentication", actual);
actual = securitySchema.getString("openIdConnectUrl");
assertNotNull(actual);
assertTrue(actual.endsWith("/auth/realms/test-realm/.well-known/openid-configuration"));
}

private static String getRequiredRoleForPath(JsonObject content, String path) {
return content
.getJsonObject("paths")
.getJsonObject(path)
.getJsonObject("get")
.getJsonArray("security")
.getJsonObject(0)
.getJsonArray("SecurityScheme")
.getString(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ void rolesAllowedResourceAuthPermitted() {
assertNotNull(json.getString("paths.\"/article-jpa/{id}\".get"));

json.setRootPath("");
assertEquals("admin", json.getString("paths.\"/secured/deny-all/{id}\".get.security[0].SecurityScheme[0]"));
assertEquals("admin", json.getString("paths./secured/roles-allowed.get.security[0].SecurityScheme[0]"));
assertEquals("admin", json.getString("paths.\"/secured/roles-allowed/{id}\".get.security[0].SecurityScheme[0]"));

// TODO: https://github.com/quarkusio/quarkus/issues/30997
// assertEquals("user", json.getString("paths.\"/secured/roles-allowed/{id}\".delete.security[0].SecurityScheme[0]"));
// OpenAPI should generate per-scope security requirements only for OAuth2
// more info: https://github.com/OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#patterned-fields-3
assertEquals(null, json.getString("paths.\"/secured/deny-all/{id}\".get.security[0].SecurityScheme[0]"));
assertEquals(null, json.getString("paths./secured/roles-allowed.get.security[0].SecurityScheme[0]"));
assertEquals(null, json.getString("paths.\"/secured/roles-allowed/{id}\".get.security[0].SecurityScheme[0]"));
assertEquals(null, json.getString("paths.\"/secured/roles-allowed/{id}\".delete.security[0].SecurityScheme[0]"));

List<String> list = json.getList("components.schemas.Article.required");
assertEquals(2, list.size());
Expand Down

0 comments on commit d3012a6

Please sign in to comment.