Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 110 additions & 1 deletion src/main/java/com/minsait/api/controller/ApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
import com.minsait.api.controller.dto.ClienteRequest;
import com.minsait.api.controller.dto.ClienteResponse;
import com.minsait.api.controller.dto.MessageResponse;
import com.minsait.api.controller.dto.UsuarioRequest;
import com.minsait.api.controller.dto.UsuarioResponse;
import com.minsait.api.repository.ClienteEntity;
import com.minsait.api.repository.ClienteRepository;
import com.minsait.api.repository.UsuarioEntity;
import com.minsait.api.repository.UsuarioRepository;
import com.minsait.api.util.ObjectMapperUtil;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@RestController
Expand All @@ -26,6 +33,9 @@ public class ApiController implements ApiSwagger{

@Autowired
private ClienteRepository clienteRepository;

@Autowired
private UsuarioRepository usuarioRepository;

@PreAuthorize("hasAuthority('LEITURA_CLIENTE')")
@GetMapping("/cliente")
Expand Down Expand Up @@ -104,4 +114,103 @@ public ResponseEntity<ClienteResponse> findById(@PathVariable Long id){

return new ResponseEntity<>(clienteResponse, HttpStatus.OK);
}

@PreAuthorize("hasAuthority('LEITURA_USUARIO')")
@GetMapping("/usuario")
public ResponseEntity<Page<UsuarioResponse>> usuarioFindAll(@RequestParam(required = false) String nome,
@RequestParam(required = false) String login,
@RequestParam(required = false) String email,
@RequestParam(required = false, defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "10") int pageSize) {
final var usuarioEntity = new UsuarioEntity();
usuarioEntity.setNome(nome);
usuarioEntity.setLogin(login);
usuarioEntity.setEmail(email);

Pageable pageable = PageRequest.of(page, pageSize);

final Page<UsuarioEntity> usuarioEntityListPage = usuarioRepository.findAll(
usuarioEntity.usuarioEntitySpecification(), pageable);
final Page<UsuarioResponse> usuarioResponseList = ObjectMapperUtil.mapAll(usuarioEntityListPage,
UsuarioResponse.class);
return ResponseEntity.ok(usuarioResponseList);
}

@PreAuthorize("hasAuthority('ESCRITA_USUARIO')")
@PostMapping("/usuario")
public ResponseEntity<UsuarioResponse> insertUsuario(@RequestBody UsuarioRequest request){

BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

final var usuarioEntity = ObjectMapperUtil.map(request, UsuarioEntity.class);

final var senhaEncoded = passwordEncoder.encode(usuarioEntity.getSenha());
usuarioEntity.setSenha(senhaEncoded);

final var usuarioInserted = usuarioRepository.save(usuarioEntity);
final var usuarioResponse = ObjectMapperUtil.map(usuarioInserted, UsuarioResponse.class);

return new ResponseEntity<>(usuarioResponse, HttpStatus.CREATED);
}

@PreAuthorize("hasAuthority('ESCRITA_USUARIO')")
@PutMapping("/usuario")
public ResponseEntity<UsuarioResponse> updateUsuario(@RequestBody UsuarioRequest request){
final var usuarioEntity = ObjectMapperUtil.map(request, UsuarioEntity.class);
final var usuarioEntityFound = usuarioRepository.findById(usuarioEntity.getId());

if (usuarioEntityFound.isPresent()) {
BeanUtils.copyProperties(usuarioEntity, usuarioEntityFound.get(), "senha");

if (Objects.nonNull(usuarioEntity.getSenha()) && !usuarioEntity.getSenha().isBlank()) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String senhaEncoded = encoder.encode(usuarioEntity.getSenha());
usuarioEntityFound.get().setSenha(senhaEncoded);
}

final var usuarioUpdated = usuarioRepository.save(usuarioEntityFound.get());
final var usuarioResponse = ObjectMapperUtil.map(usuarioUpdated, UsuarioResponse.class);

return new ResponseEntity<>(usuarioResponse, HttpStatus.OK);
} else {
return new ResponseEntity<>(new UsuarioResponse(), HttpStatus.NOT_FOUND);
}
}

@PreAuthorize("hasAuthority('ESCRITA_USUARIO')")
@DeleteMapping("/usuario/{id}")
public ResponseEntity<MessageResponse> deleteUsuario(@PathVariable Long id){
final var usuarioEntityFound = usuarioRepository.findById(id);
if(usuarioEntityFound.isPresent()){
usuarioRepository.delete(usuarioEntityFound.get());
}else{
return new ResponseEntity<>(MessageResponse.builder()
.message("Usuário não encontrado!")
.date(LocalDateTime.now())
.error(false)
.build(), HttpStatus.NOT_FOUND);
}

return new ResponseEntity<>(MessageResponse.builder()
.message("OK")
.date(LocalDateTime.now())
.error(false)
.build(), HttpStatus.OK);
}

@PreAuthorize("hasAuthority('LEITURA_USUARIO')")
@GetMapping("/usuario/{id}")
public ResponseEntity<UsuarioResponse> usuarioFindById(@PathVariable Long id){
final var usuarioEntity = usuarioRepository.findById(id);
UsuarioResponse usuarioResponse = new UsuarioResponse();

if (usuarioEntity.isPresent()){
usuarioResponse = ObjectMapperUtil.map(usuarioEntity.get(), UsuarioResponse.class);
}else{
return new ResponseEntity<>(usuarioResponse, HttpStatus.NOT_FOUND);
}

return new ResponseEntity<>(usuarioResponse, HttpStatus.OK);
}

}
55 changes: 55 additions & 0 deletions src/main/java/com/minsait/api/controller/ApiSwagger.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.minsait.api.controller.dto.ClienteRequest;
import com.minsait.api.controller.dto.ClienteResponse;
import com.minsait.api.controller.dto.MessageResponse;
import com.minsait.api.controller.dto.UsuarioRequest;
import com.minsait.api.controller.dto.UsuarioResponse;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -63,4 +66,56 @@ public interface ApiSwagger {
}
)
public ResponseEntity<ClienteResponse> findById(Long id);

@Operation(summary = "Busca todos os usuarios",
responses = {
@ApiResponse(responseCode = "200", description = "Dados do usuario retornados com sucesso"),
@ApiResponse(responseCode = "400", description = "Parâmetros inválidos"),
@ApiResponse(responseCode = "500", description = "Erro interno"),
@ApiResponse(responseCode = "403", description = "Acesso negado"),
}
)
public ResponseEntity<Page<UsuarioResponse>> usuarioFindAll(String nome, String login, String email, int page, int pagesize);

@Operation(summary = "Insere um novo usuario",
responses = {
@ApiResponse(responseCode = "200", description = "Usuario inserido com sucesso"),
@ApiResponse(responseCode = "400", description = "Parâmetros inválidos"),
@ApiResponse(responseCode = "500", description = "Erro interno"),
@ApiResponse(responseCode = "403", description = "Acesso negado"),
}
)
public ResponseEntity<UsuarioResponse> insertUsuario(UsuarioRequest request);

@Operation(summary = "Atualiza um usuario",
responses = {
@ApiResponse(responseCode = "200", description = "Usuario atualizado com sucesso"),
@ApiResponse(responseCode = "400", description = "Parâmetros inválidos"),
@ApiResponse(responseCode = "500", description = "Erro interno"),
@ApiResponse(responseCode = "403", description = "Acesso negado"),
}
)
public ResponseEntity<UsuarioResponse> updateUsuario(UsuarioRequest request);

@Operation(summary = "Exclui um usuario",
responses = {
@ApiResponse(responseCode = "200", description = "Usuario excluído com sucesso"),
@ApiResponse(responseCode = "400", description = "Parâmetros inválidos"),
@ApiResponse(responseCode = "404", description = "Cliente não encontrado"),
@ApiResponse(responseCode = "500", description = "Erro interno"),
@ApiResponse(responseCode = "403", description = "Acesso negado"),
}
)
public ResponseEntity<MessageResponse> deleteUsuario(Long id);

@Operation(summary = "Busca um usuario pelo id",
responses = {
@ApiResponse(responseCode = "200", description = "Dados do cliente retornados com sucesso"),
@ApiResponse(responseCode = "400", description = "Parâmetros inválidos"),
@ApiResponse(responseCode = "404", description = "Cliente não encontrado"),
@ApiResponse(responseCode = "500", description = "Erro interno"),
@ApiResponse(responseCode = "403", description = "Acesso negado"),
}
)
public ResponseEntity<UsuarioResponse> usuarioFindById(Long id);
}
41 changes: 29 additions & 12 deletions src/main/java/com/minsait/api/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.minsait.api.controller.dto.GetTokenRequest;
import com.minsait.api.controller.dto.GetTokenResponse;
import com.minsait.api.controller.dto.UsuarioRequest;
import com.minsait.api.repository.UsuarioEntity;
import com.minsait.api.repository.UsuarioRepository;
import com.minsait.api.sicurity.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -17,6 +19,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@RestController
@RequestMapping(value = "/auth")
Expand All @@ -30,17 +33,31 @@ public class AuthController {

@PostMapping("/get-token")
public ResponseEntity<GetTokenResponse> getToken(@RequestBody GetTokenRequest request){
if(request.getPassword().equals("12345") && request.getUserName().equals("root")){
final ArrayList<String> permissions = new ArrayList<>();
permissions.add("LEITURA_CLIENTE");
permissions.add("ESCRITA_CLIENTE");

final var token =jwtUtil.generateToken("admin", permissions, 5);
return new ResponseEntity<>(GetTokenResponse.builder()
.accessToken(token)
.build(), HttpStatus.OK);
}else{
return new ResponseEntity<>(GetTokenResponse.builder().build(), HttpStatus.UNAUTHORIZED);
}
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

Optional<UsuarioEntity> usuarioEntity = Optional.ofNullable(usuarioRepository.findByLogin(request.getUserName()));

if (usuarioEntity.isPresent()) {
UsuarioEntity usuario = usuarioEntity.get();
boolean isIdenticalPassword = encoder.matches(request.getPassword(), usuario.getSenha());

if (isIdenticalPassword) {
int userId = Math.toIntExact(usuario.getId());
String[] usuarioPermissions = usuario.getPermissoes().split(",");
ArrayList<String> permissions = new ArrayList<>(List.of(usuarioPermissions));

String token = jwtUtil.generateToken(usuario.getLogin(), permissions, userId);

GetTokenResponse response = GetTokenResponse.builder()
.accessToken(token)
.build();

return new ResponseEntity<>(response, HttpStatus.OK);
} else {
return new ResponseEntity<>(GetTokenResponse.builder().build(), HttpStatus.UNAUTHORIZED);
}
} else {
return new ResponseEntity<>(GetTokenResponse.builder().build(), HttpStatus.UNAUTHORIZED);
}
}
}
25 changes: 25 additions & 0 deletions src/main/java/com/minsait/api/repository/UsuarioEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,29 @@ public class UsuarioEntity {

@Column(name = "PERMISSOES")
private String permissoes;

public Specification<UsuarioEntity> usuarioEntitySpecification() {

return (root, query, criteriaBuilder) -> {

List<Predicate> predicates = new ArrayList<>();

if (this.getNome() != null) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("nome")),
"%" + this.getNome().trim().toLowerCase() + "%"));
}

if (this.getNome() != null) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("login")),
"%" + this.getNome().trim().toLowerCase() + "%"));
}

if (this.getEmail() != null) {
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(root.get("email")),
"%" + this.getEmail().trim().toLowerCase() + "%"));
}

return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/minsait/api/sicurity/util/JWTUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public class JWTUtil {
@Value("${security.enabled}")
private String securityEnabled;

public String generateToken(String username, ArrayList<String> authorities, Integer user_id) {
public String generateToken(String username, ArrayList<String> authorities, Integer i) {
return Jwts.builder()
.claim("user_name",username)
.claim("authorities",authorities)
.claim("user_id", user_id)
.claim("user_id", i)
.setExpiration(new Date(System.currentTimeMillis() + 600000))
.signWith(SignatureAlgorithm.HS512, this.jwtSecret.getBytes())
.compact();
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/db/migration/V1_0__create_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ INSERT INTO API.CLIENTE (ID_CLIENTE, NOME, ENDERECO, EMAIL, TELEFONE) VALUES (AP
INSERT INTO API.CLIENTE (ID_CLIENTE, NOME, ENDERECO, EMAIL, TELEFONE) VALUES (API.SQ_ID_CLIENTE.nextval,'Jão','Rua H, 343','jose14@outlook.com','53 988098432');
INSERT INTO API.CLIENTE (ID_CLIENTE, NOME, ENDERECO, EMAIL, TELEFONE) VALUES (API.SQ_ID_CLIENTE.nextval,'Manolo','Rua M, 342','jose14@outlook.com','53 98098234');
INSERT INTO API.CLIENTE (ID_CLIENTE, NOME, ENDERECO, EMAIL, TELEFONE) VALUES (API.SQ_ID_CLIENTE.nextval,'Wlisses','Rua N, 341','jose14@outlook.com','53 98098234');
INSERT INTO API.CLIENTE (ID_CLIENTE, NOME, ENDERECO, EMAIL, TELEFONE) VALUES (API.SQ_ID_CLIENTE.nextval,'Leonardo','Rua O, 320','jose14@outlook.com','53 980928347');
INSERT INTO API.CLIENTE (ID_CLIENTE, NOME, ENDERECO, EMAIL, TELEFONE) VALUES (API.SQ_ID_CLIENTE.nextval,'Leonardo','Rua O, 320','jose14@outlook.com','53 980928347');

INSERT INTO API.USUARIO (ID_USUARIO, NOME, LOGIN, SENHA, EMAIL, PERMISSOES) VALUES (API.SQ_ID_USUARIO.nextval,'Root','root','$2a$10$YLB5vynNTFpphYxzjQPuruLmsdmoEcxSXO.3H.EVvrqXSKWptstUe', 'root@api.minsait.com', 'ESCRITA_CLIENTE,LEITURA_CLIENTE,ESCRITA_USUARIO,LEITURA_USUARIO');
INSERT INTO API.USUARIO (ID_USUARIO, NOME, LOGIN, SENHA, EMAIL, PERMISSOES) VALUES (API.SQ_ID_USUARIO.nextval,'Administrador','admin','$2a$10$YLB5vynNTFpphYxzjQPuruLmsdmoEcxSXO.3H.EVvrqXSKWptstUe', 'admin@api.minsait.com', 'ESCRITA_CLIENTE,LEITURA_CLIENTE,ESCRITA_USUARIO,LEITURA_USUARIO');
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void updatePasword() throws Exception {
final var usuarioAlterado = usuarioRepository.findByLogin(request.getLogin());
assertEquals(request.getNome(), usuarioAlterado.getNome());

//verifica se a senha foi alerada no banco
//verifica se a senha foi alterada no banco
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
assertTrue(encoder.matches(request.getSenha(), usuarioAlterado.getSenha()));

Expand Down