diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml
index 9d8b789..0603cf9 100644
--- a/.github/workflows/continuous-delivery.yml
+++ b/.github/workflows/continuous-delivery.yml
@@ -13,14 +13,6 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2
- - name: Modify application.yml
- run: |
- sed -i "s|^ *active:.*| active: default|" src/main/resources/application.yml
- sed -i "s|^ *url:.*| url: ${{ secrets.DATASOURCE_URL }}|" src/main/resources/application.yml
- sed -i "s|^ *username:.*| username: ${{ secrets.DATASOURCE_USERNAME }}|" src/main/resources/application.yml
- sed -i "s|^ *password:.*| password: ${{ secrets.DATASOURCE_PASSWORD }}|" src/main/resources/application.yml
- cat src/main/resources/application.yml
-
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
@@ -28,7 +20,14 @@ jobs:
java-version: '17'
- name: Build with Maven
- run: mvn clean install
+ env:
+ PGHOST: ${{ secrets.PGHOST }}
+ PGPORT: ${{ secrets.PGPORT }}
+ PGDATABASE: ${{ secrets.PGDATABASE }}
+ PGUSER: ${{ secrets.PGUSER }}
+ PGPASSWORD: ${{ secrets.PGPASSWORD }}
+ ISSUER_URI: ${{ secrets.ISSUER_URI }}
+ run: mvn clean install -Dspring.profiles.active=prd
- name: Build Docker image
run: |
@@ -49,7 +48,6 @@ jobs:
PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
HOST_NAME: ${{ secrets.EC2_HOST }}
USER_NAME: ${{ secrets.EC2_USERNAME }}
-
run: |
echo "$PRIVATE_KEY" > private_key && chmod 600 private_key
ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOST_NAME} '
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 5dbac9d..62d6f7a 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -9,6 +9,8 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+ env:
+ ISSUER_URI: https://test-issuer-uri
steps:
- name: Checkout project
uses: actions/checkout@v3
@@ -20,4 +22,4 @@ jobs:
java-version: '17'
- name: Build & Test
- run: mvn clean install
\ No newline at end of file
+ run: mvn clean install -Dspring.profiles.active=dev
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b4d0f17..709cb69 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,22 +19,35 @@
org.springframework.boot
- spring-boot-starter-data-jpa
+ spring-boot-starter
org.springframework.boot
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-resource-server
+
org.springframework.boot
spring-boot-starter-validation
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
org.springframework.boot
spring-boot-devtools
runtime
true
+
org.postgresql
postgresql
@@ -50,10 +63,7 @@
springdoc-openapi-starter-webmvc-ui
2.3.0
-
- org.apache.commons
- commons-lang3
-
+
org.springframework.boot
spring-boot-starter-test
@@ -64,6 +74,11 @@
h2
test
+
+ org.springframework.security
+ spring-security-test
+ test
+
@@ -82,5 +97,4 @@
-
\ No newline at end of file
diff --git a/src/main/java/com/gilberto/logistockapi/config/SecurityConfig.java b/src/main/java/com/gilberto/logistockapi/config/SecurityConfig.java
new file mode 100644
index 0000000..272177d
--- /dev/null
+++ b/src/main/java/com/gilberto/logistockapi/config/SecurityConfig.java
@@ -0,0 +1,27 @@
+package com.gilberto.logistockapi.config;
+
+import com.gilberto.logistockapi.security.JwtConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+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.web.SecurityFilterChain;
+
+@Configuration
+@EnableWebSecurity
+@EnableMethodSecurity
+public class SecurityConfig {
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
+ return httpSecurity
+ .csrf(AbstractHttpConfigurer::disable)
+ .oauth2ResourceServer(oauth2 ->
+ oauth2.jwt(jwt ->
+ jwt.jwtAuthenticationConverter(new JwtConverter())
+ )
+ )
+ .build();
+ }
+}
diff --git a/src/main/java/com/gilberto/logistockapi/config/WebConfig.java b/src/main/java/com/gilberto/logistockapi/config/WebConfig.java
new file mode 100644
index 0000000..76aad98
--- /dev/null
+++ b/src/main/java/com/gilberto/logistockapi/config/WebConfig.java
@@ -0,0 +1,18 @@
+package com.gilberto.logistockapi.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("http://localhost:5173")
+ .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
+ .allowedHeaders("*");
+ }
+}
+
diff --git a/src/main/java/com/gilberto/logistockapi/controllers/ProductController.java b/src/main/java/com/gilberto/logistockapi/controllers/ProductController.java
index ab27a57..c30854f 100644
--- a/src/main/java/com/gilberto/logistockapi/controllers/ProductController.java
+++ b/src/main/java/com/gilberto/logistockapi/controllers/ProductController.java
@@ -1,9 +1,6 @@
package com.gilberto.logistockapi.controllers;
-import com.gilberto.logistockapi.exceptions.ProductAlreadyRegisteredException;
-import com.gilberto.logistockapi.exceptions.ProductNotFoundException;
-import com.gilberto.logistockapi.exceptions.ProductStockExceededException;
-import com.gilberto.logistockapi.exceptions.ProductStockUnderThanZeroException;
+import com.gilberto.logistockapi.models.dto.SummaryProduct;
import com.gilberto.logistockapi.models.dto.request.ProductFilter;
import com.gilberto.logistockapi.models.dto.request.ProductForm;
import com.gilberto.logistockapi.models.dto.request.ProductUpdateForm;
@@ -11,11 +8,13 @@
import com.gilberto.logistockapi.models.dto.response.ProductDTO;
import com.gilberto.logistockapi.services.IProductService;
import jakarta.validation.Valid;
+
import java.net.URI;
-import java.util.List;
+
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
+import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
@@ -24,76 +23,70 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RestController
-@RequestMapping("/api/v1/product")
+@RequestMapping("/api/v1/products")
public class ProductController {
-
- private final IProductService productService;
-
- public ProductController(@Autowired IProductService productService) {
- this.productService = productService;
- }
-
- @PostMapping
- @ResponseStatus(HttpStatus.CREATED)
- public ResponseEntity create(@RequestBody @Valid ProductForm productForm)
- throws ProductAlreadyRegisteredException {
- return ResponseEntity.created(URI.create(""))
- .body(this.productService.create(productForm));
- }
-
- @GetMapping
- @ResponseStatus(HttpStatus.OK)
- public ResponseEntity> listAll(@Valid ProductFilter filter) {
- return ResponseEntity.ok(this.productService.listAll(filter));
- }
-
- @GetMapping("/{id}")
- @ResponseStatus(HttpStatus.OK)
- public ResponseEntity findById(@PathVariable Long id)
- throws ProductNotFoundException {
- return ResponseEntity.ok(this.productService.findById(id));
- }
-
- @GetMapping("/barcode/{barcode}")
- @ResponseStatus(HttpStatus.OK)
- public ResponseEntity findByBarCode(@PathVariable String barcode)
- throws ProductNotFoundException {
- return ResponseEntity.ok(this.productService.findByBarCode(barcode));
- }
-
- @PutMapping("/{id}")
- @ResponseStatus(HttpStatus.OK)
- public ResponseEntity updateById(@PathVariable Long id,
- @RequestBody @Valid ProductUpdateForm updateForm)
- throws ProductNotFoundException {
- return ResponseEntity.ok(this.productService.updateById(id, updateForm));
- }
-
- @DeleteMapping("/{id}")
- @ResponseStatus(HttpStatus.NO_CONTENT)
- public ResponseEntity