Initial commit

parents
Pipeline #1834 canceled with stages
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
\ No newline at end of file
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
FROM openjdk:21
EXPOSE 9090
ADD target/docker-demo-app-two.jar docker-demo-app-two.jar
ENTRYPOINT ["java", "-jar", "/docker-demo-app-two.jar"]
\ No newline at end of file
This diff is collapsed.
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.2.0
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.treinaweb</groupId>
<artifactId>twjobs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>twjobs</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<modelmapper.version>3.0.0</modelmapper.version>
<jjwt.version>0.12.5</jjwt.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.treinaweb</groupId>
<artifactId>twjobs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>twjobs</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<modelmapper.version>3.0.0</modelmapper.version>
<jjwt.version>0.12.5</jjwt.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<finalName>docker-demo-app-two</finalName>
</build>
</project>
POST {{baseUrl}}/api/auth/register
Content-Type: application/json
{
"name": "AVMakers",
"email": "contato@avmakers.com.br",
"password": "senha@123",
"role": "COMPANY"
}
###
POST {{baseUrl}}/api/auth/login
Content-Type: application/json
{
"email": "contato@treinaweb.com.br",
"password": "senha@123"
}
###
POST {{baseUrl}}/api/auth/refresh
Content-Type: application/json
{
"refreshToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjbGV5c29uQG1haWwuY29tIiwiaWF0IjoxNzA4NjU3NDQ2LCJleHAiOjE3MDg2NjEwNDZ9.SlJsXW12JHobn-O7JcUKl7O840ddJrp0769sIN94W2hISWwPjJmHNhpj5NxkH3prKkLlVpW3egu5zELIYfcNlA"
}
GET {{baseUrl}}/api/jobs
###
GET {{baseUrl}}/api/jobs/1
###
POST {{baseUrl}}/api/jobs
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjb250YXRvQGF2bWFrZXJzLmNvbS5iciIsImlhdCI6MTcwODY2MjM1NSwiZXhwIjoxNzA4NjY1OTU1fQ.CJ84nx92_MDuaRiZhW3cic2rqlcz247SISbB-AcakFO5T2kYVM5tU50K8u8TER3td7Y-lcH-16_W9i7kg_kwog
{
"title": "Desenvolvedor Java e Spring",
"description": "Vaga para um desenvolvedor Java e Spring",
"location": "São Paulo",
"level": "MID_LEVEL",
"salary": 7500,
"type": "FULL_TIME",
"skills": [1, 2]
}
###
PUT {{baseUrl}}/api/jobs/1
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjb250YXRvQGF2bWFrZXJzLmNvbS5iciIsImlhdCI6MTcwODY2MjM1NSwiZXhwIjoxNzA4NjY1OTU1fQ.CJ84nx92_MDuaRiZhW3cic2rqlcz247SISbB-AcakFO5T2kYVM5tU50K8u8TER3td7Y-lcH-16_W9i7kg_kwog
{
"title": "Desenvolvedor Back-end Java",
"description": "Vaga para um desenvolvedor que saiba Java e Spring",
"company": "TreinaWeb",
"location": "São Paulo",
"type": "FULL_TIME",
"level": "SENIOR",
"salary": 15000.00,
"skills": [
1,
2,
10
]
}
###
DELETE {{baseUrl}}/api/jobs/3
###
GET {{baseUrl}}/api/jobs/2/skills
###
POST {{baseUrl}}/api/jobs/1/apply
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjbGV5c29uQG1haWwuY29tIiwiaWF0IjoxNzA4NjYyNTgwLCJleHAiOjE3MDg2NjYxODB9.pcB13nFkuUy5lc_rqm8xhfTdP97oknWBhBestwiuMbEUp4diI9QNTeFMW2sHzJM4Hzu3K8IeUhoGNVgPXwk6SQ
GET {{baseUrl}}/api/skills
###
GET {{baseUrl}}/api/skills/1
###
POST {{baseUrl}}/api/skills
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjb250YXRvQHRyZWluYXdlYi5jb20uYnIiLCJpYXQiOjE3MDg2NTg4MjgsImV4cCI6MTcwODY2MjQyOH0.iVEqX-fwsl4scLLHNNFLh-m_QQhW-yhOIZ9Z-F_pac1Ohe8CUNSqcpyYOUK_qZ_HDc22W8YHacHcUk8RZqMpXA
{
"name": "Spring"
}
###
PUT {{baseUrl}}/api/skills/1
Content-Type: application/json
{
"name": "Java"
}
###
DELETE {{baseUrl}}/api/skills/11
\ No newline at end of file
package br.com.treinaweb.twjobs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
public class TwjobsApplication {
public static void main(String[] args) {
SpringApplication.run(TwjobsApplication.class, args);
}
}
package br.com.treinaweb.twjobs.api;
import br.com.treinaweb.twjobs.core.service.StatisticsService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RequiredArgsConstructor
@RestController
@RequestMapping("/statistics")
public class StatisticsRestController {
private final StatisticsService statisticsService;
@GetMapping("/all")
public ResponseEntity<Map<String, Object>> getAllStatistics() {
return ResponseEntity.ok(statisticsService.getStatistics());
}
}
package br.com.treinaweb.twjobs.api;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/users")
public class UsersRestController {
public final UserRepository userRepository;
// @GetMapping("statistics/count")
// @TWJobsPermissions.IsCompany
// public Long howMany() {
// return userRepository.countAllUsers();
// }
}
package br.com.treinaweb.twjobs.api.accepts.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.accepts.controllers.AcceptRestController;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class AcceptAssembler implements SimpleRepresentationModelAssembler<AcceptResponse> {
@Override
public void addLinks(EntityModel<AcceptResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(AcceptRestController.class).findById(id))
.withSelfRel()
.withType("GET");
Link updateLink = null;
try {
updateLink = linkTo(methodOn(AcceptRestController.class).update(null,id, null))
.withRel("update")
.withType("PUT");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
var deleteLink = linkTo(methodOn(AcceptRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(
selfLink,
updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<AcceptResponse>> resources) {
var selfLink = linkTo(methodOn(AcceptRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
Link createLink = null;
try {
createLink = linkTo(methodOn(AcceptRestController.class).create(null, null))
.withRel("create")
.withType("POST");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.accepts.dtos;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AcceptRequest {
// NOT EMPTY SÒ COM STRING
// COM NUMEROS È O NOTNULL
// AJEITAR
// @VesselImoIsUnique
@NotNull(message = "IMO não pode ser nulo")
// @Size(min = 7, message = "IMO deve ter no mínimo 7 caracteres")
private Long imo;
//CAN BE NULL
private String obs;
private String status;
private String restricoes;
//CAN BE NULL
private List<Berco> bercos;
// ~~~ PODE SER NULO
private List<Long> bercosId;
// @NotEmpty(message = "data não deve estar vazia")
// private String dataAccept;
// @NotEmpty(message = "data não deve estar vazia")
// private String data_create;
// @NotEmpty(message = "data não deve estar vazia")
// private String data_update;
// Dados navio
private String mmsi;
private String nome;
@NotNull(message = "LOA deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float loa;
private Float boca;
@NotNull(message = "DWT deve ser maior que zero")
// @Size(value=1 , message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
@NotEmpty
@Size(min = 1, max = 100, message = "CATEGORIA deve ter no mínimo 1 e no máximo 100 caracteres")
private String categoria;
private Integer flag;
@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_entrada;
@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_saida;
}
package br.com.treinaweb.twjobs.api.accepts.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import br.com.treinaweb.twjobs.core.enums.CategoriaVessel;
import br.com.treinaweb.twjobs.core.models.Berco;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class AcceptResponse {
private Long id;
private String user;
private String vessel;
private Long imo;
private String status;
private String obs;
private String restricoes;
private String dataAccept;
private String data_create;
private String data_update;
private String time_accept;
private String time_create;
private String time_update;
private List<Berco> bercos;
private String path;
// Dados navio
private String mmsi;
private String nome;
private Float loa;
private Float boca;
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
private String categoria;
private Integer flag;
private Float calado_entrada;
private Float calado_saida;
// private List<Long> bercos;
//private List<BercoRequestAceite> bercos;
}
package br.com.treinaweb.twjobs.api.accepts.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Aceite;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
public interface AcceptMapper {
//
Accept toAccept(AcceptRequest acceptRequest);
AcceptResponse toAcceptResponse(Accept accept);
//
}
package br.com.treinaweb.twjobs.api.accepts.mappers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Aceite;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperAcceptMapper implements AcceptMapper {
private final ModelMapper modelMapper;
@Override
public AcceptResponse toAcceptResponse(Accept accept) {
return modelMapper.map(accept, AcceptResponse.class);
}
@Override
public Accept toAccept(@Valid AcceptRequest acceptRequest) {
return modelMapper.map(acceptRequest, Accept.class);
}
}
package br.com.treinaweb.twjobs.api.aceites.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.aceites.controllers.AceiteRestController;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class AceiteAssembler implements SimpleRepresentationModelAssembler<AceiteResponse> {
@Override
public void addLinks(EntityModel<AceiteResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(AceiteRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(AceiteRestController.class).update(null, id))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(AceiteRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(selfLink, updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<AceiteResponse>> resources) {
var selfLink = linkTo(methodOn(AceiteRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(AceiteRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.aceites.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.aceites.assemblers.AceiteAssembler;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteRequest;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import br.com.treinaweb.twjobs.api.aceites.mappers.AceiteMapper;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.core.exceptions.AceiteNotFoundException;
import br.com.treinaweb.twjobs.core.models.Aceite;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.AceiteRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/aceites")
public class AceiteRestController {
private final AceiteMapper aceiteMapper;
private final AceiteAssembler aceiteAssembler;
private final AceiteRepository aceiteRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<AceiteResponse> pagedResourcesAssembler;
private final VesselRepository vesselRepository;
@GetMapping
public CollectionModel<EntityModel<AceiteResponse>> findAll(Pageable pageable) {
var aceites = aceiteRepository.findAll(pageable)
.map(aceiteMapper::toAceiteResponse);
return pagedResourcesAssembler.toModel(aceites, aceiteAssembler);
}
@GetMapping("/{id}")
public EntityModel<AceiteResponse> findById(@PathVariable Long id) {
var aceite = aceiteRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
var aceiteResponse = aceiteMapper.toAceiteResponse(aceite);
return aceiteAssembler.toModel(aceiteResponse);
}
private final ModelMapper modelMapper;
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<AceiteResponse> create(@RequestBody @Valid AceiteRequest aceiteRequest) {
var aceite = aceiteMapper.toAceite(aceiteRequest);
aceite.setUser(securityService.getCurrentUser());
var navio = vesselRepository.findByImo(aceite.getImo());
// aceite.setImo((long) 9470820);
// var navio = vesselRepository.existsByImo(aceite.getImo());
//var navio="Peróla Brazil";
// aceite.setVessel(modelMapper.map(navio, Vessel.class));
Vessel existingCustomer = navio.get();
//String nameWeWanted = existingCustomer.getName();
aceite.setVessel(existingCustomer);
aceite = aceiteRepository.save(aceite);
var aceiteResponse = aceiteMapper.toAceiteResponse(aceite);
return aceiteAssembler.toModel(aceiteResponse);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsOwner
public EntityModel<AceiteResponse> update(
@RequestBody @Valid AceiteRequest aceiteRequest,
@PathVariable Long id
) {
var aceite = aceiteRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
var aceiteData = aceiteMapper.toAceite(aceiteRequest);
BeanUtils.copyProperties(aceiteData, aceite, "id", "company", "candidates");
aceite = aceiteRepository.save(aceite);
var aceiteResponse = aceiteMapper.toAceiteResponse(aceite);
return aceiteAssembler.toModel(aceiteResponse);
}
@DeleteMapping("/{id}")
@TWJobsPermissions.IsOwner
public ResponseEntity<?> delete(@PathVariable Long id) {
var aceite = aceiteRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
aceiteRepository.delete(aceite);
return ResponseEntity.noContent().build();
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.aceites.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AceiteRequest {
private Long user;
private Long vessel;
// @NotEmpty
private Long imo;
// @NotEmpty
private AceiteStatus status;
}
package br.com.treinaweb.twjobs.api.aceites.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class AceiteResponse {
private Long id;
private String user;
private String vessel;
private Long imo;
private AceiteStatus status;
}
package br.com.treinaweb.twjobs.api.aceites.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteRequest;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.core.models.Aceite;
import jakarta.validation.Valid;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
public interface AceiteMapper {
//
AceiteResponse toAceiteResponse(Aceite aceite);
Aceite toAceite(AceiteRequest aceiteRequest);
//
}
package br.com.treinaweb.twjobs.api.aceites.mappers;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteRequest;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.core.models.Aceite;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperAceiteMapper implements AceiteMapper {
private final ModelMapper modelMapper;
@Override
public AceiteResponse toAceiteResponse(Aceite aceite) {
return modelMapper.map(aceite, AceiteResponse.class);
}
@Override
public Aceite toAceite(@Valid AceiteRequest aceiteRequest) {
return modelMapper.map(aceiteRequest, Aceite.class);
}
}
package br.com.treinaweb.twjobs.api.auth.controllers;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
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;
import br.com.treinaweb.twjobs.api.auth.dtos.LoginRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.RefreshRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.TokenResponse;
import br.com.treinaweb.twjobs.api.auth.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.UserResponse;
import br.com.treinaweb.twjobs.api.auth.mappers.UserMapper;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import br.com.treinaweb.twjobs.core.services.jwt.JwtService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/auth")
public class AuthRestController {
private final UserMapper userMapper;
private final JwtService jwtService;
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final AuthenticationManager authenticationManager;
@PostMapping("/register")
@ResponseStatus(code = HttpStatus.CREATED)
public UserResponse register(@RequestBody @Valid UserRequest userRequest) {
var user = userMapper.toUser(userRequest);
var passwordHash = passwordEncoder.encode(user.getPassword());
user.setPassword(passwordHash);
user = userRepository.save(user);
return userMapper.toUserResponse(user);
}
@PostMapping("/login")
public TokenResponse login(@RequestBody @Valid LoginRequest loginRequest) {
var user = userRepository.findByEmail(loginRequest.getEmail());
var usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
loginRequest.getEmail(),
loginRequest.getPassword()
);
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
return TokenResponse.builder()
.accessToken(jwtService.generateAccessToken(loginRequest.getEmail(), user.get().getRole()))
.refreshToken(jwtService.generateRefreshToken(loginRequest.getEmail(), user.get().getRole()))
.build();
}
@PostMapping("/refresh")
public TokenResponse refresh(@RequestBody @Valid RefreshRequest refreshRequest) {
var sub = jwtService.getSubFromRefreshToken(refreshRequest.getRefreshToken());
var user = userRepository.findByEmail(sub);
return TokenResponse.builder()
.accessToken(jwtService.generateAccessToken(sub, user.get().getRole()))
.refreshToken(jwtService.generateRefreshToken(sub, user.get().getRole()))
.build();
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.auth.cors;
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 CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "DELETE", "PUT");
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.auth.dtos;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LoginRequest {
@Email
@NotEmpty
private String email;
@NotEmpty
private String password;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RefreshRequest {
@NotEmpty
private String refreshToken;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TokenResponse {
private String accessToken;
private String refreshToken;
// private String roleReturn;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserRequest {
@NotEmpty
private String name;
@Email
@NotEmpty
private String email;
@NotEmpty
private String password;
@NotNull
private Role role;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String name;
private String email;
private Role role;
}
package br.com.treinaweb.twjobs.api.auth.mappers;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.auth.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class ModelMapperUserMapper implements UserMapper {
private final ModelMapper modelMapper;
@Override
public UserResponse toUserResponse(User user) {
return modelMapper.map(user, UserResponse.class);
}
@Override
public User toUser(UserRequest userRequest) {
return modelMapper.map(userRequest, User.class);
}
}
package br.com.treinaweb.twjobs.api.auth.mappers;
import br.com.treinaweb.twjobs.api.auth.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
public interface UserMapper {
UserResponse toUserResponse(User user);
User toUser(UserRequest userRequest);
}
package br.com.treinaweb.twjobs.api.bercos.assemblers;
import br.com.treinaweb.twjobs.api.bercos.controllers.BercosRestController;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class BercosAssembler implements SimpleRepresentationModelAssembler<BercoResponse> {
@Override
public void addLinks(EntityModel<BercoResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(BercosRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(BercosRestController.class).update(null, id))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(BercosRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(selfLink, updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<BercoResponse>> resources) {
var selfLink = linkTo(methodOn(BercosRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(BercosRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.bercos.controllers;
import br.com.treinaweb.twjobs.api.bercos.assemblers.BercosAssembler;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoRequest;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import br.com.treinaweb.twjobs.api.bercos.mappers.BercoMapper;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.AceiteNotFoundException;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.exceptions.BercoNotFoundException;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.BercoCustomRepository;
import br.com.treinaweb.twjobs.core.repositories.BercoRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.services.CadastroVesselService;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//@CrossOrigin
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/bercos")
public class BercosRestController {
private final BercosAssembler bercoAssembler;
private final BercoMapper bercoMapper;
private final CadastroVesselService cadastroVesselService;
private final BercoRepository bercoRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<BercoResponse> pagedResourcesAssembler;
private final VesselRepository vesselRepository;
private final BercoCustomRepository bercoCustomRepository;
@GetMapping
public CollectionModel<EntityModel<BercoResponse>> findAll(Pageable pageable) {
var bercos = bercoRepository.findAll(pageable)
.map(bercoMapper::toBercoResponse);
return pagedResourcesAssembler.toModel(bercos, bercoAssembler);
}
@GetMapping("/{id}")
public EntityModel<BercoResponse> findById(@PathVariable Long id) {
var berco = bercoRepository.findById(id)
.orElseThrow(BercoNotFoundException::new);
var bercoResponse = bercoMapper.toBercoResponse(berco);
return bercoAssembler.toModel(bercoResponse);
}
@GetMapping("/custom")
public List<BercoResponse> custom(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "categoria", required = false) String categoria, @RequestParam(value = "nome", required = false) String nome){
List<BercoResponse> bercos = bercoCustomRepository.bercosCustom(id, categoria, nome)
.stream()
.map(bercoMapper::toBercoResponse)
.toList();
return bercos;
}
// @GetMapping("statistics/count")
// @TWJobsPermissions.IsCompany
// public Long howManyAccepts() {
// return bercoRepository.countAllBercos();
// }
@ResponseStatus(HttpStatus.CREATED)
@TWJobsPermissions.IsCompany
@PostMapping
public EntityModel<BercoResponse> create(@Valid @RequestBody BercoRequest bercoRequest) {
var berco = bercoMapper.toBerco(bercoRequest);
berco = bercoRepository.save(berco);
List<Vessel> navios = vesselRepository.findAll();
for(Vessel i : navios){
i.setSt_ver_vessel(VeriStatus.valueOf("N"));
}
var bercoResponse = bercoMapper.toBercoResponse(berco);
return bercoAssembler.toModel(bercoResponse);
}
@PutMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public EntityModel<BercoResponse> update(
@RequestBody @Valid BercoRequest bercoRequest,
@PathVariable Long id
) {
var berco = bercoRepository.findById(id)
.orElseThrow(BercoNotFoundException::new);
var bercoData = bercoMapper.toBerco(bercoRequest);
BeanUtils.copyProperties(bercoData, berco, "id", "company", "candidates");
berco = bercoRepository.save(berco);
List<Vessel> navios = vesselRepository.findAll();
for(Vessel i : navios){
i.setSt_ver_vessel(VeriStatus.valueOf("N"));
}
var bercoResponse = bercoMapper.toBercoResponse(berco);
return bercoAssembler.toModel(bercoResponse);
}
@DeleteMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var berco = bercoRepository.findById(id)
.orElseThrow(BercoNotFoundException::new);
bercoRepository.delete(berco);
List<Vessel> navios = vesselRepository.findAll();
for(Vessel i : navios){
i.setSt_ver_vessel(VeriStatus.valueOf("N"));
}
return ResponseEntity.noContent().build();
}
// Continuar colocando os métodos e substituindo por vessels.
// Depois corrigir os objetos que talvez ainda não existam
// Testar o cadastro de um vessel pra ver se guarda o user_id
}
package br.com.treinaweb.twjobs.api.bercos.dtos;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BercoRequest {
// AJEITAR
// private Long user;
//not empty não está funcionando. Ajeiter.
// @NotEmpty
private String nome;
private Long compri_estrutural;
private Long compri_util;
private Float dwt;
private Long largura;
private Long profundidade;
private Float calado_max;
private Float boca_max;
private Float loa_max;
private String categoria;
// private List<Long> accepts; //Novo request que não possua essa linha.
private List<Accept> accepts;
}
package br.com.treinaweb.twjobs.api.bercos.dtos;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Berco;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class BercoResponse {
private Long id;
private String nome;
private Long compri_estrutural;
private Long compri_util;
private Float dwt;
private Long largura;
private Long profundidade;
private Float calado_max;
private Float boca_max;
private Float loa_max;
private String categoria;
private List<String> accepts;
}
package br.com.treinaweb.twjobs.api.bercos.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoRequest;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.models.Vessel;
public interface BercoMapper {
Berco toBerco(BercoRequest bercoRequest);
BercoResponse toBercoResponse(Berco berco);
}
package br.com.treinaweb.twjobs.api.bercos.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoRequest;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.models.Vessel;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperBercoMapper implements BercoMapper {
private final ModelMapper modelMapper;
@Override
public Berco toBerco(BercoRequest bercoRequest) {
return modelMapper.map(bercoRequest, Berco.class);
}
@Override
public BercoResponse toBercoResponse(Berco berco) {
return modelMapper.map(berco, BercoResponse.class);
}
}
package br.com.treinaweb.twjobs.api.blackList.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.blackList.controllers.BlackListRestController;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class BlackListAssembler implements SimpleRepresentationModelAssembler<BlackListResponse> {
@Override
public void addLinks(EntityModel<BlackListResponse> resource) {
var id = resource.getContent().getId();
// var selfLink = linkTo(methodOn(AcceptRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
// var updateLink = linkTo(methodOn(BlackListRestController.class).update(null, id))
// .withRel("update")
// .withType("PUT");
//
// var deleteLink = linkTo(methodOn(BlackListRestController.class).delete(id))
// .withRel("delete")
// .withType("DELETE");
resource.add(
// selfLink,
// updateLink
// ,
// deleteLink
);
}
@Override
public void addLinks(CollectionModel<EntityModel<BlackListResponse>> resources) {
var selfLink = linkTo(methodOn(BlackListRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(BlackListRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.blackList.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.blackList.assemblers.BlackListAssembler;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListRequest;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import br.com.treinaweb.twjobs.api.blackList.mappers.BlackListMapper;
import br.com.treinaweb.twjobs.core.enums.Role;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.AcceptNotFoundException;
import br.com.treinaweb.twjobs.core.exceptions.BlackListedNotFoundException;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.AcceptRepository;
import br.com.treinaweb.twjobs.core.repositories.BlackListCustomRepository;
import br.com.treinaweb.twjobs.core.repositories.BlackListRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.service.CadastroAcceptService;
import br.com.treinaweb.twjobs.core.service.EmailService;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
//"""
// Importante, quando eu tenho certeza que o dado existe, não usar findById: https://www.baeldung.com/spring-data-findbyid-vs-getbyid
// """
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/black-list")
public class BlackListRestController {
private final BlackListMapper blackListMapper;
private final BlackListAssembler blackListAssembler;
private final BlackListRepository blackListRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<BlackListResponse> pagedResourcesAssembler;
private final CadastroAcceptService cadastroAcceptService;
private final BlackListCustomRepository blackListCustomRepository;
private final VesselRepository vesselRepository;
//"@PageableDefault(value = 7)" tamanho local para o tamanho da paginação. Deve ser igual ou menor ao valor encontrado no "application.properties"
@GetMapping
@TWJobsPermissions.IsCompany
public CollectionModel<EntityModel<BlackListResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
User user = securityService.getCurrentUser();
Long userId = user.getId();
// org.springframework.data.domain.Page<BlackListResponse> blackLists = null;
// if (user.getRole().equals(Role.COMPANY)) {
// throw new NegocioException("É company");
var blackLists = blackListRepository.findAll(pageable)
.map(blackListMapper::toBlackListResponse);
return pagedResourcesAssembler.toModel(blackLists, blackListAssembler);
// } else if (user.getRole().equals(Role.CANDIDATE)) {
//// throw new NegocioException("É candidate");
//
// blackLists = blackListRepository.findAllByUserId(pageable, userId)
// .map(blackListMapper::toBlackListResponse);
// pagedResourcesAssembler.toModel(blackLists, blackListAssembler);
//
// }
// Page<AcceptResponse>
// accepts = acceptRepository.findAllByUserId(pageable,userId)
// .map(acceptMapper::toAcceptResponse);
//
//
// return null;
// return pagedResourcesAssembler.toModel(blackLists, blackListAssembler);
}
@GetMapping("/statistics/count")
@TWJobsPermissions.IsCompany
public Long howMany() {
return blackListRepository.countAllBlackLists();
}
@GetMapping("/custom")
@TWJobsPermissions.IsCompany
public List<BlackListResponse> findTest(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "imo", required = false) String imo, @RequestParam(value = "data_create", required = false) String data_create, @RequestParam(value = "time_create", required = false) String time_create) {
List<BlackListResponse> blackListeds = blackListCustomRepository.blackListedsCustom(id, imo, data_create, time_create)
.stream()
.map(blackListMapper::toBlackListResponse)
.toList();
return blackListeds;
}
@Autowired
private EmailService emailService;
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<BlackListResponse> create(@RequestBody @Valid BlackListRequest blackListRequest) {
var blackList = blackListMapper.toBlackList(blackListRequest);
var vessel = vesselRepository.findByImo(blackList.getImo());
// """Setando as datas de alteração"""
blackList.setData_blacklisted(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setData_create(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setData_update(String.valueOf(LocalDate.now()));
blackList.setTime_blacklisted(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setTime_create(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setTime_update(String.valueOf(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
// blackList.setMmsi(vessel.get().getMmsi());
// blackList.setNome(vessel.get().getNome());
// blackList.setLoa(vessel.get().getLoa());
// blackList.setBoca(vessel.get().getBoca());
// blackList.setDwt(vessel.get().getDwt());
// blackList.setPontal(vessel.get().getPontal());
// blackList.setPonte_mfold(vessel.get().getPonte_mfold());
// blackList.setMfold_quilha(vessel.get().getMfold_quilha());
// if(vessel.get().getCategoria() != null) {
// blackList.setCategoria(vessel.get().getCategoria());
// } else {
// blackList.setCategoria("nao informado");
// }
//
// blackList.setFlag(Integer.valueOf(vessel.get().getFlag()));
// blackList.setCalado_entrada(vessel.get().getCalado_entrada());
// blackList.setCalado_saida(vessel.get().getCalado_saida());
blackList = blackListRepository.save(blackList);
var vesselResponse = blackListMapper.toBlackListResponse(blackList);
return blackListAssembler.toModel(vesselResponse);
}
@PutMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public EntityModel<BlackListResponse> update(
@RequestBody @Valid BlackListRequest blackListRequest,
@PathVariable Long id
) {
var blackList = blackListRepository.findById(id)
.orElseThrow(BlackListedNotFoundException::new);
var BlackListData = blackListMapper.toBlackList(blackListRequest);
BlackListData.setData_update(String.valueOf(LocalDate.now()));
BlackListData.setTime_update(String.valueOf(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
BeanUtils.copyProperties(BlackListData, blackList, "id", "imo", "data_blacklisted","data_create","time_blacklisted","time_create");
blackList = blackListRepository.save(blackList);
var acceptResponse = blackListMapper.toBlackListResponse(blackList);
return blackListAssembler.toModel(acceptResponse);
}
//
// @TWJobsPermissions.IsOwner
@DeleteMapping("/{id}")
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var blackList = blackListRepository.findById(id)
.orElseThrow(BlackListedNotFoundException::new);
/*check_user(accept);*/
blackListRepository.delete(blackList);
return ResponseEntity.noContent().build();
}
//
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.blackList.dtos;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BlackListRequest {
// AJEITAR
// @VesselImoIsUnique
@NotNull(message = "IMO deve ter no mínimo 7 caracteres")
// @Size(min = 7, message = "IMO deve ter no mínimo 7 caracteres")
private Long imo;
@NotEmpty(message = "MOTIVO não deve estar vazio.")
private String reason;
// private String data_blacklisted;
// private String data_create;
// private String data_update;
//
// private String time_blacklisted;
// private String time_create;
// private String time_update;
// Dados navio
private String mmsi="Null";
private String nome="Null";
// @NotNull(message = "LOA deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float loa=0.0F;
private Float boca=0.0F;
// @NotNull(message = "DWT deve ser maior que zero")
// @Size(value=1 , message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float dwt=0.0F;
private Float pontal=0.0F;
private Float ponte_mfold=0.0F;
private Float mfold_quilha=0.0F;
// @NotEmpty
// @Size(min = 1, max = 100, message = "CATEGORIA deve ter no mínimo 1 e no máximo 100 caracteres")
private String categoria="Null";
private Integer flag=0;
//@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_entrada=0.0F;
//@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_saida=0.0F;
}
package br.com.treinaweb.twjobs.api.blackList.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class BlackListResponse {
private Long id;
private Long imo;
private String reason;
private String data_blacklisted;
private String data_create;
private String data_update;
private String time_blacklisted;
private String time_create;
private String time_update;
// private List<Long> bercos;
//private List<BercoRequestAceite> bercos;
// Dados navio
private String mmsi;
private String nome;
private Float loa;
private Float boca;
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
private String categoria;
private Integer flag;
private Float calado_entrada;
private Float calado_saida;
}
package br.com.treinaweb.twjobs.api.blackList.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListRequest;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
public interface BlackListMapper {
//
BlackList toBlackList(BlackListRequest blackListRequest);
BlackListResponse toBlackListResponse(BlackList blackList);
//
}
package br.com.treinaweb.twjobs.api.blackList.mappers;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListRequest;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperBlackListMapper implements BlackListMapper {
private final ModelMapper modelMapper;
@Override
public BlackListResponse toBlackListResponse(BlackList blackList) {
return modelMapper.map(blackList, BlackListResponse.class);
}
@Override
public BlackList toBlackList(@Valid BlackListRequest blackListRequest) {
return modelMapper.map(blackListRequest, BlackList.class);
}
}
package br.com.treinaweb.twjobs.api.common.dtos;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {
private String message;
@Builder.Default
private LocalDateTime timestamp = LocalDateTime.now();
}
package br.com.treinaweb.twjobs.api.common.dtos;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ValidationErrorResponse {
private String message;
@Builder.Default
private LocalDateTime timestamp = LocalDateTime.now();
private Map<String, List<String>> errors;
}
package br.com.treinaweb.twjobs.api.common.filters;
import java.io.IOException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import br.com.treinaweb.twjobs.core.exceptions.JwtServiceException;
import br.com.treinaweb.twjobs.core.services.jwt.JwtService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class AccessTokenRequestFilter extends OncePerRequestFilter {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String TOKEN_PREFIX = "Bearer ";
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
try {
var token = "";
var email = "";
var header = request.getHeader(AUTHORIZATION_HEADER);
if (isTokenPresent(header)) {
token = header.substring(TOKEN_PREFIX.length());
email = jwtService.getSubFromAccessToken(token);
}
if (isEmailValid(email)) {
setAuthentication(request, email);
}
filterChain.doFilter(request, response);
} catch (JwtServiceException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getLocalizedMessage());
}
}
private void setAuthentication(HttpServletRequest request, String email) {
var userDetails = userDetailsService.loadUserByUsername(email);
var authentication = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
private boolean isEmailValid(String email) {
return email != null && !email.isEmpty();
}
private boolean isTokenPresent(String header) {
return header != null && header.startsWith(TOKEN_PREFIX);
}
}
package br.com.treinaweb.twjobs.api.common.handlers;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import br.com.treinaweb.twjobs.api.common.dtos.ErrorResponse;
import br.com.treinaweb.twjobs.api.common.dtos.ValidationErrorResponse;
import br.com.treinaweb.twjobs.core.exceptions.JwtServiceException;
import br.com.treinaweb.twjobs.core.exceptions.ModelNotFoundException;
@RestControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(ModelNotFoundException.class)
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public ErrorResponse handleModelNotFoundException(
ModelNotFoundException exception
) {
return ErrorResponse.builder()
.message(exception.getLocalizedMessage())
.build();
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public ValidationErrorResponse handleMethodArgumentNotValidException(
MethodArgumentNotValidException exception
) {
var errors = exception.getBindingResult().getFieldErrors()
.stream()
.collect(Collectors.groupingBy(
fieldError -> fieldError.getField(),
Collectors.mapping(
fieldError -> fieldError.getDefaultMessage(),
Collectors.toList()
)
));
return ValidationErrorResponse.builder()
.message("Validation error")
.errors(errors)
.build();
}
@ExceptionHandler(JwtServiceException.class)
@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
public ErrorResponse handleJwtServiceException(JwtServiceException e) {
return ErrorResponse.builder()
.message(e.getLocalizedMessage())
.build();
}
}
package br.com.treinaweb.twjobs.api.common.handlers;
import java.io.IOException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class TokenAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException
) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getLocalizedMessage());
}
}
package br.com.treinaweb.twjobs.api.common.handlers;
import java.io.IOException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class TokenAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException
) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getLocalizedMessage());
}
}
package br.com.treinaweb.twjobs.api.emailSend;
import br.com.treinaweb.twjobs.core.enums.EmailActivation;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.EmailSend;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.EmailSendRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/emailSend")
public class EmailSendRestController {
private final EmailSendRepository emailSendRepository;
private final SecurityService securityService;
// COLOCAR DEPOIS COMO DEFAULT - STATUS = DISABLE
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EmailSend add(@RequestBody EmailSend emailSend) {
emailSend.setUser(securityService.getCurrentUser());
return emailSendRepository.save(emailSend);
}
@GetMapping
@TWJobsPermissions.IsCompany
public List<EmailSend> getAll() {
return emailSendRepository.findAllByUserId(securityService.getCurrentUser().getId());
}
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public EmailSend put(@PathVariable Long id,@RequestBody EmailSend emailSend) {
// Se liga que no frontend, assim que o usuário clicar a requisição vai ser feita mediante
// clique na check-box
// Se for enable : checa se todos os outros estão disable
// se estão: salva
// se não, retorna um erro
emailSend.setId(id);
emailSend.setUser(securityService.getCurrentUser());
Boolean check = emailSendRepository.existsByUserIdAndStatus(securityService.getCurrentUser().getId(), emailSend.getStatus());
if(emailSend.getStatus() == EmailActivation.enable) {
if(check) {
emailSend.setStatus(EmailActivation.disable);
throw new NegocioException("Você só pode ter 1 e-mail ativo");
}
}
return emailSendRepository.save(emailSend);
}
@DeleteMapping("{id}")
@TWJobsPermissions
public ResponseEntity<Void> delete(@PathVariable Long id) {
Boolean check = emailSendRepository.existsByUserIdAndId(securityService.getCurrentUser().getId(), id);
if(check) {
// return null;
emailSendRepository.deleteById(id);
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}
package br.com.treinaweb.twjobs.api.exceptionhandler;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import lombok.AllArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.*;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.net.URI;
import java.util.stream.Collectors;
@AllArgsConstructor
@RestControllerAdvice
public class ApiExceptionHanler extends ResponseEntityExceptionHandler {
private final MessageSource messageSource;
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
ProblemDetail problemDetail = ProblemDetail.forStatus(status);
problemDetail.setTitle("Um ou mais campos estão inválidos");
problemDetail.setType(URI.create("https://..."));
var fields = ex.getBindingResult().getAllErrors().stream().collect(Collectors.toMap(error -> ((FieldError) error).getField(),
error -> messageSource.getMessage(error, LocaleContextHolder.getLocale())));
problemDetail.setProperty("fields", fields);
return super.handleExceptionInternal(ex, problemDetail, headers, status, request);
}
@ExceptionHandler(NegocioException.class)
public ProblemDetail handleNegocio(NegocioException e){
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
problemDetail.setTitle(e.getMessage());
problemDetail.setType(URI.create("https://..."));
return problemDetail;
}
@ExceptionHandler(DataIntegrityViolationException.class)
public ProblemDetail handleDataIntegrityViolation(DataIntegrityViolationException e){
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.CONFLICT);
problemDetail.setTitle("Recurso está em uso");
problemDetail.setType(URI.create("https://..."));
return problemDetail;
}
}
package br.com.treinaweb.twjobs.api.file;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Files;
import java.util.logging.Level;
import java.util.logging.Logger;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class FileManagerController {
@Autowired
private FileStorageService fileStorageService;
private static final Logger log = Logger.getLogger(FileManagerController.class.getName());
// @PostMapping("/upload-file")
public boolean uploadFile(
// @RequestParam("file")
MultipartFile file) {
try {
fileStorageService.saveFile(file);
return true;
} catch(Exception e) {
log.log(Level.SEVERE, "Exception in file upload.", e);
}
return false;
}
@GetMapping("/download-file")
public ResponseEntity<Resource> downloadFile(
@RequestParam("filename")
String filename) {
log.log(Level.INFO, "[REGULAR] with /download-file");
try{
var fileToDownload = fileStorageService.getDownloadFile(filename);
return ResponseEntity.ok()
.contentLength(fileToDownload.length())
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName =\"" + filename + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new InputStreamResource(Files.newInputStream(fileToDownload.toPath())));
} catch(Exception e) {
return ResponseEntity.notFound().build();
}
// """ PERMITIR QUE SEJA UMA URL NORMAL PARA QUE CONFORME O USUÁRIO CLIQUE AQUELE ARQUIVO ESPECIFICO SEJA BAIXADO
// """ E não uma requisição baixe arquivo por arquivo.
// """ Enviar email pro user. (I)Para accept / (II)Para cadastro de usuário.
// (I)https://youtu.be/_MwdIaMy_Ao?si=V-xn0Rb8nkUow97j (II)https://youtu.be/V-ABkNuubaI?si=83K-Ejfjxs7Gy3if
}
// ~~ DIVIDE FILE EM PARTES -> BAIXA PARALELO
@GetMapping("/download-faster")
public ResponseEntity<Resource> downloadFileFaster(
@RequestParam("fileName")
String filename) {
log.log(Level.INFO, "[FASTER] with /download-faster");
try{
var fileToDownload = fileStorageService.getDownloadFile(filename);
return ResponseEntity.ok()
.contentLength(fileToDownload.length())
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName =\"" + filename + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new FileSystemResource(fileToDownload));
} catch(Exception e) {
return ResponseEntity.notFound().build();
}
// """ PERMITIR QUE SEJA UMA URL NORMAL PARA QUE CONFORME O USUÁRIO CLIQUE AQUELE ARQUIVO ESPECIFICO SEJA BAIXADO
// """ E não uma requisição baixe arquivo por arquivo.
// """ Enviar email pro user. (I)Para accept / (II)Para cadastro de usuário.
// (I)https://youtu.be/_MwdIaMy_Ao?si=V-xn0Rb8nkUow97j (II)https://youtu.be/V-ABkNuubaI?si=83K-Ejfjxs7Gy3if
}
}
package br.com.treinaweb.twjobs.api.file;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Objects;
@Service
public class FileStorageService {
private static final String STORAGE_DIRECTORY = "C:\\StorageJava";
public void saveFile(MultipartFile fileToSave) throws IOException {
if(fileToSave == null) {
throw new NullPointerException("The file is null");
}
var targetFile = new File(STORAGE_DIRECTORY + File.separator + fileToSave.getOriginalFilename());
if(!Objects.equals(targetFile.getParent(), STORAGE_DIRECTORY)){
throw new SecurityException("Unsupported file name.");
}
// O getInputStream é o que salva o file
Files.copy(fileToSave.getInputStream(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public File getDownloadFile(String fileName) throws Exception{
if(fileName == null){
throw new NullPointerException("FileName is null");
}
var fileToDownload = new File(STORAGE_DIRECTORY + File.separator + fileName);
if(!Objects.equals(fileToDownload.getParent(), STORAGE_DIRECTORY)) {
throw new SecurityException("Unsupported fileName!");
}
if(!fileToDownload.exists()) {
throw new FileNotFoundException("No file named:" + fileName);
}
return fileToDownload;
}
}
//package br.com.treinaweb.twjobs.api.files;
//
//import lombok.RequiredArgsConstructor;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.core.io.FileSystemResource;
//import org.springframework.core.io.InputStreamResource;
//import org.springframework.core.io.Resource;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.MediaType;
//import org.springframework.http.ResponseEntity;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.File;
//import java.io.IOException;
//import java.nio.file.DirectoryStream;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.util.logging.Level;
//import java.util.logging.Logger;
//import java.util.stream.Collectors;
//import java.util.stream.StreamSupport;
//
//@RestController
////@RequiredArgsConstructor
////@RequestMapping("/api/files")
//public class FilaManagerController {
//
// @Autowired
// private FileStorageService fileStorageService;
// private static final Logger log = Logger.getLogger(FilaManagerController.class.getName());
//
// @PostMapping("/upload-file")
// public boolean uploadFile(@RequestParam("file") MultipartFile file) {
// try {
// fileStorageService.saveFile(file);
// return true;
// } catch (IOException e) {
// log.log(Level.SEVERE, "Exception during upload", e);
// }
// return false;
// }
//
// @GetMapping("/download")
// public ResponseEntity<Resource> downloadFile(@RequestParam("fileName") String filename) {
// log.log(Level.INFO, "[NORMAL] Download with /download");
// try {
// var fileToDownload = fileStorageService.getDownloadFile(filename);
// return ResponseEntity.ok()
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
// .contentLength(fileToDownload.length())
// .contentType(MediaType.APPLICATION_OCTET_STREAM)
// .body(new InputStreamResource(Files.newInputStream(fileToDownload.toPath())));
// } catch (Exception e) {
// return ResponseEntity.notFound().build();
// }
// }
//
//
//
//
//
//
//
// @GetMapping("/download-faster")
// public ResponseEntity<Resource> downloadFileFaster(@RequestParam("fileName") String filename) {
// log.log(Level.INFO, "[FASTER] Download with /download-faster");
// try {
// var fileToDownload = fileStorageService.getDownloadFile(filename);
// return ResponseEntity.ok()
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
// .contentLength(fileToDownload.length())
// .contentType(MediaType.APPLICATION_OCTET_STREAM)
// .body(new FileSystemResource(fileToDownload));
// } catch (Exception e) {
// return ResponseEntity.notFound().build();
// }
// }
//
//}
//package br.com.treinaweb.twjobs.api.files;
//
//import org.springframework.stereotype.Controller;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.GetMapping;
//
//import java.io.File;
//import java.io.IOException;
//import java.nio.file.DirectoryStream;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.util.stream.Collectors;
//import java.util.stream.StreamSupport;
//
//@Controller
//public class FileManagerGuiController {
//
// @GetMapping("/uploader")
// public String uploader() {
// return "uploader";
// }
//
// @GetMapping("/list-files")
// public String listFiles(Model model) throws IOException {
// try (DirectoryStream<Path> stream = Files.newDirectoryStream(new File(FileStorageService.STORAGE_DIRECTORY).toPath())) {
// model.addAttribute("files",
// StreamSupport.stream(stream.spliterator(), false)
// .map(Path::getFileName)
// .map(Path::toString)
// .collect(Collectors.toList()));
// }
// return "list_files";
// }
//}
\ No newline at end of file
//package br.com.treinaweb.twjobs.api.files;
//
//import org.springframework.stereotype.Service;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.File;
//import java.io.FileNotFoundException;
//import java.io.IOException;
//import java.nio.file.Files;
//import java.nio.file.StandardCopyOption;
//import java.util.Objects;
//
//@Service
//public class FileStorageService {
//
// public static final String STORAGE_DIRECTORY = "C:\\fotos-java\\contato-disco-2";
//
// public void saveFile(MultipartFile fileToSave) throws IOException {
// if (fileToSave == null) {
// throw new NullPointerException("fileToSave is null");
// }
// var targetFile = new File(STORAGE_DIRECTORY + File.separator + fileToSave.getOriginalFilename());
// if (!Objects.equals(targetFile.getParent(), STORAGE_DIRECTORY)) {
// throw new SecurityException("Unsupported filename!");
// }
// Files.copy(fileToSave.getInputStream(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
// }
//
// public File getDownloadFile(String fileName) throws Exception {
// if (fileName == null) {
// throw new NullPointerException("fileName is null");
// }
// var fileToDownload = new File(STORAGE_DIRECTORY + File.separator + fileName);
// if (!Objects.equals(fileToDownload.getParent(), STORAGE_DIRECTORY)) {
// throw new SecurityException("Unsupported filename!");
// }
// if (!fileToDownload.exists()) {
// throw new FileNotFoundException("No file named: " + fileName);
// }
// return fileToDownload;
// }
//}
package br.com.treinaweb.twjobs.api.fotos.controllers;
import br.com.treinaweb.twjobs.core.models.Disco;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/fotos")
public class FotosRestController {
@Autowired
private final Disco disco;
@PostMapping
public void upload(@RequestParam MultipartFile foto, User user, String filetype){
String originalfilename = foto.getOriginalFilename();
disco.salvarFoto(foto, user, originalfilename.substring(originalfilename.lastIndexOf(".")+1));
}
}
package br.com.treinaweb.twjobs.api.jobs.assemblers;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.jobs.controllers.JobRestController;
import br.com.treinaweb.twjobs.api.jobs.controllers.JobSkillsRestController;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
@Component
public class JobAssembler implements SimpleRepresentationModelAssembler<JobResponse> {
@Override
public void addLinks(EntityModel<JobResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(JobRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(JobRestController.class).update(null, id))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(JobRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
var skillsLink = linkTo(methodOn(JobSkillsRestController.class).findSkillsByJobId(id))
.withRel("skills")
.withType("GET");
resource.add(selfLink, updateLink, deleteLink, skillsLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<JobResponse>> resources) {
var selfLink = linkTo(methodOn(JobRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(JobRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.jobs.controllers;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import br.com.treinaweb.twjobs.core.exceptions.JobNotFoundException;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs/{id}")
public class CanidateRestController {
private final JobRepository jobRepository;
private final SecurityService securityService;
@PostMapping("/apply")
@TWJobsPermissions.IsCandidate
public ResponseEntity<?> apply(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
job.getCandidates().add(securityService.getCurrentUser());
jobRepository.save(job);
return ResponseEntity.noContent().build();
}
}
package br.com.treinaweb.twjobs.api.jobs.controllers;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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;
import br.com.treinaweb.twjobs.api.jobs.assemblers.JobAssembler;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.api.jobs.mappers.JobMapper;
import br.com.treinaweb.twjobs.core.exceptions.JobNotFoundException;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs")
public class JobRestController {
private final JobMapper jobMapper;
private final JobAssembler jobAssembler;
private final JobRepository jobRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<JobResponse> pagedResourcesAssembler;
@GetMapping
public CollectionModel<EntityModel<JobResponse>> findAll(Pageable pageable) {
var jobs = jobRepository.findAll(pageable)
.map(jobMapper::toJobResponse);
return pagedResourcesAssembler.toModel(jobs, jobAssembler);
}
@GetMapping("/{id}")
public EntityModel<JobResponse> findById(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
var jobResponse = jobMapper.toJobResponse(job);
return jobAssembler.toModel(jobResponse);
}
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<JobResponse> create(@RequestBody @Valid JobRequest jobRequest) {
var job = jobMapper.toJob(jobRequest);
job.setCompany(securityService.getCurrentUser());
job = jobRepository.save(job);
var jobResponse = jobMapper.toJobResponse(job);
return jobAssembler.toModel(jobResponse);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsOwner
public EntityModel<JobResponse> update(
@RequestBody @Valid JobRequest jobRequest,
@PathVariable Long id
) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
var jobData = jobMapper.toJob(jobRequest);
BeanUtils.copyProperties(jobData, job, "id", "company", "candidates");
job = jobRepository.save(job);
var jobResponse = jobMapper.toJobResponse(job);
return jobAssembler.toModel(jobResponse);
}
@DeleteMapping("/{id}")
@TWJobsPermissions.IsOwner
public ResponseEntity<?> delete(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
jobRepository.delete(job);
return ResponseEntity.noContent().build();
}
}
package br.com.treinaweb.twjobs.api.jobs.controllers;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.api.skills.mappers.SkillMapper;
import br.com.treinaweb.twjobs.core.exceptions.JobNotFoundException;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs/{id}/skills")
public class JobSkillsRestController {
private final SkillMapper skillMapper;
private final JobRepository jobRepository;
@GetMapping
public List<SkillResponse> findSkillsByJobId(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
return job.getSkills()
.stream()
.map(skillMapper::toSkillResponse)
.toList();
}
}
package br.com.treinaweb.twjobs.api.jobs.dtos;
import java.math.BigDecimal;
import java.util.List;
import br.com.treinaweb.twjobs.core.enums.JobLevel;
import br.com.treinaweb.twjobs.core.enums.JobType;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JobRequest {
@NotEmpty
@Size(min = 5, max = 100)
private String title;
@NotEmpty
@Size(min = 10, max = 255)
private String description;
@NotEmpty
@Size(min = 3, max = 100)
private String location;
@NotNull
private JobType type;
@NotNull
private JobLevel level;
@NotNull
@Positive
private BigDecimal salary;
@NotEmpty
private List<Long> skills;
}
package br.com.treinaweb.twjobs.api.jobs.dtos;
import java.math.BigDecimal;
import br.com.treinaweb.twjobs.core.enums.JobLevel;
import br.com.treinaweb.twjobs.core.enums.JobType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JobResponse {
private Long id;
private String title;
private String description;
private String company;
private String location;
private JobType type;
private JobLevel level;
private BigDecimal salary;
}
package br.com.treinaweb.twjobs.api.jobs.mappers;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.core.models.Job;
public interface JobMapper {
JobResponse toJobResponse(Job job);
Job toJob(JobRequest jobRequest);
}
package br.com.treinaweb.twjobs.api.jobs.mappers;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.core.models.Job;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class ModelMapperJobMapper implements JobMapper {
private final ModelMapper modelMapper;
@Override
public JobResponse toJobResponse(Job job) {
return modelMapper.map(job, JobResponse.class);
}
@Override
public Job toJob(JobRequest jobRequest) {
return modelMapper.map(jobRequest, Job.class);
}
}
package br.com.treinaweb.twjobs.api.navios;
import br.com.treinaweb.twjobs.core.models.Navio;
import br.com.treinaweb.twjobs.core.repositories.NavioRepository;
import br.com.treinaweb.twjobs.core.services.CadastroNavioService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@AllArgsConstructor
@RestController
@RequestMapping("/api/navios")
public class NavioController {
private final CadastroNavioService cadastroNavioService;
private final NavioRepository navioRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public Navio adicionar(@Valid @RequestBody Navio navio) {
return cadastroNavioService.salvar(navio);
}
@GetMapping
public List<Navio> listar() {
return navioRepository.findAll();
}
@PutMapping("/{navioId}")
public ResponseEntity<Navio> atualizar(@Valid @PathVariable Long navioId, @Valid @RequestBody Navio navio) {
if(!navioRepository.existsById(navioId)) {
return ResponseEntity.notFound().build();
}
navio.setId(navioId);
Navio navioAtualizado = cadastroNavioService.salvar(navio);
return ResponseEntity.ok(navioAtualizado);
}
}
//package br.com.treinaweb.twjobs.api.ships.assemblers;
//
//import br.com.treinaweb.twjobs.api.ships.controllers.SkillRestController;
//import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
//import org.springframework.hateoas.CollectionModel;
//import org.springframework.hateoas.EntityModel;
//import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
//import org.springframework.stereotype.Component;
//
//import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
//import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
//
//@Component
//public class SkillAssembler implements SimpleRepresentationModelAssembler<SkillResponse> {
//
// @Override
// public void addLinks(EntityModel<SkillResponse> resource) {
// var id = resource.getContent().getId();
//
// var selfLink = linkTo(methodOn(SkillRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
//
// var updateLink = linkTo(methodOn(SkillRestController.class).update(id, null))
// .withRel("update")
// .withType("PUT");
//
// var deleteLink = linkTo(methodOn(SkillRestController.class).delete(id))
// .withRel("delete")
// .withType("DELETE");
//
//
// resource.add(selfLink, updateLink, deleteLink);
// }
//
// @Override
// public void addLinks(CollectionModel<EntityModel<SkillResponse>> resources) {
// var selfLink = linkTo(methodOn(SkillRestController.class).findAll(null))
// .withSelfRel()
// .withType("GET");
//
// var createLink = linkTo(methodOn(SkillRestController.class).create(null))
// .withRel("create")
// .withType("POST");
//
// resources.add(selfLink, createLink);
// }
//
//}
package br.com.treinaweb.twjobs.api.ships.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.api.skills.mappers.SkillMapper;
import br.com.treinaweb.twjobs.core.exceptions.SkillNotFoundException;
import br.com.treinaweb.twjobs.core.models.Ship;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.ShipRepository;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/ships")
public class ShipRestController {
private final ShipRepository shipRepository;
@GetMapping
@TWJobsPermissions.IsCompany
public List<Ship> getAll(){
return shipRepository.findAll();
}
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public Ship add(@RequestBody Ship ship) {
return shipRepository.save(ship);
}
// private final SkillMapper skillMapper;
// private final SkillAssembler skillAssembler;
// private final SkillRepository skillRepository;
// private final PagedResourcesAssembler<SkillResponse> pagedResourcesAssembler;
// @GetMapping
// public CollectionModel<EntityModel<SkillResponse>> findAll(Pageable pageable) {
// var skills = skillRepository.findAll(pageable)
// .map(skillMapper::toSkillResponse);
//
// return pagedResourcesAssembler.toModel(skills, skillAssembler);
// }
// @GetMapping("/{id}")
// public EntityModel<SkillResponse> findById(@PathVariable Long id) {
// var skill = skillRepository.findById(id)
// .map(skillMapper::toSkillResponse)
// .orElseThrow(SkillNotFoundException::new);
//
// return skillAssembler.toModel(skill);
// }
// @PostMapping
// @TWJobsPermissions.IsCompany
// @ResponseStatus(code = HttpStatus.CREATED)
// public EntityModel<SkillResponse> create(@Valid @RequestBody SkillRequest skillRequest) {
// var skill = skillMapper.toSkill(skillRequest);
// skill = skillRepository.save(skill);
// var skillResponse = skillMapper.toSkillResponse(skill);
// return skillAssembler.toModel(skillResponse);
// }
// @PutMapping("/{id}")
// @TWJobsPermissions.IsCompany
// public EntityModel<SkillResponse> update(
// @PathVariable Long id,
// @Valid @RequestBody SkillRequest skillRequest
// ) {
// var skill = skillRepository.findById(id)
// .orElseThrow(SkillNotFoundException::new);
// BeanUtils.copyProperties(skillRequest, skill, "id");
// skill = skillRepository.save(skill);
// var skillResponse = skillMapper.toSkillResponse(skill);
// return skillAssembler.toModel(skillResponse);
// }
// @DeleteMapping("/{id}")
// @TWJobsPermissions.IsCompany
// public ResponseEntity<?> delete(@PathVariable Long id) {
// var skill = skillRepository.findById(id)
// .orElseThrow(SkillNotFoundException::new);
// skillRepository.delete(skill);
// return ResponseEntity.noContent().build();
// }
}
package br.com.treinaweb.twjobs.api.ships.dtos;
import br.com.treinaweb.twjobs.core.validators.SkillNameIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ShipRequest {
@NotEmpty
@SkillNameIsUnique
private String imo;
}
package br.com.treinaweb.twjobs.api.ships.dtos;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ShipResponse {
private Long id;
private String imo;
}
//package br.com.treinaweb.twjobs.api.ships.mappers;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//import lombok.RequiredArgsConstructor;
//import org.modelmapper.ModelMapper;
//import org.springframework.stereotype.Component;
//
//@Component
//@RequiredArgsConstructor
//public class ModelMapperSkillMapper implements SkillMapper {
//
// private final ModelMapper modelMapper;
//
// @Override
// public Skill toSkill(ShipRequest skillRequest) {
// return modelMapper.map(skillRequest, Skill.class);
// }
//
// @Override
// public ShipResponse toSkillResponse(Skill skill) {
// return modelMapper.map(skill, ShipResponse.class);
// }
//
//}
//package br.com.treinaweb.twjobs.api.ships.mappers;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
//public interface SkillMapper {
//
// Skill toSkill(ShipRequest skillRequest);
// ShipResponse toSkillResponse(Skill skill);
//
//}
package br.com.treinaweb.twjobs.api.skills.assemblers;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.skills.controllers.SkillRestController;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
@Component
public class SkillAssembler implements SimpleRepresentationModelAssembler<SkillResponse> {
@Override
public void addLinks(EntityModel<SkillResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(SkillRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(SkillRestController.class).update(id, null))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(SkillRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(selfLink, updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<SkillResponse>> resources) {
var selfLink = linkTo(methodOn(SkillRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(SkillRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.skills.controllers;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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;
import br.com.treinaweb.twjobs.api.skills.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillRequest;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.api.skills.mappers.SkillMapper;
import br.com.treinaweb.twjobs.core.exceptions.SkillNotFoundException;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/skills")
public class SkillRestController {
private final SkillMapper skillMapper;
private final SkillAssembler skillAssembler;
private final SkillRepository skillRepository;
private final PagedResourcesAssembler<SkillResponse> pagedResourcesAssembler;
@GetMapping
public CollectionModel<EntityModel<SkillResponse>> findAll(Pageable pageable) {
var skills = skillRepository.findAll(pageable)
.map(skillMapper::toSkillResponse);
return pagedResourcesAssembler.toModel(skills, skillAssembler);
}
@GetMapping("/{id}")
public EntityModel<SkillResponse> findById(@PathVariable Long id) {
var skill = skillRepository.findById(id)
.map(skillMapper::toSkillResponse)
.orElseThrow(SkillNotFoundException::new);
return skillAssembler.toModel(skill);
}
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<SkillResponse> create(@Valid @RequestBody SkillRequest skillRequest) {
var skill = skillMapper.toSkill(skillRequest);
skill = skillRepository.save(skill);
var skillResponse = skillMapper.toSkillResponse(skill);
return skillAssembler.toModel(skillResponse);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public EntityModel<SkillResponse> update(
@PathVariable Long id,
@Valid @RequestBody SkillRequest skillRequest
) {
var skill = skillRepository.findById(id)
.orElseThrow(SkillNotFoundException::new);
BeanUtils.copyProperties(skillRequest, skill, "id");
skill = skillRepository.save(skill);
var skillResponse = skillMapper.toSkillResponse(skill);
return skillAssembler.toModel(skillResponse);
}
@DeleteMapping("/{id}")
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var skill = skillRepository.findById(id)
.orElseThrow(SkillNotFoundException::new);
skillRepository.delete(skill);
return ResponseEntity.noContent().build();
}
}
package br.com.treinaweb.twjobs.api.skills.dtos;
import br.com.treinaweb.twjobs.core.validators.SkillNameIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SkillRequest {
@NotEmpty
@SkillNameIsUnique
private String name;
}
package br.com.treinaweb.twjobs.api.skills.dtos;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class SkillResponse {
private Long id;
private String name;
}
package br.com.treinaweb.twjobs.api.skills.mappers;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillRequest;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class ModelMapperSkillMapper implements SkillMapper {
private final ModelMapper modelMapper;
@Override
public Skill toSkill(SkillRequest skillRequest) {
return modelMapper.map(skillRequest, Skill.class);
}
@Override
public SkillResponse toSkillResponse(Skill skill) {
return modelMapper.map(skill, SkillResponse.class);
}
}
package br.com.treinaweb.twjobs.api.skills.mappers;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillRequest;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
public interface SkillMapper {
Skill toSkill(SkillRequest skillRequest);
SkillResponse toSkillResponse(Skill skill);
}
package br.com.treinaweb.twjobs.api.users.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.users.controllers.UsersCRUDRestController;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class UserAssembler implements SimpleRepresentationModelAssembler<UserResponse> {
@Override
public void addLinks(EntityModel<UserResponse> resource) {
var id = resource.getContent().getId();
// var selfLink = linkTo(methodOn(UsersCRUDRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
Link updateLink = null;
updateLink = linkTo(methodOn(UsersCRUDRestController.class).update(id, null))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(UsersCRUDRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(
// selfLink,
updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<UserResponse>> resources) {
var selfLink = linkTo(methodOn(UsersCRUDRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
// Link createLink = null;
// try {
// createLink = linkTo(methodOn(UsersCRUDRestController.class).create(null, null))
// .withRel("create")
// .withType("POST");
// } catch (JsonProcessingException e) {
// throw new RuntimeException(e);
// }
resources.add(selfLink
//,
// createLink
);
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.users.controllers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.api.users.assemblers.UserAssembler;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import br.com.treinaweb.twjobs.api.users.mappers.UserMapper;
import br.com.treinaweb.twjobs.api.vessels.assemblers.VesselAssembler;
import br.com.treinaweb.twjobs.api.vessels.mappers.VesselMapper;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/users")
public class UsersCRUDRestController {
// private final UserMapper userMapper;
private final UserAssembler userAssembler;
private final UserMapper userMapper;
private final UserRepository userRepository;
private final SecurityService securityService;
private final PasswordEncoder passwordEncoder;
// private final UserAssembler userAssembler;
private final PagedResourcesAssembler<UserResponse> pagedResourcesAssembler;
@GetMapping
@TWJobsPermissions.IsCompany
public CollectionModel<EntityModel<UserResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
var users = userRepository.findAll(pageable)
.map(userMapper::toUserResponse);
return pagedResourcesAssembler.toModel(users, userAssembler);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public User update(@PathVariable Long id, @RequestBody User user) {
Optional<User> userSaved = userRepository.findById(id);
//A única coisa que pode alterar até agora é o atributo SendEmail
user.setEmail(userSaved.get().getEmail());
user.setPassword(userSaved.get().getPassword());
user.setName(userSaved.get().getName());
user.setRole(userSaved.get().getRole());
user.setId(id);
Boolean check = userRepository.existsBySendEmail(user.getSendEmail());
if(user.getSendEmail() == Boolean.TRUE) {
if(check) {
user.setSendEmail(Boolean.FALSE);
throw new NegocioException("Você só pode ter 1 e-mail ativo");
}
}
//É NECESSÁRIO QUE O FRONT DESCRIPTOGRAFE
//var passwordHash = passwordEncoder.encode(user.getPassword());
//user.setPassword(passwordHash);
return userRepository.save(user);
}
@DeleteMapping("{id}")
@TWJobsPermissions
public ResponseEntity<Void> delete(@PathVariable Long id) {
Boolean check = userRepository.existsById(id);
Optional<User> user = userRepository.findById(id);
if(check) {
if(user != null) {
//user.deleteById(id);
throw new NegocioException("Error");
}
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}
package br.com.treinaweb.twjobs.api.users.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.persistence.*;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserRequest {
private String name;
private String email;
private String password;
private Role role;
private Boolean sendEmail;
}
package br.com.treinaweb.twjobs.api.users.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.persistence.*;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String name;
private String email;
private String password;
private Role role;
private Boolean sendEmail;
}
package br.com.treinaweb.twjobs.api.users.mappers;
import br.com.treinaweb.twjobs.api.users.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperUserCRUDMapper implements UserMapper {
private final ModelMapper modelMapper;
@Override
public User toUser(UserRequest userRequest) {
return modelMapper.map(userRequest, User.class);
}
@Override
public UserResponse toUserResponse(User user) {
return modelMapper.map(user, UserResponse.class);
}
}
package br.com.treinaweb.twjobs.api.users.mappers;
import br.com.treinaweb.twjobs.api.users.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
public interface UserMapper {
User toUser(UserRequest userRequest);
UserResponse toUserResponse(User user);
}
package br.com.treinaweb.twjobs.api.vessels.assemblers;
import br.com.treinaweb.twjobs.api.vessels.controllers.VesselRestController;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class VesselAssembler implements SimpleRepresentationModelAssembler<VesselResponse> {
@Override
public void addLinks(EntityModel<VesselResponse> resource) {
var id = resource.getContent().getId();
// var selfLink = linkTo(methodOn(VesselRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
Link updateLink = null;
try {
updateLink = linkTo(methodOn(VesselRestController.class).update(null, id, null))
.withRel("update")
.withType("PUT");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
var deleteLink = linkTo(methodOn(VesselRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(
// selfLink,
updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<VesselResponse>> resources) {
var selfLink = linkTo(methodOn(VesselRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
Link createLink = null;
try {
createLink = linkTo(methodOn(VesselRestController.class).create(null, null))
.withRel("create")
.withType("POST");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.vessels.controllers;
import br.com.treinaweb.twjobs.api.vessels.assemblers.VesselAssembler;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.api.vessels.mappers.VesselMapper;
import br.com.treinaweb.twjobs.core.exceptions.VesselNotFoundException;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.hateoas.EntityModel;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/vdatas")
public class VesselDataRestController {
private final VesselRepository vesselRepository;
private final VesselMapper vesselMapper;
private final VesselAssembler vesselAssembler;
@GetMapping("{imo}")
EntityModel<VesselResponse> ReturnVDataByImo(@PathVariable Long imo){
var vessel = vesselRepository.findByImo(imo)
.orElseThrow(VesselNotFoundException::new);
var vesselResponse = vesselMapper.toVesselResponse(vessel);
return vesselAssembler.toModel(vesselResponse);
}
}
package br.com.treinaweb.twjobs.api.vessels.dtos;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.validators.SkillNameIsUnique;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.springframework.web.multipart.MultipartFile;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VesselRequest {
// AJEITAR
//COMENTEI ID, SE DER ERRO É ISSO AQUI
//private Long id;
// private Long user;
//not empty não está funcionando. Ajeiter.
// @NotEmpty
// @VesselImoIsUnique
@NotNull(message = "IMO não pode ser nulo")
// @Size(min = 7, message = "IMO deve ter no mínimo 7 caracteres")
private Long imo;
private String mmsi;
private String nome;
//NOT NULL AND GREATER THAN ZERO
@NotNull(message = "LOA deve ser maior que zero")
// @Size(min = 1, max = 100, message = "LOA deve ter no mínimo 1 e no máximo 100 caracteres")
private Float loa;
private Float boca;
//NOT NULL AND GREATER THAN ZERO
@NotNull(message = "DWT deve ser maior que zero")
// @Size(min = 1, max = 100, message = "DWT deve ter no mínimo 1 e no máximo 100 caracteres")
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
//NOT NULL
// @NotEmpty
// @Size(min = 1, max = 100, message = "CATEGORIA deve ter no mínimo 1 e no máximo 100 caracteres")
private String categoria;
@JsonProperty("flag")
private String flag;
private String obs;
//private VeriStatus status;
//private VeriStatus st_ver_vessel;
private String path;
}
package br.com.treinaweb.twjobs.api.vessels.dtos;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class VesselResponse {
private Long id;
private String user;
private Long imo;
private String mmsi;
private String nome;
private Float loa;
private Float boca;
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
private String categoria;
private String flag;
private String obs;
private String status;
private String st_ver_vessel;
private String path;
}
package br.com.treinaweb.twjobs.api.vessels.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselRequest;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
import br.com.treinaweb.twjobs.core.models.Vessel;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperVesselMapper implements VesselMapper {
private final ModelMapper modelMapper;
@Override
public Vessel toVessel(VesselRequest vesselRequest) {
return modelMapper.map(vesselRequest, Vessel.class);
}
@Override
public VesselResponse toVesselResponse(Vessel vessel) {
return modelMapper.map(vessel, VesselResponse.class);
}
}
package br.com.treinaweb.twjobs.api.vessels.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselRequest;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
import br.com.treinaweb.twjobs.core.models.Vessel;
public interface VesselMapper {
Vessel toVessel(VesselRequest vesselRequest);
VesselResponse toVesselResponse(Vessel vessel);
}
package br.com.treinaweb.twjobs.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties(prefix = "br.com.treinaweb.twjobs.jwt")
public class JwtConfigProperties {
private String accessSecret;
private Long accessExpiresIn;
private String refreshSecret;
private Long refreshExpiresIn;
}
package br.com.treinaweb.twjobs.config;
import java.util.List;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.core.models.Job;
import br.com.treinaweb.twjobs.core.models.Skill;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import lombok.RequiredArgsConstructor;
@Configuration
@RequiredArgsConstructor
public class ModelMapperConfig {
private final SkillRepository skillRepository;
@Bean
ModelMapper modelMapper() {
var modelmapper = new ModelMapper();
modelmapper.createTypeMap(JobRequest.class, Job.class)
.addMappings(mapper -> mapper
.using(toListOfSkills())
.map(JobRequest::getSkills, Job::setSkills)
);
modelmapper.createTypeMap(Job.class, JobResponse.class)
.addMappings(mapper -> mapper
.map(src -> src.getCompany().getName(), JobResponse::setCompany)
);
return modelmapper;
}
private Converter<List<Long>, List<Skill>> toListOfSkills() {
return context -> skillRepository.findAllById(context.getSource());
}
}
package br.com.treinaweb.twjobs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordEnconderConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
package br.com.treinaweb.twjobs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
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.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import br.com.treinaweb.twjobs.api.common.filters.AccessTokenRequestFilter;
import lombok.RequiredArgsConstructor;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
private final AccessDeniedHandler accessDeniedHandler;
private final AccessTokenRequestFilter accessTokenRequestFilter;
private final AuthenticationEntryPoint authenticationEntryPoint;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(customizer -> customizer
.anyRequest().permitAll()
)
// .logout((logout) -> logout.logoutUrl("/teste/logout").permitAll())
.csrf(customizer -> customizer
.disable()
)
.sessionManagement(customizer -> customizer
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.exceptionHandling(customizer -> customizer
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
)
.addFilterBefore(accessTokenRequestFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration
) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
package br.com.treinaweb.twjobs.core.enums;
public enum AceiteStatus {
Y,
N;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment