Skip to content

Commit fa7defe

Browse files
author
noobandy
committed
Password reset form is now protected with captcha.
1 parent 82e2806 commit fa7defe

File tree

21 files changed

+483
-155
lines changed

21 files changed

+483
-155
lines changed

pom.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,10 @@
255255
<artifactId>velocity</artifactId>
256256
<version>1.7</version>
257257
</dependency>
258-
259-
258+
<!-- Commons -->
259+
<groupId>org.apache.commons</groupId>
260+
<artifactId>commons-lang3</artifactId>
261+
<version>3.3.2</version>
260262
<!-- Test -->
261263
<dependency>
262264
<groupId>junit</groupId>

src/main/java/in/anandm/apps/template/domain/model/user/IFailedLoginRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55

66
import java.util.List;
77

8+
import org.springframework.transaction.annotation.Transactional;
9+
810
/**
911
* @author anandm
1012
*
1113
*/
1214
public interface IFailedLoginRepository {
1315

16+
@Transactional
1417
void saveFailedLogin(FailedLogin failedLogin);
1518

1619
List<FailedLogin> getFailedLoginofUserWithId(String userId);

src/main/java/in/anandm/apps/template/domain/model/user/IPasswordResetRequestRepository.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,24 @@
33
*/
44
package in.anandm.apps.template.domain.model.user;
55

6+
import java.util.List;
7+
8+
import org.springframework.transaction.annotation.Transactional;
9+
610

711
/**
812
* @author anandm
913
*
1014
*/
1115
public interface IPasswordResetRequestRepository {
1216

17+
@Transactional
1318
void savePasswordResetRequest(PasswordResetRequest passwordResetRequest);
19+
20+
PasswordResetRequest getPasswordResetRequestById(Long id);
21+
22+
List<PasswordResetRequest> getAllPasswordRequestOfUser(String userId);
23+
1424

15-
PasswordResetRequest getPasswordResetRequestByKey(String resetKey);
1625

1726
}

src/main/java/in/anandm/apps/template/domain/model/user/ISuccessfullLoginRepository.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55

66
import java.util.List;
77

8+
import org.springframework.transaction.annotation.Transactional;
9+
810
/**
911
* @author anandm
1012
*
1113
*/
1214
public interface ISuccessfullLoginRepository {
1315

16+
@Transactional
1417
void saveSuccessfullLogin(SuccessfullLogin successfullLogin);
15-
18+
1619
List<SuccessfullLogin> getSuccessfullLoginofUserWithId(String userId);
1720
}

src/main/java/in/anandm/apps/template/domain/model/user/IUserRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77

88
import java.util.Map;
99

10+
import org.springframework.transaction.annotation.Transactional;
11+
1012
/**
1113
* @author anandm
1214
*
1315
*/
1416
public interface IUserRepository {
1517

18+
@Transactional
1619
void saveUser(User user);
20+
1721
User getUserByUserId(String userId);
1822
User getUserByVerificationKey(String verificationKey);
1923
DataTable<User> getDataTable(Map<String, String> params);

src/main/java/in/anandm/apps/template/domain/model/user/IUserSessionRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55

66
import java.util.List;
77

8+
import org.springframework.transaction.annotation.Transactional;
9+
810
/**
911
* @author anandm
1012
*
1113
*/
1214
public interface IUserSessionRepository {
1315

16+
@Transactional
1417
void saveUserSession(UserSession userSession);
1518

1619
List<UserSession> getUserSessionofUserWithId(String userId);

src/main/java/in/anandm/apps/template/domain/model/user/PasswordResetRequest.java

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@
33
*/
44
package in.anandm.apps.template.domain.model.user;
55

6+
import in.anandm.apps.template.interfaces.web.helper.HashingUtility;
7+
8+
import java.util.UUID;
9+
610
import javax.persistence.Embedded;
711
import javax.persistence.Entity;
812
import javax.persistence.GeneratedValue;
913
import javax.persistence.GenerationType;
1014
import javax.persistence.Id;
1115
import javax.persistence.ManyToOne;
1216

17+
import org.apache.commons.lang.Validate;
18+
1319
/**
1420
* @author anandm
1521
*
@@ -34,14 +40,48 @@ public class PasswordResetRequest {
3440
* @param hostAddress
3541
* @param user
3642
*/
37-
public PasswordResetRequest(String resetKey, Long initiatedOn,
38-
HostAddress hostAddress, User user) {
43+
public PasswordResetRequest(User user,HostAddress hostAddress) {
3944
super();
40-
this.resetKey = resetKey;
41-
this.initiatedOn = initiatedOn;
4245
this.hostAddress = hostAddress;
4346
this.user = user;
4447
}
48+
49+
public String initiateRequest(){
50+
String newResetKey = UUID.randomUUID().toString();
51+
String hashedKey = HashingUtility.sha512Hash(newResetKey);
52+
53+
resetKey = hashedKey;
54+
initiatedOn = System.currentTimeMillis();
55+
56+
return newResetKey;
57+
58+
}
59+
60+
private boolean isExpired(){
61+
return (expiredOn != null && expiredOn < System.currentTimeMillis());
62+
}
63+
64+
65+
public void resetPassword(String resetKey,String newPassword){
66+
Validate.notEmpty(resetKey, "resetKey is empty");
67+
Validate.notEmpty(newPassword, "newPassword is empty");
68+
69+
if(isExpired()){
70+
throw new IllegalStateException("Request is expired");
71+
}
72+
String hashedResetKey = HashingUtility.sha512Hash(resetKey);
73+
if(this.resetKey.equals(hashedResetKey)){
74+
user.changePassword(newPassword);
75+
expiredOn = System.currentTimeMillis();
76+
}else{
77+
throw new IllegalArgumentException("Invalid resetKey");
78+
}
79+
80+
81+
82+
}
83+
84+
4585
public String getResetKey() {
4686
return resetKey;
4787
}
@@ -59,17 +99,6 @@ public User getUser() {
5999
}
60100

61101

62-
public boolean isExpired(){
63-
return (expiredOn != null && expiredOn < System.currentTimeMillis());
64-
}
65-
66-
public void expire(){
67-
this.expiredOn = System.currentTimeMillis();
68-
}
69-
public boolean verify(String resetKey){
70-
return this.resetKey.equals(resetKey);
71-
}
72-
73102
@Id
74103
@GeneratedValue(strategy=GenerationType.AUTO)
75104
private Long id;

src/main/java/in/anandm/apps/template/domain/model/user/User.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,34 @@ public User(UserAccount userAccount, UserProfile userProfile) {
4949
}
5050

5151

52+
public boolean isUserAccountVerified(){
53+
return userAccount.isVerified();
54+
}
55+
56+
public String requestVerification(){
57+
return userAccount.requestVerification();
58+
}
59+
60+
public void verify(String verificationKey){
61+
userAccount.verify(verificationKey);
62+
63+
}
64+
65+
public boolean isAdmin(){
66+
return userAccount.getAdmin();
67+
}
68+
69+
public void changePassword(String newPassword){
70+
userAccount.changePassword(newPassword);
71+
}
72+
73+
public boolean isEnabled(){
74+
return userAccount.getEnabled();
75+
}
76+
77+
public boolean isExpired(){
78+
return userAccount.isExpired();
79+
}
5280

5381
public List<PasswordResetRequest> getPasswordResetRequests() {
5482
return passwordResetRequests;

src/main/java/in/anandm/apps/template/domain/model/user/UserAccount.java

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
*/
44
package in.anandm.apps.template.domain.model.user;
55

6+
import in.anandm.apps.template.interfaces.web.helper.HashingUtility;
7+
68
import java.io.Serializable;
9+
import java.util.UUID;
710

811
import javax.persistence.Embeddable;
912

13+
import org.apache.commons.lang.Validate;
14+
1015
/**
1116
* @author noobandy
1217
*
@@ -28,17 +33,81 @@ public class UserAccount implements Serializable {
2833
private String verificationKey;
2934
private Long verifiedOn;
3035

31-
public UserAccount(String userId,String password, Boolean admin,
32-
Long expireOn,String verificationKey) {
36+
public UserAccount(String userId,String password) {
3337
super();
38+
Validate.notEmpty(userId, "userId is empty");
39+
40+
Validate.notEmpty(password, "password is empty");
41+
42+
3443
this.userId = userId;
35-
this.password = password;
36-
this.admin = admin;
37-
this.expireOn = expireOn;
38-
this.verificationKey = verificationKey;
44+
45+
Validate.notEmpty(password, "password is empty");
46+
String saltedPassword = password + "{" + userId + "}";
47+
String hashedPassword = HashingUtility.sha512Hash(saltedPassword);
48+
this.password = hashedPassword;
49+
50+
this.admin = false;
51+
this.expireOn = null;
3952
this.enabled = false;
4053
}
4154

55+
56+
void makeAdmin(){
57+
admin = true;
58+
}
59+
60+
void makeNonAdmin(){
61+
admin = false;
62+
}
63+
void enable(){
64+
enabled = true;
65+
}
66+
67+
void disable(){
68+
enabled = false;
69+
}
70+
71+
void changePassword(String newPassword){
72+
Validate.notEmpty(newPassword, "password is empty");
73+
String saltedPassword = newPassword + "{" + userId + "}";
74+
String hashedPassword = HashingUtility.sha512Hash(saltedPassword);
75+
password = hashedPassword;
76+
}
77+
78+
String requestVerification(){
79+
if(isVerified()){
80+
throw new IllegalStateException("User Account is already verified");
81+
}
82+
String newVerificationKey = UUID.randomUUID().toString();
83+
String hashedKey = HashingUtility.sha512Hash(newVerificationKey);
84+
this.verificationKey = hashedKey;
85+
return newVerificationKey;
86+
}
87+
88+
boolean isVerified(){
89+
return verifiedOn != null;
90+
}
91+
92+
void verify(String verificationKey){
93+
Validate.notEmpty(verificationKey, "verificationKey is empty");
94+
95+
if(isVerified()){
96+
throw new IllegalStateException("User Account is already verified");
97+
}
98+
99+
String hashedVerificationKey = HashingUtility.sha512Hash(verificationKey);
100+
101+
if(this.verificationKey.equals(hashedVerificationKey)){
102+
enabled = true;
103+
verifiedOn = System.currentTimeMillis();
104+
}
105+
}
106+
107+
boolean isExpired(){
108+
return (expireOn != null && expireOn < System.currentTimeMillis());
109+
}
110+
42111
public String getUserId() {
43112
return userId;
44113
}
@@ -67,25 +136,6 @@ public Long getVerifiedOn() {
67136
return verifiedOn;
68137
}
69138

70-
public void changePassword(String newPassword){
71-
this.password = newPassword;
72-
}
73-
74-
public boolean isExpired(){
75-
return (expireOn != null && expireOn < System.currentTimeMillis());
76-
}
77-
78-
public void verify(String verificationKey){
79-
if(String.valueOf(this.verificationKey).equals(verificationKey)){
80-
this.verifiedOn = System.currentTimeMillis();
81-
this.enabled = Boolean.valueOf(true);
82-
}
83-
}
84-
85-
public boolean isVerified(){
86-
return (verifiedOn != null);
87-
}
88-
89139
UserAccount() {
90140
super();
91141
}

0 commit comments

Comments
 (0)