r1664 - in trunk: . src/main/java/cc/kune/core/client src/main/java/cc/kune/core/client/auth src/main/java/cc/kune/core/client/rpcservices src/main/java/cc/kune/core/client/sitebar/auth src/main/java/cc/kune/core/client/state src/main/java/cc/kune/core/server/manager src/main/java/cc/kune/core/server/manager/impl src/main/java/cc/kune/core/server/rpc src/main/java/cc/kune/domain src/main/java/cc/kune/domain/finders
Author: vjrj_ Date: 2012-01-17 02:24:06 +0100 (Tue, 17 Jan 2012) New Revision: 1664 Added: trunk/src/main/java/cc/kune/core/client/sitebar/auth/AskForPasswordResetPanel.java Modified: trunk/TODO trunk/src/main/java/cc/kune/core/client/CoreParts.java trunk/src/main/java/cc/kune/core/client/auth/RegisterForm.java trunk/src/main/java/cc/kune/core/client/auth/RegisterPanel.java trunk/src/main/java/cc/kune/core/client/rpcservices/UserService.java trunk/src/main/java/cc/kune/core/client/rpcservices/UserServiceAsync.java trunk/src/main/java/cc/kune/core/client/sitebar/auth/VerifyEmailClientManager.java trunk/src/main/java/cc/kune/core/client/state/SiteTokens.java trunk/src/main/java/cc/kune/core/server/manager/UserManager.java trunk/src/main/java/cc/kune/core/server/manager/impl/UserManagerDefault.java trunk/src/main/java/cc/kune/core/server/rpc/UserRPC.java trunk/src/main/java/cc/kune/domain/User.java trunk/src/main/java/cc/kune/domain/finders/UserFinder.java Log: NEW - # 99: Add a recovery password functionality http://kune.ourproject.org/issues/ticket/99 Modified: trunk/TODO =================================================================== --- trunk/TODO 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/TODO 2012-01-17 01:24:06 UTC (rev 1664) @@ -12,7 +12,54 @@ nick == assigned to * SHORT-TERM (URGENT) -** Emil notifications for new waves +** Passwd reset +Please enter your username or email address. You will receive a link to create a new password via email. +Username or E-mail: +Get New Password +Check your e-mail for the confirmation link. + + +Enter your new password below. + +New password +Confirm new password +Reset password + +Your password has been reset. Log in +-------------------------------- + +Please enter your username or email address. You will receive a link to create a new password via email. + +You are receiving this e-mail because a request has been made to change the FIXME password associated with this address ([email protected]). If you would like to reset the password for this account simply click on the link below or paste it into the url field on your favorite browser: + +LINK + +If you didn't request this email then you can just ignore it -- your details have not been disclosed to anyone. +If you have any questions about the system, feel free to contact us anytime at FIXME. + +Bla, bla, bla +----- + +Someone requested that the password be reset for the following account: + +LINK +Username: vjrj + +ReseIf this was a mistake, just ignore this email and nothing will happen. + +To reset your password, visit the following address: +LINK + + + + + +** Connection persistence +java.io.NotSerializableException: org.eclipse.jetty.websocket.WebSocketConnectionD13$WSFrameConnection +java.io.NotSerializableException: com.glines.socketio.server.transport.jetty.JettyContinuationTransportHandler + + +** Email notifications for new waves *** Migration of DB!!!!! *** Text for UI Email Notifications @@ -21,7 +68,6 @@ at most hourly at most daily I don't need email notifications -*** Cron and pseudocode ** group.inexistentTool nasty error ** calendar support *** gwt-cal + http://ical4j.sourceforge.net/introduction.html Modified: trunk/src/main/java/cc/kune/core/client/CoreParts.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/CoreParts.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/CoreParts.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -27,6 +27,7 @@ import cc.kune.core.client.groups.newgroup.NewGroup; import cc.kune.core.client.sitebar.AboutKuneDialog; import cc.kune.core.client.sitebar.SiteUserOptionsPresenter; +import cc.kune.core.client.sitebar.auth.AskForPasswordResetPanel; import cc.kune.core.client.sitebar.auth.VerifyEmailClientManager; import cc.kune.core.client.sitebar.spaces.Space; import cc.kune.core.client.sitebar.spaces.SpaceSelectEvent; @@ -61,7 +62,8 @@ final Provider<AboutKuneDialog> aboutKuneDialog, final Provider<NewGroup> newGroup, final Provider<SubtitlesManager> subProvider, final EventBus eventBus, final Provider<VerifyEmailClientManager> verifyManager, - final Provider<UserOptions> userOptionsDialog, final Provider<GroupOptions> groupOptionsDialog) { + final Provider<UserOptions> userOptionsDialog, final Provider<GroupOptions> groupOptionsDialog, + final Provider<AskForPasswordResetPanel> askForPass) { session.onAppStart(true, new AppStartHandler() { @Override public void onAppStart(final AppStartEvent event) { @@ -130,7 +132,14 @@ groupOptionsDialog.get().show(token); } }); - + tokenListener.put(SiteTokens.RESET_PASSWD, new HistoryTokenAuthNotNeededCallback() { + @Override + public void onHistoryToken(final String token) { + if (!session.isLogged()) { + askForPass.get().show(); + } + } + }); verifyManager.get(); } } Modified: trunk/src/main/java/cc/kune/core/client/auth/RegisterForm.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/auth/RegisterForm.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/auth/RegisterForm.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -21,7 +21,6 @@ import cc.kune.common.shared.i18n.I18nTranslationService; import cc.kune.core.client.ui.DefaultForm; -import cc.kune.core.shared.SessionConstants; import com.extjs.gxt.ui.client.widget.form.Field; import com.extjs.gxt.ui.client.widget.form.TextField; @@ -46,8 +45,7 @@ private final TextField<String> shortNameRegField; - public RegisterForm(final I18nTranslationService i18n, final SessionConstants session, - final UserFieldFactory userFieldFactory) { + public RegisterForm(final I18nTranslationService i18n, final UserFieldFactory userFieldFactory) { super.addStyleName("kune-Margin-Large-l"); shortNameRegField = userFieldFactory.createUserShortName(NICK_FIELD); @@ -63,7 +61,7 @@ add(passwdRegField); emailRegField = userFieldFactory.createUserEmail(EMAIL_FIELD); - emailRegField.setTabIndex(5); + emailRegField.setTabIndex(4); add(emailRegField); } Modified: trunk/src/main/java/cc/kune/core/client/auth/RegisterPanel.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/auth/RegisterPanel.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/auth/RegisterPanel.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -26,7 +26,6 @@ import cc.kune.core.client.auth.RegisterPresenter.RegisterView; import cc.kune.core.client.resources.CoreMessages; import cc.kune.core.client.ui.KuneUiUtils; -import cc.kune.core.shared.SessionConstants; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -35,9 +34,7 @@ public class RegisterPanel extends SignInAbstractPanel implements RegisterView { public static final String CANCEL_BUTTON_ID = "k-regp-cb"; - public static final String ERRMSG = "k-regp-errmsg"; - public static final String REGISTER_BUTTON_ID = "k-regp-rb"; public static final String REGISTER_DIALOG = "k-regp-dialog"; public static final String REGISTER_FORM = "k-regp-p"; @@ -46,12 +43,12 @@ private final RegisterForm registerForm; @Inject - public RegisterPanel(final I18nTranslationService i18n, final SessionConstants session, - final MaskWidgetView mask, final NotifyLevelImages images, final UserFieldFactory userFieldFactory) { + public RegisterPanel(final I18nTranslationService i18n, final MaskWidgetView mask, + final NotifyLevelImages images, final UserFieldFactory userFieldFactory) { super(REGISTER_DIALOG, mask, i18n, i18n.t(CoreMessages.REGISTER_TITLE), true, true, true, "", i18n.t(CoreMessages.REGISTER_TITLE), REGISTER_BUTTON_ID, - i18n.tWithNT("Cancel", "used in button"), CANCEL_BUTTON_ID, images, ERRMSG, 5); - registerForm = new RegisterForm(i18n, session, userFieldFactory); + i18n.tWithNT("Cancel", "used in button"), CANCEL_BUTTON_ID, images, ERRMSG, 4); + registerForm = new RegisterForm(i18n, userFieldFactory); registerForm.setWidth(330); registerForm.getFormPanel().setId(REGISTER_FORM); messageErrorBar = new MessageToolbar(images, errorLabelId); Modified: trunk/src/main/java/cc/kune/core/client/rpcservices/UserService.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/rpcservices/UserService.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/rpcservices/UserService.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -20,6 +20,7 @@ package cc.kune.core.client.rpcservices; import cc.kune.core.client.errors.DefaultException; +import cc.kune.core.client.errors.EmailNotFoundException; import cc.kune.core.shared.domain.UserSNetVisibility; import cc.kune.core.shared.domain.utils.StateToken; import cc.kune.core.shared.dto.I18nLanguageSimpleDTO; @@ -34,9 +35,9 @@ @RemoteServiceRelativePath("UserService") public interface UserService extends RemoteService { - void askForEmailConfirmation(String userHash);; + void askForEmailConfirmation(String userHash); - void askForEmailForgot(String email); + void askForPasswordReset(String email) throws EmailNotFoundException; void changePasswd(String userHash, String oldPassword, String newPassword) throws DefaultException; @@ -54,6 +55,8 @@ UserInfoDTO reloadUserInfo(String userHash) throws DefaultException; + void resetPassword(String passwdHash, String newpasswd); + void setBuddiesVisibility(String userHash, StateToken groupToken, UserSNetVisibility visibility); StateAbstractDTO updateUser(String userHash, UserDTO user, I18nLanguageSimpleDTO lang); Modified: trunk/src/main/java/cc/kune/core/client/rpcservices/UserServiceAsync.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/rpcservices/UserServiceAsync.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/rpcservices/UserServiceAsync.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -33,7 +33,7 @@ void askForEmailConfirmation(String userHash, AsyncCallback<Void> callback); - void askForEmailForgot(String email, AsyncCallback<Void> callback); + void askForPasswordReset(String email, AsyncCallback<Void> callback); void changePasswd(String userHash, String oldPassword, String newPassword, AsyncCallback<Void> callback); @@ -52,6 +52,8 @@ void reloadUserInfo(String userHash, AsyncCallback<UserInfoDTO> asyncCallback); + void resetPassword(String passwdHash, String newpasswd, AsyncCallback<Void> callback); + void setBuddiesVisibility(String userHash, StateToken groupToken, UserSNetVisibility visibility, AsyncCallback<Void> asyncCallback); Added: trunk/src/main/java/cc/kune/core/client/sitebar/auth/AskForPasswordResetPanel.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/sitebar/auth/AskForPasswordResetPanel.java (rev 0) +++ trunk/src/main/java/cc/kune/core/client/sitebar/auth/AskForPasswordResetPanel.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -0,0 +1,101 @@ +package cc.kune.core.client.sitebar.auth; + +import cc.kune.common.client.notify.NotifyLevel; +import cc.kune.common.client.notify.NotifyLevelImages; +import cc.kune.common.client.notify.NotifyUser; +import cc.kune.common.client.ui.MaskWidgetView; +import cc.kune.common.client.ui.dialogs.MessageToolbar; +import cc.kune.common.shared.i18n.I18nTranslationService; +import cc.kune.core.client.auth.SignInAbstractPanel; +import cc.kune.core.client.auth.UserFieldFactory; +import cc.kune.core.client.errors.EmailNotFoundException; +import cc.kune.core.client.events.StackErrorEvent; +import cc.kune.core.client.rpcservices.UserServiceAsync; +import cc.kune.core.client.state.Session; +import cc.kune.core.client.ui.DefaultForm; + +import com.extjs.gxt.ui.client.widget.form.LabelField; +import com.extjs.gxt.ui.client.widget.form.TextField; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +@Singleton +public class AskForPasswordResetPanel extends SignInAbstractPanel { + + public static final String ASK_PASSWD_RESET_DIALOG = "k-ask-for-pwd-diag"; + public static final String CANCEL_BUTTON_ID = "k-ask-for-pwd-cancel"; + public static final String EMAIL_RESET_ID = "k-ask-for-pwd-email"; + public static final String ERRMSG = "k-ask-for-pwd-error"; + public static final String RESET_BUTTON_ID = "k-ask-for-pwd-reset"; + private final TextField<String> resetEmail; + + @Inject + public AskForPasswordResetPanel(final I18nTranslationService i18n, final Session session, + final MaskWidgetView mask, final NotifyLevelImages images, final EventBus eventbus, + final UserFieldFactory userFieldFactory, final Provider<UserServiceAsync> userService) { + super(ASK_PASSWD_RESET_DIALOG, mask, i18n, i18n.t("Reset your password"), true, true, true, "", + i18n.t("Reset your password"), RESET_BUTTON_ID, i18n.tWithNT("Cancel", "used in button"), + CANCEL_BUTTON_ID, images, ERRMSG, 1); + final DefaultForm form = new DefaultForm(); + final LabelField desc = new LabelField( + i18n.t("Please enter your email address. You will receive a link to create a new password via email.")); + form.add(desc); + resetEmail = userFieldFactory.createUserEmail(EMAIL_RESET_ID); + resetEmail.setFieldLabel(i18n.t("email")); + resetEmail.setTabIndex(1); + messageErrorBar = new MessageToolbar(images, errorLabelId); + form.add(resetEmail); + form.add(messageErrorBar); + super.getFirstBtn().addClickHandler(new ClickHandler() { + @Override + public void onClick(final ClickEvent event) { + if (form.isValid()) { + userService.get().askForPasswordReset(resetEmail.getValue(), new AsyncCallback<Void>() { + @Override + public void onFailure(final Throwable caught) { + if (caught instanceof EmailNotFoundException) { + AskForPasswordResetPanel.this.setErrorMessage(i18n.t("Invalid email"), NotifyLevel.error); + } else { + AskForPasswordResetPanel.this.setErrorMessage( + i18n.t("Other error trying to reset your password"), NotifyLevel.error); + } + StackErrorEvent.fire(eventbus, caught); + AskForPasswordResetPanel.this.messageErrorBar.setVisible(true); + } + + @Override + public void onSuccess(final Void result) { + NotifyUser.info(i18n.t("Check your email for the confirmation link")); + hide(); + } + }); + } + } + }); + super.getInnerPanel().add(form.getFormPanel()); + super.getSecondBtn().addClickHandler(new ClickHandler() { + + @Override + public void onClick(final ClickEvent event) { + hide(); + } + }); + } + + @Override + public void hide() { + super.hide(); + super.messageErrorBar.hideErrorMessage(); + resetEmail.clear(); + } + + @Override + public void show() { + super.show(); + } +} Modified: trunk/src/main/java/cc/kune/core/client/sitebar/auth/VerifyEmailClientManager.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/sitebar/auth/VerifyEmailClientManager.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/sitebar/auth/VerifyEmailClientManager.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -28,7 +28,7 @@ new AsyncCallbackSimple<Void>() { @Override public void onSuccess(final Void result) { - NotifyUser.info("Great. Your email is now verified."); + NotifyUser.info("Great. Your email is now verified"); session.getCurrentUser().setEmailVerified(true); optGeneral.get().update(); } Modified: trunk/src/main/java/cc/kune/core/client/state/SiteTokens.java =================================================================== --- trunk/src/main/java/cc/kune/core/client/state/SiteTokens.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/client/state/SiteTokens.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -36,7 +36,7 @@ public final static String PREFS = "prefs"; public static final String PREVIEW = "preview"; public final static String REGISTER = "register"; - public final static String RESET_PWD = "resetpasswd"; + public final static String RESET_PASSWD = "resetpasswd"; public final static String SIGN_IN = "signin"; public final static String SUBTITLES = "sub"; public final static String TRANSLATE = "translate"; @@ -58,6 +58,6 @@ reserverdWords.add(PREFS); reserverdWords.add(GROUP_PREFS); reserverdWords.add(VERIFY_EMAIL); - reserverdWords.add(RESET_PWD); + reserverdWords.add(RESET_PASSWD); } } Modified: trunk/src/main/java/cc/kune/core/server/manager/UserManager.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/manager/UserManager.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/server/manager/UserManager.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -41,7 +41,21 @@ */ void askForEmailConfirmation(User user, EmailConfirmationType type) throws DefaultException; - User changePasswd(Long userId, String oldPassword, String newPassword); + /** + * Change passwd. + * + * @param userId + * the user id to change the passwd + * @param oldPassword + * the old password + * @param newPassword + * the new password + * @param checkOldPasswd + * if we have to check the old passwd (not necessary if we are + * reseting a unknown password) + * @return the user + */ + User changePasswd(Long userId, String oldPassword, String newPassword, boolean checkOldPasswd); /** * CreateUser new method with language country and timezone params Modified: trunk/src/main/java/cc/kune/core/server/manager/impl/UserManagerDefault.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/manager/impl/UserManagerDefault.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/server/manager/impl/UserManagerDefault.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -133,6 +133,11 @@ * @see * cc.kune.core.server.manager.UserManager#askForEmailConfirmation(cc.kune * .domain.User, cc.kune.core.server.manager.impl.EmailConfirmationType) + * + * More info: http://en.wikipedia.org/wiki/Self-service_password_reset + * http://en.wikipedia.org/wiki/Password_notification_e-mail + * http://stackoverflow + * .com/questions/1102781/best-way-for-a-forgot-password-implementation */ @Override public void askForEmailConfirmation(final User user, final EmailConfirmationType type) @@ -150,29 +155,43 @@ TokenUtils.addRedirect(SiteTokens.VERIFY_EMAIL, hash)); break; case passwordReset: - // FIXME + notifyService.sendEmailToWithLink( + user, + "Verify password reset", + "You are receiving this email because a request has been made to change the password associated with this email address in %s.<br>" + + "If this was a mistake, just ignore this email and nothing will happen.<br>" + + "If you would like to reset the password for this account simply click on the link below or paste it into the url field on your favorite browser:", + TokenUtils.addRedirect(SiteTokens.RESET_PASSWD, hash)); default: break; } } @Override - public User changePasswd(final Long userId, final String oldPassword, final String newPassword) { + public User changePasswd(final Long userId, final String oldPassword, final String newPassword, + final boolean checkOldPasswd) { final User user = find(userId); final ParticipantId participantId = participantUtils.of(user.getShortName()); - // Check oldPasswd + if (checkOldPasswd) { + // Check oldPasswd + AccountData account; + try { + account = waveAccountStore.getAccount(participantId); + if (TextUtils.notEmpty(oldPassword) && account != null + && !account.asHuman().getPasswordDigest().verify(oldPassword.toCharArray())) { + throw new WrongCurrentPasswordException(); + } + } catch (final PersistenceException e) { + thowExceptionChangingPasswd(e); + } + } try { - final AccountData account = waveAccountStore.getAccount(participantId); - if (TextUtils.notEmpty(oldPassword) && account != null - && !account.asHuman().getPasswordDigest().verify(oldPassword.toCharArray())) { - throw new WrongCurrentPasswordException(); - } // Wave change passwd RobotAgentUtil.changeUserPassword(newPassword, participantId, waveAccountStore); } catch (final IllegalArgumentException e) { - throw new DefaultException("Error changing user passwd", e); + thowExceptionChangingPasswd(e); } catch (final PersistenceException e) { - throw new DefaultException("Error changing user passwd", e); + thowExceptionChangingPasswd(e); } // Kune db change passwd final PasswordDigest newPasswordDigest = new PasswordDigest(newPassword.toCharArray()); @@ -402,6 +421,10 @@ persist(user); } + private void thowExceptionChangingPasswd(final Exception e) { + throw new DefaultException("Error changing user passwd", e); + } + @Override public User update(final Long userId, final UserDTO userDTO, final I18nLanguageSimpleDTO lang) { final User user = find(userId); Modified: trunk/src/main/java/cc/kune/core/server/rpc/UserRPC.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/rpc/UserRPC.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/core/server/rpc/UserRPC.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -29,6 +29,7 @@ import cc.kune.core.client.errors.AccessViolationException; import cc.kune.core.client.errors.DefaultException; +import cc.kune.core.client.errors.EmailHashInvalidException; import cc.kune.core.client.errors.EmailNotFoundException; import cc.kune.core.client.errors.UserAuthException; import cc.kune.core.client.rpcservices.UserService; @@ -104,7 +105,7 @@ @Override @Transactional - public void askForEmailForgot(final String email) throws DefaultException { + public void askForPasswordReset(final String email) throws EmailNotFoundException { try { final User user = userFinder.findByEmail(email); userManager.askForEmailConfirmation(user, EmailConfirmationType.passwordReset); @@ -119,7 +120,7 @@ public void changePasswd(final String userHash, final String oldPassword, final String newPassword) throws DefaultException { final Long userId = userSessionManager.getUser().getId(); - userManager.changePasswd(userId, oldPassword, newPassword); + userManager.changePasswd(userId, oldPassword, newPassword, true); } @Override @@ -208,6 +209,17 @@ } @Override + @Transactional + public void resetPassword(final String passwdHash, final String newpasswd) { + try { + final User user = userFinder.findByHash(passwdHash); + userManager.changePasswd(user.getId(), null, newpasswd, false); + } catch (final NoResultException e) { + throw new EmailHashInvalidException(); + } + } + + @Override @Authenticated(mandatory = true) @Authorizated(accessRolRequired = AccessRol.Administrator, actionLevel = ActionLevel.group) @Transactional @@ -241,4 +253,5 @@ final User user = userSessionManager.getUser(); userManager.verifyPasswordHash(user.getId(), emailReceivedHash, SessionConstants._AN_HOUR); } + } Modified: trunk/src/main/java/cc/kune/domain/User.java =================================================================== --- trunk/src/main/java/cc/kune/domain/User.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/domain/User.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -83,11 +83,13 @@ @Length(min = 1) private String email; + @Basic(optional = true) private Long emailCheckDate; // @OneToOne(cascade = CascadeType.REMOVE) // private final CustomProperties customProperties; + @Column(unique = true, nullable = true) private String emailConfirmHash; @Enumerated(EnumType.STRING) Modified: trunk/src/main/java/cc/kune/domain/finders/UserFinder.java =================================================================== --- trunk/src/main/java/cc/kune/domain/finders/UserFinder.java 2012-01-16 20:53:44 UTC (rev 1663) +++ trunk/src/main/java/cc/kune/domain/finders/UserFinder.java 2012-01-17 01:24:06 UTC (rev 1664) @@ -44,6 +44,9 @@ @Finder(query = "from User where email = :email") public User findByEmail(@Named("email") final String email); + @Finder(query = "from User where emailConfirmHash = :emailConfirmHash") + public User findByHash(@Named("emailConfirmHash") final String emailConfirmHash); + @Finder(query = "from User where id = :id") public User findById(@Named("id") final Long id);
participants (1)
-
Vicente J. Ruiz Jurado