change user and pass

This commit is contained in:
Anthony Stirling
2023-08-15 00:39:13 +01:00
parent d7307665b3
commit 86f71ffb93
10 changed files with 125 additions and 34 deletions

View File

@@ -20,9 +20,9 @@ public class InitialSetup {
if(initialUsername != null && initialPassword != null) {
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
}
// else {
// userService.saveUser("admin", "password", Role.ADMIN.getRoleId());
// }
else {
userService.saveUser("admin", "password", Role.ADMIN.getRoleId());
}
}
}
}

View File

@@ -134,7 +134,7 @@ public class UserService {
}
public boolean usernameExists(String username) {
return userRepository.findByUsername(username) != null;
return userRepository.findByUsername(username).isPresent();
}
public boolean hasUsers() {
@@ -158,5 +158,21 @@ public class UserService {
}
}
public Optional<User> findByUsername(String username) {
return userRepository.findByUsername(username);
}
public void changeUsername(User user, String newUsername) {
user.setUsername(newUsername);
userRepository.save(user);
}
public void changePassword(User user, String newPassword) {
user.setPassword(passwordEncoder.encode(newPassword));
userRepository.save(user);
}
public boolean isPasswordCorrect(User user, String currentPassword) {
return passwordEncoder.matches(currentPassword, user.getPassword());
}
}

View File

@@ -3,6 +3,7 @@ package stirling.software.SPDF.controller.api;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -17,8 +18,11 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.model.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
@Controller
public class UserController {
@@ -26,6 +30,9 @@ public class UserController {
@Autowired
private UserService userService;
@Autowired
private PasswordEncoder passwordEncoder;
@PostMapping("/register")
public String register(@RequestParam String username, @RequestParam String password, Model model) {
if(userService.usernameExists(username)) {
@@ -37,6 +44,59 @@ public class UserController {
return "redirect:/login?registered=true";
}
@PostMapping("/change-username")
public ResponseEntity<String> changeUsername(Principal principal, @RequestParam String currentPassword, @RequestParam String newUsername, HttpServletRequest request, HttpServletResponse response) {
if (principal == null) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("User not authenticated.");
}
Optional<User> userOpt = userService.findByUsername(principal.getName());
if(userOpt == null || userOpt.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found.");
}
User user = userOpt.get();
if(!userService.isPasswordCorrect(user, currentPassword)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Current password is incorrect.");
}
if(userService.usernameExists(newUsername)) {
return ResponseEntity.status(HttpStatus.CONFLICT).body("New username already exists.");
}
userService.changeUsername(user, newUsername);
// Logout using Spring's utility
new SecurityContextLogoutHandler().logout(request, response, null);
return ResponseEntity.ok("Username updated successfully.");
}
@PostMapping("/change-password")
public ResponseEntity<String> changePassword(Principal principal, @RequestParam String currentPassword, @RequestParam String newPassword, HttpServletRequest request, HttpServletResponse response) {
if (principal == null) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("User not authenticated.");
}
Optional<User> userOpt = userService.findByUsername(principal.getName());
if(userOpt == null || userOpt.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found.");
}
User user = userOpt.get();
if(!userService.isPasswordCorrect(user, currentPassword)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Current password is incorrect.");
}
userService.changePassword(user, passwordEncoder.encode(newPassword));
// Logout using Spring's utility
new SecurityContextLogoutHandler().logout(request, response, null);
return ResponseEntity.ok("Password updated successfully.");
}
@PostMapping("/updateUserSettings")
public String updateUserSettings(HttpServletRequest request, Principal principal) {

View File

@@ -33,7 +33,7 @@ public class Authority {
private String authority;
@ManyToOne
@JoinColumn(name = "username")
@JoinColumn(name = "user_id")
private User user;
public Long getId() {

View File

@@ -9,6 +9,8 @@ import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.OneToMany;
@@ -21,8 +23,12 @@ import java.util.HashSet;
@Table(name = "users")
public class User {
@Id
@Column(name = "username")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "username", unique = true)
private String username;
@Column(name = "password")
@@ -40,11 +46,19 @@ public class User {
@ElementCollection
@MapKeyColumn(name = "setting_key")
@Column(name = "setting_value")
@CollectionTable(name = "user_settings", joinColumns = @JoinColumn(name = "username"))
@CollectionTable(name = "user_settings", joinColumns = @JoinColumn(name = "user_id"))
private Map<String, String> settings = new HashMap<>(); // Key-value pairs of settings.
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getApiKey() {
return apiKey;
}