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
30 changes: 30 additions & 0 deletions src/main/java/com/devsuperior/bds03/config/AppConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.devsuperior.bds03.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
public class AppConfig {
@Value("${jwt.secret}")
private String jwtSecret;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
tokenConverter.setSigningKey(jwtSecret);
return tokenConverter;
}

@Bean
public JwtTokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.devsuperior.bds03.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.client.client-secret}")
private String clientSecret;
@Value("${jwt.duration}")
private Integer jwtDuration;

private final BCryptPasswordEncoder passwordEncoder;
private final JwtAccessTokenConverter accessTokenConverter;
private final JwtTokenStore tokenStore;
private final AuthenticationManager authenticationManager;


public AuthorizationServerConfig(BCryptPasswordEncoder passwordEncoder , JwtAccessTokenConverter accessTokenConverter , JwtTokenStore tokenStore , AuthenticationManager authenticationManager) {
this.passwordEncoder = passwordEncoder;
this.accessTokenConverter = accessTokenConverter;
this.tokenStore = tokenStore;
this.authenticationManager = authenticationManager;
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.scopes("read", "write")
.authorizedGrantTypes("password")
.accessTokenValiditySeconds(jwtDuration);
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.devsuperior.bds03.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.util.Arrays;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

private final JwtTokenStore tokenStore;
private final Environment env;
private static final String[] PUBLIC = { "/oauth/token", "/h2-console/**" };
private static final String[] OPERATOR_GET = { "/departments/**", "/employees/**" };

public ResourceServerConfig(JwtTokenStore tokenStore , Environment env) {
this.tokenStore = tokenStore;
this.env = env;
}

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore);
}

@Override
public void configure(HttpSecurity http) throws Exception {

// H2
if (Arrays.asList(env.getActiveProfiles()).contains("test")) {
http.headers().frameOptions().disable();
}

http.authorizeRequests()
.antMatchers(PUBLIC).permitAll()
.antMatchers(HttpMethod.GET, OPERATOR_GET).hasAnyRole("OPERATOR", "ADMIN")
.anyRequest().hasAnyRole("ADMIN");
}
}
16 changes: 0 additions & 16 deletions src/main/java/com/devsuperior/bds03/config/SecurityConfig.java

This file was deleted.

40 changes: 40 additions & 0 deletions src/main/java/com/devsuperior/bds03/config/WebSecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.devsuperior.bds03.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.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

private final BCryptPasswordEncoder passwordEncoder;
private final UserDetailsService userDetailsService;

public WebSecurityConfig(BCryptPasswordEncoder passwordEncoder , UserDetailsService userDetailsService) {
this.passwordEncoder = passwordEncoder;
this.userDetailsService = userDetailsService;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}

@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/actuator/**");
}

@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package com.devsuperior.bds03.controllers;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import com.devsuperior.bds03.dto.DepartmentDTO;
import com.devsuperior.bds03.services.DepartmentService;
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 com.devsuperior.bds03.dto.DepartmentDTO;
import com.devsuperior.bds03.services.DepartmentService;
import java.util.List;

@RestController
@RequestMapping(value = "/departments")
public class DepartmentController {

@Autowired
private DepartmentService service;

@GetMapping
private final DepartmentService service;

public DepartmentController(DepartmentService service) {
this.service = service;
}

@GetMapping
public ResponseEntity<List<DepartmentDTO>> findAll() {
List<DepartmentDTO> list = service.findAll();
return ResponseEntity.ok().body(list);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,37 @@
package com.devsuperior.bds03.controllers;

import java.net.URI;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import com.devsuperior.bds03.dto.EmployeeDTO;
import com.devsuperior.bds03.services.EmployeeService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
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.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import com.devsuperior.bds03.dto.EmployeeDTO;
import com.devsuperior.bds03.services.EmployeeService;
import javax.validation.Valid;
import java.net.URI;

@RestController
@RequestMapping(value = "/employees")
public class EmployeeController {

@Autowired
private EmployeeService service;

@GetMapping
private final EmployeeService service;

public EmployeeController(EmployeeService service) {
this.service = service;
}

@GetMapping
public ResponseEntity<Page<EmployeeDTO>> findAll(Pageable pageable) {
PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by("name"));
Page<EmployeeDTO> list = service.findAll(pageRequest);
return ResponseEntity.ok().body(list);
}

@PostMapping
public ResponseEntity<EmployeeDTO> insert(@RequestBody EmployeeDTO dto) {
public ResponseEntity<EmployeeDTO> insert(@Valid @RequestBody EmployeeDTO dto) {
dto = service.insert(dto);
URI uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
.buildAndExpand(dto.getId()).toUri();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.devsuperior.bds03.controllers.exceptions;

import java.io.Serializable;

public class FieldMessage implements Serializable {
private static final long serialVersionUID = 1L;

private String fieldName;
private String message;

public FieldMessage() {}

public FieldMessage(String fieldName , String message) {
this.fieldName = fieldName;
this.message = message;
}

public String getFieldName() {
return fieldName;
}

public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.devsuperior.bds03.controllers.exceptions;

import com.devsuperior.bds03.services.exceptions.DatabaseException;
import com.devsuperior.bds03.services.exceptions.ResourceNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import java.time.Instant;

@ControllerAdvice
public class ResourceExceptionHandler {

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<StandardError> entityNotFound(ResourceNotFoundException e, HttpServletRequest request) {
HttpStatus status = HttpStatus.NOT_FOUND;
StandardError err = new StandardError();
err.setTimestamp(Instant.now());
err.setStatus(status.value());
err.setError("Resource not found");
err.setMessage(e.getMessage());
err.setPath(request.getRequestURI());
return ResponseEntity.status(status).body(err);
}

@ExceptionHandler(DatabaseException.class)
public ResponseEntity<StandardError> database(DatabaseException e, HttpServletRequest request) {
HttpStatus status = HttpStatus.BAD_REQUEST;
StandardError err = new StandardError();
err.setTimestamp(Instant.now());
err.setStatus(status.value());
err.setError("Database exception");
err.setMessage(e.getMessage());
err.setPath(request.getRequestURI());
return ResponseEntity.status(status).body(err);
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ValidationError> validation(MethodArgumentNotValidException e, HttpServletRequest request) {
HttpStatus status = HttpStatus.UNPROCESSABLE_ENTITY;
ValidationError err = new ValidationError();
err.setTimestamp(Instant.now());
err.setStatus(status.value());
err.setError("Validation exception");
err.setMessage(e.getMessage());
err.setPath(request.getRequestURI());

for (FieldError f : e.getBindingResult().getFieldErrors()) {
err.addErrors(f.getField(), f.getDefaultMessage());
}

return ResponseEntity.status(status).body(err);
}
}
Loading