[Notice] Announcing the End of Demo Server [Read me]
wansoon 2013-04-25
add change password on userinfo page
@6140bcfc2ea92c5a5f50a2e5c8c8c49dae907105
app/controllers/UserApp.java
--- app/controllers/UserApp.java
+++ app/controllers/UserApp.java
@@ -25,6 +25,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.persistence.Transient;
+
 import static play.data.Form.form;
 import static play.libs.Json.toJson;
 
@@ -198,6 +200,40 @@
 		return user;
 	}
 
+	public static Result resetUserPassword() {
+		Form<User> userForm = form(User.class).bindFromRequest();
+
+		if(userForm.hasErrors()) {
+			return badRequest();
+		}
+
+		User currentUser = currentUser();
+		User user = userForm.get();
+		
+		if(!isValidPassword(currentUser, user.oldPassword)) {
+			Form<User> currentUserForm = new Form<User>(User.class);
+			currentUserForm = currentUserForm.fill(currentUser);
+	    
+			flash(Constants.WARNING, "user.wrongPassword.alert");
+			return badRequest(edit.render(currentUserForm, currentUser));
+		}
+		
+		resetPassword(currentUser, user.password);
+		
+		//go to login page
+		session().clear();
+		response().discardCookie(TOKEN);
+		
+		flash(Constants.WARNING, "user.loginWithNewPassword");
+        return ok(login.render("title.login", form(User.class)));
+
+	}
+	
+	public static boolean isValidPassword(User currentUser, String password) {
+		String hashedOldPassword = hashedPassword(password, currentUser.passwordSalt);
+		return currentUser.password.equals(hashedOldPassword); 
+	}
+	
     public static void resetPassword(User user, String newPassword) {
 		user.password = new Sha256Hash(newPassword,
 				ByteSource.Util.bytes(user.passwordSalt), 1024).toBase64();
app/models/User.java
--- app/models/User.java
+++ app/models/User.java
@@ -43,6 +43,9 @@
 
     @Pattern(value = "^[a-zA-Z0-9-]+([_.][a-zA-Z0-9-]+)*$", message = "user.wrongloginId.alert") @Required
     public String loginId;
+    
+    @Transient
+    public String oldPassword;
     public String password;
     public String passwordSalt;
 
@@ -175,7 +178,6 @@
                 ByteSource.Util.bytes(user.passwordSalt), 1024).toBase64();
         user.save();
     }
-
 
     public Resource asResource() {
         return new Resource() {
app/views/user/edit.scala.html
--- app/views/user/edit.scala.html
+++ app/views/user/edit.scala.html
@@ -34,7 +34,7 @@
                     @helper.inputText(userForm("email"),'_showConstraints -> false,'_label -> null, 'class -> "span2")</p>
                 </div>
                 
-                <input class="btn" type="submit" value="저장"/>
+                <input class="btn" type="submit" value="@Messages("button.save")"/>
     }
                 <hr/>
                 <div class="user-other-info info-box">
@@ -79,11 +79,34 @@
                     </li>
                 }
                 </ul>
+                <div>
+                <form name="passwordReset" action="@routes.UserApp.resetUserPassword()" method="post">
+                <input type="hidden" name="loginId" value="@user.loginId" />
+                <hr />
+                <dl>
+                <dt>@Messages("user.password")</dt>
+                <dd><input type="password" name="oldPassword" value="" autocomplete="off" /></dd>
+                <dt>@Messages("user.newPassword")</dt>
+                <dd><input type="password" id="password" name="password" value="" autocomplete="off" /></dd>
+                <dt>@Messages("validation.retypePassword")</dt>
+                <dd><input type="password" id="retypedPassword" name="retypedPassword" value="" autocomplete="off" /></dd>
+                </dl>
+                <input class="btn" type="submit" value="@Messages("button.save")" />
+                </form>
+                <hr />
+                </div>
             </div>
         </section>
     </div>
 </div>
 
+	<script type="text/javascript" src="@getJSLink("lib/validate")"></script>
+	<script type="text/javascript">
+	$(document).ready(function(){
+		$hive.loadModule("user.ResetPassword");
+	});
+	</script>
+    
     <script src="@getJSLink("lib/jquery/jquery.form")" type="text/javascript"></script>
     <script type="text/javascript">
     (function(){
conf/messages.en
--- conf/messages.en
+++ conf/messages.en
@@ -297,6 +297,7 @@
 user.loginId.duplicate = Already existing ID
 user.login.alert = Please, login.
 user.password = Password
+user.newPassword = New Password
 user.confirmPassword = Confirm Password
 user.confirmPassword.alert = Password doesn't match the confirmation
 user.wrongPassword.alert = Wrong password!
conf/messages.ko
--- conf/messages.ko
+++ conf/messages.ko
@@ -303,6 +303,7 @@
 user.loginId.duplicate = 이미 존재하는 아이디입니다.
 user.login.alert = 로그인이 필요합니다.
 user.password = 비밀번호
+user.newPassword = 신규 비밀번호
 user.confirmPassword = 비밀번호 확인
 user.confirmPassword.alert = 입력한 두 비밀번호가 서로 일치하지 않습니다
 user.wrongPassword.alert = 잘못된 비밀번호입니다!
conf/routes
--- conf/routes
+++ conf/routes
@@ -23,6 +23,7 @@
 POST    /users/signup                                   controllers.UserApp.newUser()
 GET     /user/editform                                  controllers.UserApp.editUserInfoForm()
 POST    /user/edit                                      controllers.UserApp.editUserInfo()
+POST	/user/resetPassword								controllers.UserApp.resetUserPassword()
 GET     /user/isExist/:loginId                          controllers.UserApp.isUserExist(loginId)
 GET     /user/isEmailExist/:email                       controllers.UserApp.isEmailExist(email)
 
 
public/javascripts/service/hive.user.ResetPassword.js (added)
+++ public/javascripts/service/hive.user.ResetPassword.js
@@ -0,0 +1,134 @@
+/**
+ * @(#)hive.user.Reset.js 2013.04.25
+ *
+ * Copyright NHN Corporation.
+ * Released under the MIT license
+ * 
+ * http://hive.dev.naver.com/license
+ */
+(function(ns){
+	
+	var oNS = $hive.createNamespace(ns);
+	oNS.container[oNS.name] = function(){
+		
+		var htVar = {};
+		var htElement = {};
+		
+		/**
+		 * initialize
+		 */
+		function _init(){
+			_initElement();
+			_initFormValidator();
+			_attachEvent();
+		}
+		
+		/**
+		 * initialize elements
+		 */
+		function _initElement(){
+			htElement.welInputOldPassword  = $('#oldPassword');
+			htElement.welInputPassword  = $('#password');
+			htElement.welInputRetypedPassword = $('#retypedPassword');
+
+			htElement.welForm = $("form[name=passwordReset]");
+		}
+		
+		/**
+		 * attach event
+		 */
+		function _attachEvent(){
+			htElement.welInputOldPassword.focusout(_onBlurInputPassword);
+			htElement.welInputPassword.focusout(_onBlurInputPassword);
+            htElement.welInputRetypedPassword.focusout(_onBlurInputPassword);
+		}
+		
+
+		/**
+		 * 비밀번호 확인 입력란 벗어날 때 이벤트 핸들러
+		 * 마지막 입력란이므로 전체 폼 유효성 검사
+		 */
+		function _onBlurInputPassword(){
+			htVar.oValidator._validateForm();
+		}
+
+		/**
+		 * initialize FormValidator
+		 * @require validate.js
+		 */
+		function _initFormValidator(){
+			var aRules = [
+			    {"name": 'oldPassword',		"rules": 'required'},        
+	  			{"name": 'password',		"rules": 'required|min_length[4]'},
+	  			{"name": 'retypedPassword', "rules": 'required|matches[password]'}
+	  		];
+
+			htVar.oValidator = new FormValidator('passwordReset', aRules, _onFormValidate);
+
+            // set error message
+            htVar.oValidator.setMessage('required',		 Messages("validation.required"));
+            htVar.oValidator.setMessage('min_length',	 Messages("validation.tooShortPassword"));
+            htVar.oValidator.setMessage('matches',		 Messages("validation.passwordMismatch"));
+		}
+
+		/**
+		 * on validate form
+		 * @param {Array} aErrors
+		 */
+		function _onFormValidate(aErrors){
+            _clearTooltips();
+			// to avoid bootstrap bug
+			if (aErrors.length <= 0) {
+				return _clearTooltips();
+			}
+
+			var welTarget;
+			aErrors.forEach(function(htError){
+				welTarget = htElement.welForm.find("input[name=" + htError.name + "]");
+				if(welTarget){
+					showErrorMessage(welTarget, htError.message);
+				}
+			});
+		}
+
+		/**
+		 * 폼 영역에 있는 jquery.tooltip 모두 제거하는 함수
+		 */
+		function _clearTooltips(){
+			try {
+				htElement.welForm.find("input").each(function(i, v){
+					$(v).tooltip("destroy");
+				});
+			} catch(e){}
+		}
+		
+		/**
+		 * Bootstrap toolTip function has some limitation.
+		 * In this case, toolTip doesn't provide easy way to change title and contents.
+		 * So, unfortunately I had to change data value in directly.
+		 * @param {Wrapped Element} welInput
+		 * @param {String} sMessage
+		 */
+		function showErrorMessage(welInput, sMessage){
+	        welInput.tooltip({"trigger": "manual", "placement": "right"});
+
+	        var oToolTip = welInput.data('tooltip');
+	        oToolTip.options.placement = 'right';
+	        oToolTip.options.trigger   = 'manual';
+	        oToolTip.options.title     = sMessage;
+	        oToolTip.options.content   = sMessage;
+
+	        welInput.tooltip('show');
+		}
+			
+		function hideErrorMessage(welInput){
+            welInput.tooltip("hide");
+            
+            try{
+                welInput.tooltip("destroy");
+            } catch(e){} // to avoid bootstrap bug			
+		}
+		
+		_init();
+	};
+})("hive.user.ResetPassword");(No newline at end of file)
Add a comment
List