diff --git a/pom.xml b/pom.xml index 6b51459a6..5cb46af2d 100644 --- a/pom.xml +++ b/pom.xml @@ -73,10 +73,21 @@ org.springframework.boot spring-boot-starter-thymeleaf + + + org.springframework + spring-messaging + + + org.springframework.boot spring-boot-starter-websocket + + org.springframework.security + spring-security-messaging + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/org/springframework/samples/petclinic/configuration/WebSecurityConfig.java b/src/main/java/org/springframework/samples/petclinic/configuration/WebSecurityConfig.java index 8b6af024d..660db990a 100644 --- a/src/main/java/org/springframework/samples/petclinic/configuration/WebSecurityConfig.java +++ b/src/main/java/org/springframework/samples/petclinic/configuration/WebSecurityConfig.java @@ -60,7 +60,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/login", "/logout", "/register","/confirm-account").permitAll() - .antMatchers("/websocket/**", "/topic/**", "/app/**").permitAll() + .antMatchers("/websocket/**", "/topic/**","/topic/public", "/app/**").permitAll() .antMatchers("/resources/**").permitAll() .antMatchers("/h2-console/**").permitAll() .antMatchers("/**").authenticated() diff --git a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java index 8d488690b..7d89077bf 100644 --- a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java +++ b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java @@ -3,9 +3,10 @@ package org.springframework.samples.petclinic.configuration; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry; +import org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; -import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; /** * Configuration class to enable WebSocket and STOMP messaging. @@ -14,8 +15,9 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo */ @Configuration @EnableWebSocketMessageBroker -public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { +public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { +/* @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/websocket").withSockJS(); @@ -27,4 +29,31 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { registry.setApplicationDestinationPrefixes("/app"); } +*/ + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + config.enableSimpleBroker("/topic"); + config.setApplicationDestinationPrefixes("/app"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/websocket") + .setAllowedOrigins("*") + .withSockJS(); + } + + @Override + protected void configureInbound(MessageSecurityMetadataSourceRegistry message) { + message + .nullDestMatcher().permitAll() + .simpDestMatchers("/app/**").permitAll() + .simpSubscribeDestMatchers("/topic/**").permitAll() + .anyMessage().denyAll(); + } + + @Override + protected boolean sameOriginDisabled() { + return true; + } } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java index cbc45e820..89fb16232 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/UserRepository.java @@ -27,10 +27,15 @@ public interface UserRepository extends Repository { /** * Save an {@link User} to the data store, either inserting or updating it. - * @param user the {@link User} to save + * @param user the {@link User} to delete + * @return the deleted {@link User} */ User save(User user); - void deleteById(Integer id); - + /** + * Delete an {@link User} to the data store. + * @param user the {@link User} to delete + * @return the deleted {@link User} + */ + User delete(User user); } diff --git a/src/main/resources/db/h2/data.sql b/src/main/resources/db/h2/data.sql index 56734e0f6..ee493f18e 100644 --- a/src/main/resources/db/h2/data.sql +++ b/src/main/resources/db/h2/data.sql @@ -67,6 +67,7 @@ INSERT INTO users_roles (user_id, role_id) VALUES (1,1),(1,2),(1,3), (2,3),(3,3); + INSERT INTO auth_providers (id, name) VALUES (1,'local'), (2,'google'), diff --git a/src/main/resources/db/h2/schema.sql b/src/main/resources/db/h2/schema.sql index 8aa68cc4f..84a8cffac 100644 --- a/src/main/resources/db/h2/schema.sql +++ b/src/main/resources/db/h2/schema.sql @@ -1,17 +1,7 @@ -DROP TABLE vet_specialties IF EXISTS; -DROP TABLE vets IF EXISTS; -DROP TABLE specialties IF EXISTS; -DROP TABLE visits IF EXISTS; -DROP TABLE pets IF EXISTS; -DROP TABLE types IF EXISTS; -DROP TABLE owners IF EXISTS; -DROP TABLE roles IF EXISTS; -DROP TABLE users IF EXISTS; -DROP TABLE users_email IF EXISTS; -DROP TABLE users_roles IF EXISTS; -DROP TABLE auth_providers IF EXISTS; -DROP TABLE credentials IF EXISTS; + + +DROP TABLE vets IF EXISTS; CREATE TABLE vets ( id INTEGER IDENTITY PRIMARY KEY, first_name VARCHAR(30), @@ -19,12 +9,14 @@ CREATE TABLE vets ( ); CREATE INDEX vets_last_name ON vets (last_name); +DROP TABLE specialties IF EXISTS; CREATE TABLE specialties ( id INTEGER IDENTITY PRIMARY KEY, name VARCHAR(80) ); CREATE INDEX specialties_name ON specialties (name); +DROP TABLE vet_specialties IF EXISTS; CREATE TABLE vet_specialties ( vet_id INTEGER NOT NULL, specialty_id INTEGER NOT NULL @@ -32,12 +24,14 @@ CREATE TABLE vet_specialties ( ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id); ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id); +DROP TABLE types IF EXISTS; CREATE TABLE types ( id INTEGER IDENTITY PRIMARY KEY, name VARCHAR(80) ); CREATE INDEX types_name ON types (name); +DROP TABLE owners IF EXISTS; CREATE TABLE owners ( id INTEGER IDENTITY PRIMARY KEY, first_name VARCHAR(30), @@ -48,6 +42,7 @@ CREATE TABLE owners ( ); CREATE INDEX owners_last_name ON owners (last_name); +DROP TABLE pets IF EXISTS; CREATE TABLE pets ( id INTEGER IDENTITY PRIMARY KEY, name VARCHAR(30), @@ -59,6 +54,7 @@ ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id); CREATE INDEX pets_name ON pets (name); +DROP TABLE visits IF EXISTS; CREATE TABLE visits ( id INTEGER IDENTITY PRIMARY KEY, pet_id INTEGER NOT NULL, @@ -68,12 +64,15 @@ CREATE TABLE visits ( ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id); CREATE INDEX visits_pet_id ON visits (pet_id); +DROP TABLE roles IF EXISTS; CREATE TABLE roles ( id INTEGER IDENTITY PRIMARY KEY, name VARCHAR(20) NOT NULL ); CREATE INDEX roles_name ON roles (name); + +DROP TABLE users IF EXISTS; CREATE TABLE users ( id INTEGER IDENTITY PRIMARY KEY, first_name VARCHAR(30) NOT NULL, @@ -94,7 +93,8 @@ CREATE TABLE users ( ); CREATE INDEX users_email ON users (email); -CREATE TABLE public.users_roles ( +DROP TABLE users_roles IF EXISTS; +CREATE TABLE users_roles ( user_id INTEGER NOT NULL, role_id INTEGER NOT NULL ); @@ -102,12 +102,14 @@ ALTER TABLE users_roles ADD CONSTRAINT fk_users_roles_user_id FOREIGN KEY (user_ ALTER TABLE users_roles ADD CONSTRAINT fk_users_roles_role_id FOREIGN KEY (role_id) REFERENCES roles (id); CREATE INDEX users_roles_user_id ON users_roles (user_id); +DROP TABLE auth_providers IF EXISTS; CREATE TABLE auth_providers ( id INTEGER IDENTITY PRIMARY KEY, name VARCHAR(20) NOT NULL ); CREATE INDEX auth_providers_name ON auth_providers (name); +DROP TABLE credentials IF EXISTS; CREATE TABLE credentials ( id INTEGER IDENTITY PRIMARY KEY, provider_id INTEGER NOT NULL, diff --git a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerIntegrationTest.java b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerIntegrationTest.java index 196f83524..556e5af29 100644 --- a/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerIntegrationTest.java +++ b/src/test/java/org/springframework/samples/petclinic/controller/OwnerControllerIntegrationTest.java @@ -31,6 +31,11 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +/** + * Test class for the {@link OwnerController} + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ @Slf4j @SpringBootTest @AutoConfigureMockMvc @@ -96,7 +101,7 @@ class OwnerControllerIntegrationTest { int ownerId = Integer.parseInt(Objects.requireNonNull(path).split("/")[2]); OwnerDTO found = ownerService.findById(ownerId); - assertThat(found).isEqualToIgnoringGivenFields(george, "id"); + assertThat(found).isEqualToIgnoringGivenFields(george, CommonAttribute.ID); } @Test diff --git a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTest.java b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTest.java index aa68db2b0..3e65fb980 100644 --- a/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTest.java +++ b/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTest.java @@ -16,10 +16,14 @@ package org.springframework.samples.petclinic.system; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.samples.petclinic.controller.WebSecurityConfig; +import org.springframework.samples.petclinic.service.common.UserDetailsServiceImpl; +import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -32,16 +36,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * Test class for {@link CrashController} * * @author Colin But + * @author Paul-Emmanuel DOS SANTOS FACAO */ // Waiting https://github.com/spring-projects/spring-boot/issues/5574 -@Disabled -@WebMvcTest(controllers = CrashController.class) +@SpringBootTest +@AutoConfigureMockMvc class CrashControllerTest { @Autowired private MockMvc mockMvc; + @MockBean + private UserDetailsServiceImpl userDetailsService; + @Test + @WithMockUser(value = WebSecurityConfig.TEST_USER) void testTriggerException() throws Exception { mockMvc.perform(get("/oups")).andExpect(view().name("exception")) .andExpect(model().attributeExists("exception")).andExpect(forwardedUrl("exception"))