diff --git a/todo-workspace/backend/compose.yaml b/todo-workspace/backend/compose.yaml index 3b26131c01a8bdf1b8180576cc0963c1f1ca8b0f..d5ba86cb2258f428c29b4edcb30815a5c9a76acb 100755 --- a/todo-workspace/backend/compose.yaml +++ b/todo-workspace/backend/compose.yaml @@ -1,9 +1,24 @@ services: postgres: image: 'postgres:latest' + container_name: 'todo-db' + restart: 'unless-stopped' + env_file: + - '.env' environment: - 'POSTGRES_DB=${POSTGRES_DB}' - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}' - 'POSTGRES_USER=${POSTGRES_USER}' ports: - - '5432' + - '5432:5432' + volumes: + - pgdata:/var/lib/postgresql/data + networks: + - todo-network + +networks: + todo-network: + driver: bridge +volumes: + pgdata: + driver: local diff --git a/todo-workspace/backend/pom.xml b/todo-workspace/backend/pom.xml index b44a92e58cdf521f5ef7d65f0e0955aa05ee50c7..3d09d2ecd8ce3e8816a019bf0aa658bf8ddcea27 100755 --- a/todo-workspace/backend/pom.xml +++ b/todo-workspace/backend/pom.xml @@ -78,6 +78,21 @@ <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>junit-jupiter</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-testcontainers</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>postgresql</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/todo-workspace/backend/src/main/java/com/hepia/backend/TodoApplication.java b/todo-workspace/backend/src/main/java/com/hepia/backend/TodoApplication.java index be190c0b84eb9ad4b17ece41501d6165745e579f..ef48489e3e027d7c50cb6493cf9d991a6f4a7586 100755 --- a/todo-workspace/backend/src/main/java/com/hepia/backend/TodoApplication.java +++ b/todo-workspace/backend/src/main/java/com/hepia/backend/TodoApplication.java @@ -5,9 +5,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TodoApplication { - + // https://medium.com/@faroukymedia/de-la-th%C3%A9orie-%C3%A0-la-pratique-spring-boot-architecture-hexagonale-et-ddd-pour-des-applications-f1110d83bced public static void main(String[] args) { SpringApplication.run(TodoApplication.class, args); } - } diff --git a/todo-workspace/backend/src/main/java/com/hepia/backend/config/BeanConfig.java b/todo-workspace/backend/src/main/java/com/hepia/backend/config/BeanConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..fe0281adca199be60e282d33fefb9c230b17392c --- /dev/null +++ b/todo-workspace/backend/src/main/java/com/hepia/backend/config/BeanConfig.java @@ -0,0 +1,32 @@ +package com.hepia.backend.config; + +import org.springframework.web.filter.CorsFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; +import java.util.Collections; + +import static org.springframework.http.HttpHeaders.*; + +@Configuration +public class BeanConfig { + @Bean + public CorsFilter corsFilter() { + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + final CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.setAllowedOrigins(Collections.singletonList("http://localhost:4200")); + config.setAllowedHeaders(Arrays.asList( + ORIGIN, + CONTENT_TYPE, + ACCEPT, + AUTHORIZATION + )); + config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } +} diff --git a/todo-workspace/backend/src/main/java/com/hepia/backend/config/SecurityConfig.java b/todo-workspace/backend/src/main/java/com/hepia/backend/config/SecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..60bae092ef90fb7f72cc502736d8617c98b7d840 --- /dev/null +++ b/todo-workspace/backend/src/main/java/com/hepia/backend/config/SecurityConfig.java @@ -0,0 +1,37 @@ +package com.hepia.backend.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; + +import static org.springframework.security.config.Customizer.withDefaults; +import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity(securedEnabled = true) +public class SecurityConfig { + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .cors(withDefaults()) + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(req -> + req.requestMatchers( + "/todos/**" + ).permitAll() + .anyRequest() + .authenticated() + ) + .sessionManagement(s -> + s.sessionCreationPolicy(STATELESS) + ); + return http.build(); + } +} diff --git a/todo-workspace/backend/src/main/java/com/hepia/backend/controller/TodoController.java b/todo-workspace/backend/src/main/java/com/hepia/backend/controller/TodoController.java new file mode 100644 index 0000000000000000000000000000000000000000..88d8bea68a44e3db44e3fe591f5ebf75f2613fad --- /dev/null +++ b/todo-workspace/backend/src/main/java/com/hepia/backend/controller/TodoController.java @@ -0,0 +1,17 @@ +package com.hepia.backend.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/todos") +@RequiredArgsConstructor +public class TodoController { + + @GetMapping + public String getTodos() { + return "Hello World!"; + } +} diff --git a/todo-workspace/backend/src/main/java/com/hepia/backend/domain/entity/TodoEntity.java b/todo-workspace/backend/src/main/java/com/hepia/backend/domain/entity/TodoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..c56c0c5dad6cd8429650464e577652f05754b4aa --- /dev/null +++ b/todo-workspace/backend/src/main/java/com/hepia/backend/domain/entity/TodoEntity.java @@ -0,0 +1,20 @@ +package com.hepia.backend.domain.entity; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "todos") +public class TodoEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private boolean completed; + private String createdAt; +} diff --git a/todo-workspace/backend/src/main/java/com/hepia/backend/domain/model/Todo.java b/todo-workspace/backend/src/main/java/com/hepia/backend/domain/model/Todo.java new file mode 100644 index 0000000000000000000000000000000000000000..473b54ca3b6b974dabd5687959f798408374fb2b --- /dev/null +++ b/todo-workspace/backend/src/main/java/com/hepia/backend/domain/model/Todo.java @@ -0,0 +1,17 @@ +package com.hepia.backend.domain.model; + +import lombok.*; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Todo { + private Long id; + private String name; + private boolean completed; + private LocalDateTime createdAt; +} diff --git a/todo-workspace/backend/src/main/resources/application.properties b/todo-workspace/backend/src/main/resources/application.properties deleted file mode 100755 index 3e6d0dcfb8997b9ef849ed227ee25b3c626d1d50..0000000000000000000000000000000000000000 --- a/todo-workspace/backend/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=todo diff --git a/todo-workspace/backend/src/main/resources/application.yml b/todo-workspace/backend/src/main/resources/application.yml new file mode 100755 index 0000000000000000000000000000000000000000..d024d92bbb15bf189df0b0ee945c00cc441423f7 --- /dev/null +++ b/todo-workspace/backend/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + datasource: + url: ${SPRING_DATASOURCE_URL} + username: ${SPRING_DATASOURCE_USER} + password: ${SPRING_DATASOURCE_PASSWORD} + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: update + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.PostgreSQLDialect + show-sql: true + database: postgresql + database-platform: org.hibernate.dialect.PostgreSQLDialect +server: + servlet: + context-path: /api/v1 + port: 8080