// // Copyright 2009 Robin Komiwes, Bruno Verachten, Christophe Cordenier // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package com.wooki.pages; import org.apache.tapestry5.EventConstants; import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.OnEvent; import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.SetupRender; import org.apache.tapestry5.beaneditor.Validate; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.TextField; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; import org.springframework.security.authentication.dao.SaltSource; import org.springframework.security.authentication.encoding.PasswordEncoder; import com.wooki.domain.biz.UserManager; import com.wooki.domain.exception.AuthorizationException; import com.wooki.domain.exception.UserAlreadyException; import com.wooki.domain.model.User; import com.wooki.services.security.WookiSecurityContext; /** * Provide the ability to changes user account settings , like password, name, username and so on. */ public class AccountSettings { @Inject private WookiSecurityContext securityCtx; @Inject private UserManager userManager; @Inject private Messages messages; @Inject private SaltSource saltSource; @Inject private PasswordEncoder passwordEncoder; @Component(id = "userDetails") private Form userDetails; @Component(id = "username") private TextField username; @Component(id = "passwordChange") private Form passwordChange; @Property private User user; @Property @Validate("required") private String oldPassword; @Property @Validate("required") private String newPassword; @Property @Validate("required") private String newPasswordConfirmation; @Property @Persist(PersistenceConstants.FLASH) private String flashMessage; /** * Set current user if someone has logged in. * * @return */ @OnEvent(value = EventConstants.ACTIVATE) public Object setupUser() { if (securityCtx.isLoggedIn()) { this.user = securityCtx.getUser(); return true; } return Signin.class; } @SetupRender public Object setupUserSettings() { if (this.user == null) { return false; } return true; } @OnEvent(value = EventConstants.VALIDATE, component = "userDetails") void validateUserDetailsChange() { User userByUsername = userManager.findByUsername(user.getUsername()); // check if the new username is not already taken by someone else if (userByUsername != null && userByUsername.getId() != user.getId()) { userDetails.recordError(username, messages.get("error-username-already-taken")); } } @OnEvent(value = EventConstants.SUCCESS, component = "userDetails") void successUserDetailsChange() { try { this.user = userManager.updateDetails(user); } catch (UserAlreadyException e) { userDetails.recordError(username, messages.get("error-username-already-taken")); } } @OnEvent(value = EventConstants.VALIDATE, component = "passwordChange") void validatePasswordChange() { // first, let's check if old password is ok String encodedPassword = this.passwordEncoder.encodePassword(oldPassword, this.saltSource .getSalt(this.user)); if (!encodedPassword.equals(this.securityCtx.getUser().getPassword())) { passwordChange.recordError(messages.get("error-old-password-wrong")); } // then check if password confirmation is ok if (!newPassword.equals(newPasswordConfirmation)) { passwordChange.recordError(messages.get("error-passwords-dont-match")); } } @OnEvent(value = EventConstants.SUCCESS, component = "passwordChange") void successPasswordChange() { try { this.user = userManager.updatePassword(user, oldPassword, newPassword); this.flashMessage = messages.get("success-password-updated"); } catch (AuthorizationException e) { userDetails.recordError(messages.get("error-authorization-exception")); } } public String getTitle() { return this.messages.format("account-settings-title", user.getUsername()); } }