Add Service & Controllers Package
This commit is contained in:
@@ -0,0 +1,122 @@
|
|||||||
|
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.controllers;
|
||||||
|
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.ERole;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.Role;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request.LoginRequest;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.request.SignupRequest;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response.MessageResponse;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.payload.response.UserInfoResponse;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.jwt.JwtUtils;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.RoleRepository;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.UserRepository;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service.UserDetailsImpl;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.ResponseCookie;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/auth")
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RoleRepository roleRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
PasswordEncoder encoder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
JwtUtils jwtUtils;
|
||||||
|
|
||||||
|
@PostMapping("/signup")
|
||||||
|
public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
|
||||||
|
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
|
||||||
|
return ResponseEntity.badRequest().body(new MessageResponse("Error: Username is already taken!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
|
||||||
|
return ResponseEntity.badRequest().body(new MessageResponse("Error: Email is already in use!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
User user = new User(signUpRequest.getUsername(),
|
||||||
|
signUpRequest.getEmail(),
|
||||||
|
encoder.encode(signUpRequest.getPassword()));
|
||||||
|
|
||||||
|
Set<String> strRoles = signUpRequest.getRole();
|
||||||
|
Set<Role> roles = new HashSet<>();
|
||||||
|
|
||||||
|
if (strRoles == null) {
|
||||||
|
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||||
|
roles.add(userRole);
|
||||||
|
} else {
|
||||||
|
strRoles.forEach(role -> {
|
||||||
|
if (role.equals("admin")) {
|
||||||
|
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||||
|
roles.add(adminRole);
|
||||||
|
} else {
|
||||||
|
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||||
|
roles.add(userRole);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
user.setRoles(roles);
|
||||||
|
userRepository.save(user);
|
||||||
|
|
||||||
|
return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/signin")
|
||||||
|
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
|
||||||
|
|
||||||
|
Authentication authentication = authenticationManager
|
||||||
|
.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
|
||||||
|
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
|
||||||
|
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
|
||||||
|
|
||||||
|
ResponseCookie jwtCookie = jwtUtils.generateJwtCookie(userDetails);
|
||||||
|
|
||||||
|
List<String> roles = userDetails.getAuthorities().stream()
|
||||||
|
.map(item -> item.getAuthority())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE, jwtCookie.toString())
|
||||||
|
.body(new UserInfoResponse(userDetails.getId(),
|
||||||
|
userDetails.getUsername(),
|
||||||
|
userDetails.getEmail(),
|
||||||
|
roles));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/signout")
|
||||||
|
public ResponseEntity<?> logoutUser() {
|
||||||
|
ResponseCookie cookie = jwtUtils.getCleanJwtCookie();
|
||||||
|
return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE, cookie.toString())
|
||||||
|
.body(new MessageResponse("You've been signed out!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.controllers;
|
||||||
|
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/test")
|
||||||
|
public class TestController {
|
||||||
|
|
||||||
|
@GetMapping("/all")
|
||||||
|
public String allAccess() {
|
||||||
|
return "Public Content.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/user")
|
||||||
|
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
|
||||||
|
public String userAccess() {
|
||||||
|
return "User Content.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/admin")
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
public String adminAccess() {
|
||||||
|
return "Admin Board.";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
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.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class UserDetailsImpl implements UserDetails {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private Collection<? extends GrantedAuthority> authorities;
|
||||||
|
|
||||||
|
public UserDetailsImpl(Long id, String username, String email, String password, Collection<? extends GrantedAuthority> authorities) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.email = email;
|
||||||
|
this.password = password;
|
||||||
|
this.authorities = authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserDetailsImpl build(User user) {
|
||||||
|
List<GrantedAuthority> authorities = user.getRoles().stream()
|
||||||
|
.map(role -> new SimpleGrantedAuthority(role.getName().name()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return new UserDetailsImpl(
|
||||||
|
user.getId(),
|
||||||
|
user.getUsername(),
|
||||||
|
user.getEmail(),
|
||||||
|
user.getPassword(),
|
||||||
|
authorities
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
UserDetailsImpl user = (UserDetailsImpl) o;
|
||||||
|
return Objects.equals(id, user.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.hakimfauzi23.boilerplatespringsecurity.modules.auth.service;
|
||||||
|
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.data.User;
|
||||||
|
import com.hakimfauzi23.boilerplatespringsecurity.modules.auth.repository.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
User user = userRepository.findByUsername(username)
|
||||||
|
.orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
|
||||||
|
|
||||||
|
return UserDetailsImpl.build(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user