-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathUserDto.java
More file actions
135 lines (119 loc) · 4.17 KB
/
Copy pathUserDto.java
File metadata and controls
135 lines (119 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.digitalsanctuary.spring.user.dto;
import com.digitalsanctuary.spring.user.util.PasswordSecurityUtil;
import com.digitalsanctuary.spring.user.validation.PasswordMatches;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.ToString;
/**
* A user dto. This object is used for handling user related form data (registration, forms passing in email addresses,
* etc...).
*
* <p>Note: This DTO supports both String and char[] for passwords. The char[] methods are preferred
* for enhanced security as they allow explicit memory clearing. String methods are maintained
* for backward compatibility.
*/
@Data
@PasswordMatches
public class UserDto implements AutoCloseable {
/** The first name. */
@NotBlank(message = "First name is required")
@Size(max = 50, message = "First name must not exceed 50 characters")
private String firstName;
/** The last name. */
@NotBlank(message = "Last name is required")
@Size(max = 50, message = "Last name must not exceed 50 characters")
private String lastName;
/** The password. */
@ToString.Exclude
@NotBlank(message = "Password is required")
@Size(min = 8, max = 128, message = "Password must be between 8 and 128 characters")
private String password;
/** The matching password. */
@ToString.Exclude
@NotBlank(message = "Password confirmation is required")
private String matchingPassword;
/** The email. */
@NotBlank(message = "Email is required")
@Email(message = "Please provide a valid email address")
@Size(max = 100, message = "Email must not exceed 100 characters")
private String email;
/** The role. */
private Integer role;
/** The password as char array (for secure handling). */
@ToString.Exclude
private transient char[] passwordChars;
/** The matching password as char array (for secure handling). */
@ToString.Exclude
private transient char[] matchingPasswordChars;
/**
* Gets the password as a char array for secure handling.
* If passwordChars is null but password is set, converts from String.
*
* @return the password as char array, or null if not set
*/
public char[] getPasswordChars() {
if (passwordChars == null && password != null) {
return PasswordSecurityUtil.toCharArray(password);
}
return passwordChars;
}
/**
* Sets the password from a char array (preferred for security).
* Also updates the String password field for backward compatibility.
*
* @param passwordChars the password as char array
*/
public void setPasswordChars(char[] passwordChars) {
this.passwordChars = passwordChars;
if (passwordChars != null) {
this.password = PasswordSecurityUtil.toString(passwordChars);
} else {
this.password = null;
}
}
/**
* Gets the matching password as a char array for secure handling.
* If matchingPasswordChars is null but matchingPassword is set, converts from String.
*
* @return the matching password as char array, or null if not set
*/
public char[] getMatchingPasswordChars() {
if (matchingPasswordChars == null && matchingPassword != null) {
return PasswordSecurityUtil.toCharArray(matchingPassword);
}
return matchingPasswordChars;
}
/**
* Sets the matching password from a char array (preferred for security).
* Also updates the String matchingPassword field for backward compatibility.
*
* @param matchingPasswordChars the matching password as char array
*/
public void setMatchingPasswordChars(char[] matchingPasswordChars) {
this.matchingPasswordChars = matchingPasswordChars;
if (matchingPasswordChars != null) {
this.matchingPassword = PasswordSecurityUtil.toString(matchingPasswordChars);
} else {
this.matchingPassword = null;
}
}
/**
* Clears sensitive password data from memory.
* This method should be called in a finally block to ensure passwords are cleared.
*/
public void clearPasswords() {
PasswordSecurityUtil.clearPassword(passwordChars);
PasswordSecurityUtil.clearPassword(matchingPasswordChars);
passwordChars = null;
matchingPasswordChars = null;
}
/**
* Closes this resource, clearing password data from memory.
*/
@Override
public void close() {
clearPasswords();
}
}