Add MapStruct to remove Boilerplate-Code. Adjust Authorization.
This commit is contained in:
parent
f0361c4ed6
commit
e94d23d760
32
pom.xml
32
pom.xml
|
@ -15,6 +15,7 @@
|
|||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
@ -48,6 +49,11 @@
|
|||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||
<version>0.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
@ -64,6 +70,11 @@
|
|||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -71,15 +82,28 @@
|
|||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
<version>1.18.32</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</path>
|
||||
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.springframework.boot.SpringApplication;
|
|||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@SpringBootApplication
|
||||
|
@ -38,11 +37,13 @@ public class Application {
|
|||
CommandLineRunner run() {
|
||||
return args -> {
|
||||
LOG.info("Creating default ADMIN Account.");
|
||||
roleService.init();
|
||||
|
||||
Set<Role> allRoles = roleService.getAllRoles();
|
||||
User adminAccount = userService.createUser("Admin", "Admin", "admin", "admin", allRoles);
|
||||
|
||||
User adminAccount = userService
|
||||
.createUser("Admin",
|
||||
"Admin",
|
||||
"admin",
|
||||
"admin",
|
||||
Set.of(roleService.getDefaultRole(), roleService.getAdminRole()));
|
||||
boolean existingAdminAccount = userService.existsByUsername(adminAccount.getUsername());
|
||||
if (!existingAdminAccount) {
|
||||
LOG.info("Admin Account created.");
|
||||
|
@ -50,7 +51,6 @@ public class Application {
|
|||
} else {
|
||||
LOG.info("Admin Account already exists.");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package de.arminwolf.configs;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
|
|
@ -3,6 +3,7 @@ package de.arminwolf.configs;
|
|||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import de.arminwolf.util.RSAKeyProvider;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
|
@ -13,7 +14,7 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
@AllArgsConstructor
|
||||
@Component
|
||||
public class TokenProvider {
|
||||
public class TokenConfig {
|
||||
|
||||
private final RSAKeyProvider keyProvider;
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
package de.arminwolf.configs;
|
||||
|
||||
import de.arminwolf.Application;
|
||||
import de.arminwolf.exceptions.AppException;
|
||||
import de.arminwolf.models.User;
|
||||
import de.arminwolf.models.dto.RoleDTO;
|
||||
import de.arminwolf.models.dto.UserDTO;
|
||||
import de.arminwolf.services.UserService;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
@ -25,24 +21,19 @@ import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class UserAuthenticationProvider {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(UserAuthenticationProvider.class);
|
||||
|
||||
public static final String ROLES = "roles";
|
||||
public static final String ROLES = "roles";
|
||||
public static final String USERNAME = "username";
|
||||
@Value("${security.jwt.token.issuer:https://armin-wolf.de}")
|
||||
private String issuer;
|
||||
private String issuer;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final UserService userService;
|
||||
|
@ -51,22 +42,20 @@ public class UserAuthenticationProvider {
|
|||
|
||||
|
||||
public Authentication validateToken(final String token) throws MalformedURLException {
|
||||
Jwt decode = jwtDecoder.decode(token);
|
||||
boolean equals = decode.getIssuer().toString().equals(issuer);
|
||||
if (!equals) {
|
||||
Jwt decode = jwtDecoder.decode(token);
|
||||
if (!decode.getIssuer().toString().equals(issuer)) {
|
||||
throw new AppException("Invalid token", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
String username = decode.getClaim(USERNAME);
|
||||
User user = userService.findByUsername(username)
|
||||
User user = userService.findByUsername(decode.getClaim(USERNAME))
|
||||
.orElseThrow(() -> new AppException("User not found", HttpStatus.BAD_REQUEST));
|
||||
|
||||
return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
||||
}
|
||||
|
||||
|
||||
public String createToken(final UserDTO user) {
|
||||
Date now = new Date();
|
||||
Date validity = new Date(now.getTime() + 3600000); // 1 hour
|
||||
Date now = new Date();
|
||||
Date validity = new Date(now.getTime() + TimeUnit.HOURS.toMillis(1));
|
||||
|
||||
JwtClaimsSet jwtClaimsSet = JwtClaimsSet.builder()
|
||||
.issuer(issuer)
|
||||
|
@ -76,6 +65,7 @@ public class UserAuthenticationProvider {
|
|||
.issuedAt(now.toInstant())
|
||||
.build();
|
||||
|
||||
LOG.info("Creating token for user: {}", user.getUsername());
|
||||
JwtEncoderParameters jwtEncoderParameters = JwtEncoderParameters.from(jwtClaimsSet);
|
||||
return jwtEncoder.encode(jwtEncoderParameters).getTokenValue();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
package de.arminwolf.configs;
|
||||
|
||||
import com.nimbusds.jose.jwk.JWK;
|
||||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
import de.arminwolf.util.UserAuthenticationEntryPoint;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -15,11 +10,6 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
|
||||
|
@ -34,7 +24,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi
|
|||
public class WebConfig {
|
||||
|
||||
private final UserAuthenticationEntryPoint userAuthenticationEntryPoint;
|
||||
private final UserAuthenticationProvider userAuthenticationProvider;
|
||||
private final UserAuthenticationProvider userAuthenticationProvider;
|
||||
|
||||
|
||||
|
||||
|
@ -47,6 +37,10 @@ public class WebConfig {
|
|||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests((requests) -> requests
|
||||
.requestMatchers(HttpMethod.POST, "/login", "/register").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/public/**").permitAll()
|
||||
.requestMatchers("/api/**").hasRole("ADMIN")
|
||||
.requestMatchers("/admin/**").hasRole("ADMIN")
|
||||
.requestMatchers("/user/**").hasAnyRole("ADMIN", "USER")
|
||||
.anyRequest().authenticated());
|
||||
return http.build();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
package de.arminwolf.controllers;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
@RequestMapping("/admin/")
|
||||
public class AdminAccessController {
|
||||
|
||||
@GetMapping("/admin")
|
||||
@RolesAllowed("ADMIN")
|
||||
@GetMapping("/")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<String> admin() {
|
||||
return ResponseEntity.ok("Admin access granted");
|
||||
}
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
package de.arminwolf.controllers;
|
||||
|
||||
import de.arminwolf.models.dto.LoginRequestDTO;
|
||||
import de.arminwolf.models.dto.RegisterRequestDTO;
|
||||
import de.arminwolf.models.dto.RegistrationRequestDTO;
|
||||
import de.arminwolf.models.dto.UserDTO;
|
||||
import de.arminwolf.services.AuthenticationService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
|
@ -20,7 +19,6 @@ public class AuthenticationController {
|
|||
|
||||
private final AuthenticationService authenticationService;
|
||||
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<UserDTO> login(@RequestBody LoginRequestDTO loginRequestDTO) {
|
||||
return ResponseEntity.ok(authenticationService.login(loginRequestDTO));
|
||||
|
@ -28,7 +26,7 @@ public class AuthenticationController {
|
|||
|
||||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<UserDTO> register(@RequestBody RegisterRequestDTO registerRequestDTO) {
|
||||
public ResponseEntity<UserDTO> register(@RequestBody RegistrationRequestDTO registerRequestDTO) {
|
||||
UserDTO registeredUser = authenticationService.register(registerRequestDTO);
|
||||
return ResponseEntity
|
||||
.created(URI.create("/users/" + registeredUser.getId()))
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
package de.arminwolf.controllers;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@PreAuthorize("hasAnyRole(['USER', 'ADMIN'])")
|
||||
@RequestMapping("/user/")
|
||||
public class UserAccessController {
|
||||
|
||||
@GetMapping("/user")
|
||||
@RolesAllowed({ "USER", "ADMIN" })
|
||||
@GetMapping("/")
|
||||
public ResponseEntity<String> user() {
|
||||
return ResponseEntity.ok("User access granted");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package de.arminwolf.exceptions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
|
||||
|
|
|
@ -8,20 +8,20 @@ import jakarta.persistence.GeneratedValue;
|
|||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import lombok.Setter;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static jakarta.persistence.FetchType.LAZY;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Table(name = "app_users")
|
||||
@Data
|
||||
|
@ -35,12 +35,17 @@ public class User implements UserDetails {
|
|||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "user_id")
|
||||
private Long id;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
@Column(name = "first_name")
|
||||
private String firstName;
|
||||
|
||||
@Column(name = "last_name")
|
||||
private String lastName;
|
||||
|
||||
private String email;
|
||||
|
||||
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
|
@ -51,11 +56,13 @@ public class User implements UserDetails {
|
|||
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return getRoles();
|
||||
public List<SimpleGrantedAuthority> getAuthorities() {
|
||||
return getRoles()
|
||||
.stream()
|
||||
.map(role -> new SimpleGrantedAuthority("ROLE_".concat(role.getName())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package de.arminwolf.models.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class LoginRequestDTO {
|
||||
|
||||
private String username;
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package de.arminwolf.models.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class RegisterRequestDTO {
|
||||
public class RegistrationRequestDTO {
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String username;
|
||||
private String email;
|
||||
private String password;
|
||||
}
|
|
@ -13,11 +13,12 @@ import java.util.Set;
|
|||
@Builder
|
||||
public class UserDTO {
|
||||
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String username;
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String username;
|
||||
private String token;
|
||||
private String email;
|
||||
private Set<RoleDTO> roles;
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package de.arminwolf.models.mapper;
|
||||
|
||||
|
||||
import de.arminwolf.models.User;
|
||||
import de.arminwolf.models.dto.RegistrationRequestDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Mapper(componentModel = "spring")
|
||||
public abstract class RegistrationMapper {
|
||||
|
||||
@Autowired
|
||||
protected PasswordEncoder passwordEncoder;
|
||||
|
||||
|
||||
@Mapping(target = "password", qualifiedByName ="passwordMapping")
|
||||
public abstract User registrationRequestDTOToUser(RegistrationRequestDTO registrationRequestDTO);
|
||||
|
||||
|
||||
@Named("passwordMapping")
|
||||
String passwordMapping(String password) {
|
||||
return this.passwordEncoder.encode(password);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package de.arminwolf.models.mapper;
|
||||
|
||||
import de.arminwolf.models.Role;
|
||||
import de.arminwolf.models.dto.RoleDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
|
||||
@Mapper(componentModel = "spring",
|
||||
unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface RoleMapper {
|
||||
|
||||
|
||||
RoleDTO roleToRoleDTO(Role role);
|
||||
|
||||
Role roleDTOToRole(RoleDTO roleDTO);
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package de.arminwolf.models.mapper;
|
||||
|
||||
import de.arminwolf.models.User;
|
||||
import de.arminwolf.models.dto.UserDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper(componentModel = "spring",
|
||||
unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface UserMapper {
|
||||
|
||||
UserDTO userToUserDTO(User user);
|
||||
|
||||
User userDTOToUser(UserDTO userDTO);
|
||||
}
|
|
@ -2,67 +2,57 @@ package de.arminwolf.services;
|
|||
|
||||
import de.arminwolf.configs.UserAuthenticationProvider;
|
||||
import de.arminwolf.exceptions.AppException;
|
||||
import de.arminwolf.models.Role;
|
||||
import de.arminwolf.models.User;
|
||||
import de.arminwolf.models.dto.LoginRequestDTO;
|
||||
import de.arminwolf.models.dto.RegisterRequestDTO;
|
||||
import de.arminwolf.models.dto.RoleDTO;
|
||||
import de.arminwolf.models.dto.RegistrationRequestDTO;
|
||||
import de.arminwolf.models.dto.UserDTO;
|
||||
import de.arminwolf.models.mapper.RegistrationMapper;
|
||||
import de.arminwolf.models.mapper.UserMapper;
|
||||
import de.arminwolf.repositories.RoleRepository;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
public class AuthenticationService {
|
||||
|
||||
private final UserService userService;
|
||||
private final UserAuthenticationProvider userAuthenticationProvider;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final RoleRepository roleRepository;
|
||||
private final UserService userService;
|
||||
|
||||
private final UserAuthenticationProvider userAuthenticationProvider;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final RoleRepository roleRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private RegistrationMapper registrationMapper;
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
public UserDTO login(LoginRequestDTO loginRequestDTO) {
|
||||
UserDTO userDTO = userService.login(loginRequestDTO.getUsername(), loginRequestDTO.getPassword());
|
||||
final String token = userAuthenticationProvider.createToken(userDTO);
|
||||
userDTO.setToken(token);
|
||||
userDTO.setToken(userAuthenticationProvider.createToken(userDTO));
|
||||
return userDTO;
|
||||
}
|
||||
|
||||
|
||||
public UserDTO register(final RegisterRequestDTO registerRequestDTO) {
|
||||
public UserDTO register(final RegistrationRequestDTO registerRequestDTO) {
|
||||
boolean userExists = userService.existsByUsername(registerRequestDTO.getUsername());
|
||||
if (userExists) {
|
||||
throw new AppException("User already exists", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
User createdUser = User.builder().email(registerRequestDTO.getEmail())
|
||||
.firstName(registerRequestDTO.getFirstName())
|
||||
.lastName(registerRequestDTO.getLastName())
|
||||
.username(registerRequestDTO.getUsername())
|
||||
.password(passwordEncoder.encode(registerRequestDTO.getPassword()))
|
||||
.roles(Set.of(roleRepository.findByName("USER")))
|
||||
.build();
|
||||
// save user
|
||||
User user = registrationMapper.registrationRequestDTOToUser(registerRequestDTO);
|
||||
user.setRoles(userService.getDefaultRoles());
|
||||
userService.save(user);
|
||||
|
||||
User savedUser = userService.save(createdUser);
|
||||
Set<Role> roles = savedUser.getRoles();
|
||||
Set<RoleDTO> roleDTO = roles.stream()
|
||||
.map(role -> new RoleDTO(role.getId(), role.getName()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
UserDTO userDTO = new UserDTO(savedUser.getId(),
|
||||
savedUser.getFirstName(),
|
||||
savedUser.getLastName(),
|
||||
savedUser.getUsername(),
|
||||
null, roleDTO);
|
||||
|
||||
final String token = userAuthenticationProvider.createToken(userDTO);
|
||||
userDTO.setToken(token);
|
||||
// convert the latest user to a userDTO
|
||||
final UserDTO userDTO = userMapper.userToUserDTO(user);
|
||||
userDTO.setToken(userAuthenticationProvider.createToken(userDTO));
|
||||
return userDTO;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.springframework.data.util.Optionals.ifPresentOrElse;
|
||||
|
||||
@Service
|
||||
public class RoleService {
|
||||
|
||||
|
@ -24,21 +21,31 @@ public class RoleService {
|
|||
return new HashSet<>(repository.findAll());
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void init() {
|
||||
public Role getDefaultRole() {
|
||||
Role user = repository.findByName("USER");
|
||||
if (Objects.isNull(user)) {
|
||||
user = Role.builder().name("USER").build();
|
||||
repository.save(user);
|
||||
if (Objects.nonNull(user)) {
|
||||
return user;
|
||||
} else {
|
||||
return createRoleByName("USER");
|
||||
}
|
||||
}
|
||||
|
||||
public Role getAdminRole() {
|
||||
Role admin = repository.findByName("ADMIN");
|
||||
if (Objects.isNull(admin)) {
|
||||
admin = Role.builder().name("ADMIN").build();
|
||||
repository.save(admin);
|
||||
if (Objects.nonNull(admin)) {
|
||||
return admin;
|
||||
} else {
|
||||
return createRoleByName("ADMIN");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
private Role createRoleByName(final String name) {
|
||||
Role role = Role.builder().name(name).build();
|
||||
repository.save(role);
|
||||
return role;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,14 +5,19 @@ import de.arminwolf.models.Role;
|
|||
import de.arminwolf.models.User;
|
||||
import de.arminwolf.models.dto.RoleDTO;
|
||||
import de.arminwolf.models.dto.UserDTO;
|
||||
import de.arminwolf.models.mapper.RoleMapper;
|
||||
import de.arminwolf.models.mapper.UserMapper;
|
||||
import de.arminwolf.repositories.RoleRepository;
|
||||
import de.arminwolf.repositories.UserRepository;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -22,8 +27,17 @@ import java.util.stream.Collectors;
|
|||
public class UserService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final RoleRepository roleRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Autowired
|
||||
private RoleMapper roleMapper;
|
||||
|
||||
|
||||
|
||||
|
||||
public User createUser(final String firstName, final String lastName, final String username, final String password, final Set<Role> allRoles) {
|
||||
return User.builder().id(0L).email("")
|
||||
|
@ -45,11 +59,23 @@ public class UserService {
|
|||
}
|
||||
|
||||
|
||||
public Set<Role> getDefaultRoles() {
|
||||
Role user = roleRepository.findByName("USER");
|
||||
if (Objects.nonNull(user)) {
|
||||
return Set.of(user);
|
||||
} else {
|
||||
Role role = Role.builder().name("USER").build();
|
||||
return Set.of(roleRepository.save(role));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public UserDTO login(final String username, final String password) {
|
||||
User user = userRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new AppException("Unknown user", HttpStatus.NOT_FOUND));
|
||||
|
||||
if (passwordEncoder.matches(CharBuffer.wrap(password), user.getPassword())) {
|
||||
/*
|
||||
Set<Role> roles = user.getRoles();
|
||||
Set<RoleDTO> roleDTO = roles.stream()
|
||||
.map(role -> new RoleDTO(role.getId(), role.getName()))
|
||||
|
@ -60,6 +86,9 @@ public class UserService {
|
|||
user.getLastName(),
|
||||
user.getUsername(),
|
||||
null, roleDTO);
|
||||
*/
|
||||
return userMapper.userToUserDTO(user);
|
||||
|
||||
}
|
||||
|
||||
throw new AppException("Invalid password", HttpStatus.BAD_REQUEST);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package de.arminwolf.configs;
|
||||
package de.arminwolf.util;
|
||||
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.security.KeyPair;
|
|
@ -1,4 +1,4 @@
|
|||
package de.arminwolf.configs;
|
||||
package de.arminwolf.util;
|
||||
|
||||
import de.arminwolf.exceptions.AppException;
|
||||
import de.arminwolf.models.dto.ErrorDTO;
|
|
@ -1,4 +1,4 @@
|
|||
package de.arminwolf.configs;
|
||||
package de.arminwolf.util;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import de.arminwolf.models.dto.ErrorDTO;
|
Loading…
Reference in New Issue