Skip to content
Snippets Groups Projects
Verified Commit 9128d2ff authored by Ira ¯\_(ツ)_/¯'s avatar Ira ¯\_(ツ)_/¯
Browse files

Fix formatting and linting (google style checks)

parent 5b939d79
No related branches found
No related tags found
No related merge requests found
Showing with 203 additions and 145 deletions
package org.archlinux.keycloak.mailpass.rest;
import static io.restassured.RestAssured.given;
import static org.junit.Assert.assertEquals;
import com.palantir.docker.compose.DockerComposeRule;
import com.palantir.docker.compose.connection.waiting.HealthChecks;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import static io.restassured.RestAssured.given;
import static org.junit.Assert.assertEquals;
import java.text.MessageFormat;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
public class MailPassResourceIntegrationTest {
private final static String ROOT_URI = "http://localhost:{0,number,#}/auth/realms/master/mailpass/roleauth";
private final static String TOKEN_GEN_URI = "http://localhost:{0,number,#}/auth/realms/master/protocol/openid-connect/token";
private static final String ROOT_URI =
"http://localhost:{0,number,#}/auth/realms/master/mailpass/roleauth";
private static final String TOKEN_GEN_URI =
"http://localhost:{0,number,#}/auth/realms/master/protocol/openid-connect/token";
private static String adminToken;
private static int port;
@ClassRule
public static DockerComposeRule docker = DockerComposeRule.builder()
.file("src/integrationTest/resources/docker-compose.yml").waitingForService("keycloak", HealthChecks
.toRespondOverHttp(8080, (port) -> port.inFormat("http://$HOST:$EXTERNAL_PORT/auth/realms/master")))
.build();
public static DockerComposeRule docker =
DockerComposeRule.builder()
.file("src/integrationTest/resources/docker-compose.yml")
.waitingForService(
"keycloak",
HealthChecks.toRespondOverHttp(
8080, (port) -> port.inFormat("http://$HOST:$EXTERNAL_PORT/auth/realms/master")))
.build();
/** Generate bearer token and make it available to all the tests in the class. */
@BeforeClass
public static void setup() {
port = docker.containers().container("keycloak").port(8080).getExternalPort();
Response response = given().accept(ContentType.JSON).contentType(ContentType.URLENC)
.body("grant_type=password&username=admin&password=admin&client_id=admin-cli")
.post(MessageFormat.format(TOKEN_GEN_URI, port));
Response response =
given()
.accept(ContentType.JSON)
.contentType(ContentType.URLENC)
.body("grant_type=password&username=admin&password=admin&client_id=admin-cli")
.post(MessageFormat.format(TOKEN_GEN_URI, port));
adminToken = response.jsonPath().getString("access_token");
}
@Test
public void testNonAuthenticatedAccessReturnsUnauthorized401() {
Response response = given().contentType(ContentType.JSON).body("{ \"password\": \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
Response response =
given()
.contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
assertEquals(401, response.getStatusCode());
}
@Test
public void testAuthenticatedAccessReturnsCreated200() {
Response response = given().header("Authorization", "Bearer " + adminToken).contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
Response response =
given()
.header("Authorization", "Bearer " + adminToken)
.contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
assertEquals(201, response.getStatusCode());
}
@Test
public void testMalformedJsonRaisesBadRequestException400() {
Response response = given().header("Authorization", "Bearer " + adminToken).contentType(ContentType.JSON)
.body("{ \"password\"x \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
Response response =
given()
.header("Authorization", "Bearer " + adminToken)
.contentType(ContentType.JSON)
.body("{ \"password\"x \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
assertEquals(400, response.getStatusCode());
}
@Test
public void testMalformedJsonExceptionMessage() {
Response response = given().header("Authorization", "Bearer " + adminToken).contentType(ContentType.JSON)
.body("{ \"password\"x \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
Response response =
given()
.header("Authorization", "Bearer " + adminToken)
.contentType(ContentType.JSON)
.body("{ \"password\"x \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
String error = response.jsonPath().getString("error");
......@@ -75,21 +98,28 @@ public class MailPassResourceIntegrationTest {
@Test
public void testMissingJsonObjectRaisesBadRequestException400() {
Response response = given().header("Authorization", "Bearer " + adminToken).contentType(ContentType.JSON)
.body("{ \"missing_password\": \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
Response response =
given()
.header("Authorization", "Bearer " + adminToken)
.contentType(ContentType.JSON)
.body("{ \"missing_password\": \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
assertEquals(400, response.getStatusCode());
}
@Test
public void testMissingJsonObjectExceptionMessage() {
Response response = given().header("Authorization", "Bearer " + adminToken).contentType(ContentType.JSON)
.body("{ \"missing_password\": \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
Response response =
given()
.header("Authorization", "Bearer " + adminToken)
.contentType(ContentType.JSON)
.body("{ \"missing_password\": \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
String error = response.jsonPath().getString("error");
assertEquals("password object not detected in provided JSON body", error);
}
}
package org.archlinux.keycloak.mailpass.rest;
import static io.restassured.RestAssured.given;
import static org.junit.Assert.assertEquals;
import com.palantir.docker.compose.DockerComposeRule;
import com.palantir.docker.compose.connection.waiting.HealthChecks;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import static io.restassured.RestAssured.given;
import static org.junit.Assert.assertEquals;
import java.text.MessageFormat;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
public class MailPassRestResourceIntegrationTest {
private final static String ROOT_URI = "http://localhost:{0,number,#}/auth/realms/master/mailpass/roleauth";
private final static String ALT_URI = "http://localhost:{0,number,#}/auth/realms/develop/mailpass/roleauth";
private final static String TOKEN_GEN_URI = "http://localhost:{0,number,#}/auth/realms/master/protocol/openid-connect/token";
private static String testToken;
private static int port;
@ClassRule
public static DockerComposeRule docker = DockerComposeRule.builder()
.file("src/integrationTest/resources/docker-compose.yml")
.waitingForService("keycloak", HealthChecks.toRespondOverHttp(8080,
(port) -> port.inFormat("http://$HOST:$EXTERNAL_PORT/auth/realms/master")))
.build();
@BeforeClass
public static void setup() {
port = docker.containers().container("keycloak").port(8080).getExternalPort();
Response response = given().accept(ContentType.JSON).contentType(ContentType.URLENC)
.body("grant_type=password&username=test&password=test&client_id=admin-cli")
.post(MessageFormat.format(TOKEN_GEN_URI, port));
testToken = response.jsonPath().getString("access_token");
}
@Test
public void testInvalidRoleReturnsForbidden403() {
Response response = given().header("Authorization", "Bearer " + testToken).contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
assertEquals(403, response.getStatusCode());
}
@Test
public void testInvalidRoleMessage() {
Response response = given().header("Authorization", "Bearer " + testToken).contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }").when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
String error = response.jsonPath().getString("error");
assertEquals("Does not have realm admin role", error);
}
@Test
public void testInvalidRealmReturnsForbidden403() {
Response response = given().header("Authorization", "Bearer " + testToken).contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }").when()
.post(MessageFormat.format(ALT_URI, port) + "/compute-password-hash");
assertEquals(403, response.getStatusCode());
}
@Test
public void testInvalidRealmMessage() {
Response response = given().header("Authorization", "Bearer " + testToken).contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }").when()
.post(MessageFormat.format(ALT_URI, port) + "/compute-password-hash");
String error = response.jsonPath().getString("error");
assertEquals("Operation not allowed on this realm", error);
}
private static final String ROOT_URI =
"http://localhost:{0,number,#}/auth/realms/master/mailpass/roleauth";
private static final String ALT_URI =
"http://localhost:{0,number,#}/auth/realms/develop/mailpass/roleauth";
private static final String TOKEN_GEN_URI =
"http://localhost:{0,number,#}/auth/realms/master/protocol/openid-connect/token";
private static String testToken;
private static int port;
@ClassRule
public static DockerComposeRule docker =
DockerComposeRule.builder()
.file("src/integrationTest/resources/docker-compose.yml")
.waitingForService(
"keycloak",
HealthChecks.toRespondOverHttp(
8080, (port) -> port.inFormat("http://$HOST:$EXTERNAL_PORT/auth/realms/master")))
.build();
/** Generate bearer token and make it available to all the tests in the class. */
@BeforeClass
public static void setup() {
port = docker.containers().container("keycloak").port(8080).getExternalPort();
Response response =
given()
.accept(ContentType.JSON)
.contentType(ContentType.URLENC)
.body("grant_type=password&username=test&password=test&client_id=admin-cli")
.post(MessageFormat.format(TOKEN_GEN_URI, port));
testToken = response.jsonPath().getString("access_token");
}
@Test
public void testInvalidRoleReturnsForbidden403() {
Response response =
given()
.header("Authorization", "Bearer " + testToken)
.contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
assertEquals(403, response.getStatusCode());
}
@Test
public void testInvalidRoleMessage() {
Response response =
given()
.header("Authorization", "Bearer " + testToken)
.contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }")
.when()
.post(MessageFormat.format(ROOT_URI, port) + "/compute-password-hash");
String error = response.jsonPath().getString("error");
assertEquals("Does not have realm admin role", error);
}
@Test
public void testInvalidRealmReturnsForbidden403() {
Response response =
given()
.header("Authorization", "Bearer " + testToken)
.contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }")
.when()
.post(MessageFormat.format(ALT_URI, port) + "/compute-password-hash");
assertEquals(403, response.getStatusCode());
}
@Test
public void testInvalidRealmMessage() {
Response response =
given()
.header("Authorization", "Bearer " + testToken)
.contentType(ContentType.JSON)
.body("{ \"password\": \"password\" }")
.when()
.post(MessageFormat.format(ALT_URI, port) + "/compute-password-hash");
String error = response.jsonPath().getString("error");
assertEquals("Operation not allowed on this realm", error);
}
}
package org.archlinux.keycloak.mailpass.rest;
import io.restassured.path.json.JsonPath;
import io.restassured.path.json.exception.JsonPathException;
import java.security.SecureRandom;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
......@@ -9,20 +10,15 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.bouncycastle.crypto.generators.OpenBSDBCrypt;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.models.KeycloakSession;
import io.restassured.path.json.JsonPath;
import io.restassured.path.json.exception.JsonPathException;
/**
* A custom REST endpoint to trigger functionality on the Keycloak server, which
* is not available through the default set of built-in Keycloak REST endpoints.
* This is to be used during the storage of a custom attribute on the Account
* Management Console for the mail password. The data stored will be a Bcrypt
* hash instead of the plain text password.
* A custom REST endpoint to trigger functionality on the Keycloak server, which is not available
* through the default set of built-in Keycloak REST endpoints. This is to be used during the
* storage of a custom attribute on the Account Management Console for the mail password. The data
* stored will be a Bcrypt hash instead of the plain text password.
*/
public class MailPassResource {
......@@ -77,5 +73,4 @@ public class MailPassResource {
throw new BadRequestException("provided data is not in valid JSON format");
}
}
}
......@@ -4,9 +4,8 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.services.resource.RealmResourceProvider;
/**
* A provider of a custom REST resource for a path relative to Realm's RESTful
* API that cannot be resolved by the Keycloak server. This implementation is a
* requirement for custom REST endpoints.
* A provider of a custom REST resource for a path relative to Realm's RESTful API that cannot be
* resolved by the Keycloak server. This implementation is a requirement for custom REST endpoints.
*/
public class MailPassResourceProvider implements RealmResourceProvider {
......@@ -14,6 +13,13 @@ public class MailPassResourceProvider implements RealmResourceProvider {
private String realmName;
private String realmRole;
/**
* Store the pre-configured SPI fields to enable verification before requests take place.
*
* @param session The Keycloak session.
* @param realmName The Keycloak realm under which requests are allowed.
* @param realmRole The role required to submit requests.
*/
public MailPassResourceProvider(KeycloakSession session, String realmName, String realmRole) {
this.session = session;
this.realmName = realmName;
......@@ -26,7 +32,5 @@ public class MailPassResourceProvider implements RealmResourceProvider {
}
@Override
public void close() {
}
public void close() {}
}
......@@ -7,9 +7,8 @@ import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resource.RealmResourceProviderFactory;
/**
* A factory that extends RealmResourceProviderFactory instance to create the
* custom mail pass resource provider. This implementation is a requirement for
* custom REST endpoints.
* A factory that extends RealmResourceProviderFactory instance to create the custom mail pass
* resource provider. This implementation is a requirement for custom REST endpoints.
*/
public class MailPassResourceProviderFactory implements RealmResourceProviderFactory {
......@@ -38,11 +37,8 @@ public class MailPassResourceProviderFactory implements RealmResourceProviderFac
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
public void postInit(KeycloakSessionFactory factory) {}
@Override
public void close() {
}
public void close() {}
}
......@@ -8,11 +8,10 @@ import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager;
/**
* A custom REST resource in the form of a domain extension which makes the
* custom endpoint accessible just for authenticated users. The REST request
* must be authenticated with bearer access token of an authenticated user and
* the user must be part of a pre-configured realm role in order to access the
* resource.
* A custom REST resource in the form of a domain extension which makes the custom endpoint
* accessible just for authenticated users. The REST request must be authenticated with bearer
* access token of an authenticated user and the user must be part of a pre-configured realm role in
* order to access the resource.
*/
public class MailPassRestResource {
......@@ -21,6 +20,13 @@ public class MailPassRestResource {
private final String realmRole;
private final AuthenticationManager.AuthResult auth;
/**
* Store the pre-configured SPI fields to enable verification before requests take place.
*
* @param session The Keycloak session.
* @param realmName The Keycloak realm under which requests are allowed.
* @param realmRole The role required to submit requests.
*/
public MailPassRestResource(KeycloakSession session, String realmName, String realmRole) {
this.session = session;
this.auth = new AppAuthManager.BearerTokenAuthenticator(session).authenticate();
......@@ -28,6 +34,11 @@ public class MailPassRestResource {
this.realmRole = realmRole;
}
/**
* Ensure the realm and role match the SPI configuration before enabling mailpass requests.
*
* @return MailPassResource instance after successful verification.
*/
@Path("roleauth")
public MailPassResource getMailPassResourceAuthenticated() {
checkRealm();
......@@ -45,9 +56,9 @@ public class MailPassRestResource {
private void checkRealmAdmin() {
if (auth == null) {
throw new NotAuthorizedException("Bearer");
} else if (auth.getToken().getRealmAccess() == null || !auth.getToken().getRealmAccess().isUserInRole(realmRole)) {
} else if (auth.getToken().getRealmAccess() == null
|| !auth.getToken().getRealmAccess().isUserInRole(realmRole)) {
throw new ForbiddenException("Does not have realm admin role");
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment