Reputation: 155
I'm trying to change password of current logged in user. Any idea, why is it adding another row with the same columns except password that has been changed? May be i'm using the wrong method?
There is my controller MainController.java
@RestController
public class MainController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private JwtUtil jwtTokenUtil;
// Change the password
@RequestMapping(value = "/settings", method = RequestMethod.PUT)
public String updatePassword(@AuthenticationPrincipal MyUserDetails myUserDetails,
@RequestBody UserCredentialsPojo pojo,
Users users) {
return myUserDetailsService.changePassword(users, myUserDetails,
pojo.getNewPassword(), pojo.getNewPassword1(), pojo.getOldPassword());
}
// Authentication with jwt token
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
);
} catch (BadCredentialsException e) {
throw new Exception("Incorrect username and password", e);
}
final UserDetails userDetails = myUserDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String jwt = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(jwt));
}
}
UsersEntity.java
@Entity
@Table(name = "users")
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@Column(name = "username", length = 255)
private String username;
@Column(name = "firstname", length = 255)
private String firstname;
@Column(name = "lastname", length = 255)
private String lastname;
@Column(name = "password", length = 255)
private String password;
@Column(name = "roles", length = 255)
private String roles;
@Column(name = "email", length = 255)
private String email;
@Column(name = "lastLoginDate", length = 255)
private String lastLoginDate;
@Column(name = "registrationDate", length = 255)
private String registrationDate;
@Column(name = "lastLoginIp", length = 255)
private String lastLoginIp;
@Column(name = "balance")
private Integer balance;
@Column(name = "status")
private Integer status;
@Column(name = "birthDate", length = 255)
private String birthDate;
@Column(name = "departmentId")
private Integer departmentId;
@Column(name = "facultyId")
private Integer facultyId;
@Column(name = "advisorId")
private Integer advisorId;
// Getters and setters without constructor..
Here is MyUserDetails that extends UserDetails MyUserDetails.java.
public class MyUserDetails implements UserDetails {
private Integer id;
private String username;
private String firstname;
private String lastname;
private String password;
private List<GrantedAuthority> authorities;
private String email;
private String lastLoginDate;
private String registrationDate;
private String lastLoginIp;
private Integer balance;
private Integer status;
private String birthDate;
private Integer departmentId;
private Integer facultyId;
private Integer advisorId;
public MyUserDetails(Users user) {
this.id = user.getId();
this.username = user.getUsername();
this.firstname = user.getFirstname();
this.lastname = user.getLastname();
this.password = user.getPassword();
this.authorities = Arrays.stream(user.getRoles().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
this.email = user.getEmail();
this.lastLoginDate = user.getLastLoginDate();
this.registrationDate = user.getRegistrationDate();
this.lastLoginIp = user.getLastLoginIp();
this.balance = user.getBalance();
this.status = user.getStatus();
this.birthDate = user.getBirthDate();
this.departmentId = user.getDepartmentId();
this.facultyId = user.getFacultyId();
this.advisorId = user.getAdvisorId();
}
public MyUserDetails() {
}
// Getters and setters..
UsersRepository.java
public interface UserRepository extends JpaRepository<Users, Integer> {
Optional<Users> findByUsername(String username);
}
MyUserDetailsService.java
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
// Change user password
public String changePassword(Users users, MyUserDetails myUserDetails, String newPassword, String newPassword1, String oldPassword) {
if (oldPassword.equals(myUserDetails.getPassword())) {
if (oldPassword.equals(newPassword)) {
return "New password cannot be the same as the old";
} else if (!newPassword.equals(newPassword1)) {
return "Passwords mismatches";
} else if (newPassword.length() < 8) {
return "New password too short";
} else if (!newPassword.matches(".*")) {
return "New password must contain at least 1 number";
} else {
users.setFirstname(myUserDetails.getFirstname());
users.setLastname(myUserDetails.getLastname());
users.setPassword(newPassword);
users.setRoles(String.valueOf(myUserDetails.getAuthorities()));
users.setEmail(myUserDetails.getEmail());
users.setLastLoginDate(myUserDetails.getLastLoginDate());
users.setRegistrationDate(myUserDetails.getRegistrationDate());
users.setLastLoginIp(myUserDetails.getLastLoginIp());
users.setBalance(myUserDetails.getBalance());
users.setStatus(myUserDetails.getStatus());
users.setBirthDate(myUserDetails.getBirthDate());
users.setFacultyId(myUserDetails.getFacultyId());
users.setAdvisorId(myUserDetails.getAdvisorId());
users.setUsername(myUserDetails.getUsername());
users.setDepartmentId(myUserDetails.getDepartmentId());
userRepository.save(users);
return "Password has been successfully changed";
}
} else {
return "Password is wrong";
}
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<Users> user = userRepository.findByUsername(username);
user.orElseThrow(() -> new UsernameNotFoundException("Not found: " + username));
return user.map(MyUserDetails::new).get();
}
}
Users table
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
| id | firstname | lastname | password | roles | email | lastLoginDate | registrationDate | lastLoginIp | balance | status | birthDate | facultyId | advisorId | username | departmentId |
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
| 2 | damir | esenov | admin | student | damir | NULL | NULL | NULL | NULL | NULL | NULL | 1 | 1 | admin | 1 |
| 3 | rapkat | baudunov | rapkat | NULL | rapkat | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | rapkat | NULL |
| 15 | damir | esenov | admin123 | [student] | damir | NULL | NULL | NULL | NULL | NULL | NULL | 1 | 1 | admin | 1 |
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
My request in PostMan (I've changed the request to PUT method) Postman
{
"oldPassword":"admin",
"newPassword":"admin123",
"newPassword1":"admin123"
}
Upvotes: 0
Views: 2469
Reputation: 18410
Since id
for users
is null so JPA treats as new user that why create a new row in database. So just set id
of users
inside else
users.setId(myUserDetails.getId());
Better solution:
You don't need to set all the field if you need only to change password. First get the user by id then set the password and save.
users = userRepository.findById(myUserDetails.getId()).get();
users.setPassword(newPassword);
userRepository.save(users);
Upvotes: 1