Skip to content

Commit

Permalink
Security JPA Reactive - fix non-unique ex
Browse files Browse the repository at this point in the history
(cherry picked from commit 08c152d)
  • Loading branch information
michalvavrik authored and gsmet committed May 31, 2023
1 parent c716678 commit 98e81ec
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,60 @@
package io.quarkus.security.jpa.reactive;

import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import io.restassured.response.ValidatableResponse;

public class PanacheEntitiesConfigurationTest extends JpaSecurityRealmTest {

private static final String DUPLICATE_USERNAME = "merlin";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(testClasses)
.addClass(PanacheUserEntity.class)
.addClass(PanacheRoleEntity.class)
.addClass(UserResource.class)
.addAsResource("multiple-entities/import.sql", "import.sql")
.addAsResource("multiple-entities/application.properties", "application.properties"));

@Test
void duplicateUsernameTest() {
// duplicate username must lead to 401
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();

// no user -> unauthenticated
getUsername().statusCode(401);
createUser();
// one user
getUsername().statusCode(200).body(is(DUPLICATE_USERNAME));
createUser();
// two users -> NonUniqueResultException -> 401
getUsername().statusCode(401);
}

private static void createUser() {
RestAssured
.given()
.auth().preemptive().basic("user", "user")
.body(DUPLICATE_USERNAME)
.post("/jaxrs-secured/user")
.then()
.statusCode(201);
}

private static ValidatableResponse getUsername() {
return RestAssured
.given()
.auth().preemptive().basic(DUPLICATE_USERNAME, DUPLICATE_USERNAME)
.body(DUPLICATE_USERNAME)
.get("/jaxrs-secured/user")
.then();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.quarkus.security.jpa.reactive;

import static java.util.Objects.requireNonNull;

import java.util.List;

import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext;

import io.quarkus.hibernate.reactive.panache.common.WithTransaction;
import io.smallrye.mutiny.Uni;

@RolesAllowed("user")
@Path("/user")
public class UserResource {

@WithTransaction
@POST
public Uni<Response> createUser(String username) {
if (username == null || username.isBlank()) {
throw new IllegalStateException("Invalid username");
}

// create new user with role 'user' and do not validate whether username is unique
return PanacheRoleEntity
.<PanacheRoleEntity> find("role", "user")
.singleResult()
.flatMap(userRole -> {
PanacheUserEntity user = new PanacheUserEntity();
user.name = username;
user.pass = username;
user.roles = List.of(userRole);
return user.persist();
})
.map(user -> Response.created(null).build());
}

@GET
public Uni<String> getUsername(@Context SecurityContext sec) {
var principal = requireNonNull(sec.getUserPrincipal());
return Uni.createFrom().item(principal.getName());
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
INSERT INTO test_user (id, username, password) VALUES (1, 'admin', 'admin');
INSERT INTO test_user (id, username, password) VALUES (2, 'user','user');
INSERT INTO test_user (id, username, password) VALUES (3, 'noRoleUser','noRoleUser');
INSERT INTO test_user (id, username, password) VALUES (-1, 'admin', 'admin');
INSERT INTO test_user (id, username, password) VALUES (-2, 'user','user');
INSERT INTO test_user (id, username, password) VALUES (-3, 'noRoleUser','noRoleUser');

INSERT INTO test_role (id, role_name) VALUES (1, 'admin');
INSERT INTO test_role (id, role_name) VALUES (2, 'user');

INSERT INTO test_user_role (user_id, role_id) VALUES (1, 1);
INSERT INTO test_user_role (user_id, role_id) VALUES (2, 2);
INSERT INTO test_user_role (user_id, role_id) VALUES (-1, 1);
INSERT INTO test_user_role (user_id, role_id) VALUES (-2, 2);
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.function.Predicate;

import jakarta.inject.Inject;
import jakarta.persistence.NonUniqueResultException;

import org.hibernate.FlushMode;
import org.hibernate.NonUniqueResultException;
import org.hibernate.reactive.mutiny.Mutiny;
import org.jboss.logging.Logger;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.function.Predicate;

import jakarta.inject.Inject;
import jakarta.persistence.NonUniqueResultException;

import org.hibernate.FlushMode;
import org.hibernate.NonUniqueResultException;
import org.hibernate.reactive.mutiny.Mutiny;
import org.jboss.logging.Logger;

Expand Down

0 comments on commit 98e81ec

Please sign in to comment.