Author: fdesbois Date: 2010-04-10 01:28:55 +0200 (Sat, 10 Apr 2010) New Revision: 2969 Log: - Remove PropertiesFileSymbolProvider, PollenManager provide this service - PollenContext is no longer a service to Inject, PollenManager contains the context and can be injected - Change EmailException to PollenBusinessException to show correct message on smtp error - Implements updateUser for UserProfile page + add method for validations - Improve tests and password managment (no more encoding in UI, add newPassword getter/setter in UserAccount) Added: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_en.properties trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_fr.properties trunk/pollen-ui/src/main/webapp/user/UserProfile.tml Removed: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PropertiesFileSymbolProvider.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/utils/BusinessUtils.java trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_en.properties trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_fr.properties trunk/pollen-ui/src/main/webapp/user/Account.tml Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java trunk/pollen-business/src/main/java/org/chorem/pollen/PollenContextImpl.java trunk/pollen-business/src/main/java/org/chorem/pollen/entity/UserAccountImpl.java trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceEmailImpl.java trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties trunk/pollen-business/src/main/xmi/pollen.properties trunk/pollen-business/src/main/xmi/pollen.zargo trunk/pollen-business/src/test/java/org/chorem/pollen/business/TestManager.java trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java trunk/pollen-business/src/test/resources/log4j.properties trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/Border.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/FeedContextLink.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/LoginComponent.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/Index.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/admin/UsersAdmin.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/poll/VoteForPoll.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserRegister.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PollenManager.java trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties trunk/pollen-ui/src/main/resources/log4j.properties trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/LoginComponent.tml trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserRegister_fr.properties trunk/pollen-ui/src/main/webapp/css/common.css trunk/pollen-ui/src/main/webapp/user/UserRegister.tml Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -38,7 +38,8 @@ USER_LOGIN_EXIST(n_("pollen.exception.user_login_exist")), USER_EMAIL_EXIST(n_("pollen.exception.user_email_exist")), USER_NOT_EXIST(n_("pollen.exception.user_not_exist")), - USER_WRONG_PASSWORD(n_("pollen.exception.user_wrong_password")); + USER_WRONG_PASSWORD(n_("pollen.exception.user_wrong_password")), + SMTP_NOT_AVAILABLE(n_("pollen.exception.smtp_not_available")); private String message; Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/PollenContextImpl.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/PollenContextImpl.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/PollenContextImpl.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -120,7 +120,7 @@ try { if (log.isInfoEnabled()) { log.info("Start Pollen"); - log.info("Initialize i18n bundle"); +// log.info("Initialize i18n bundle"); } I18n.setInitializer(new DefaultI18nInitializer("pollen-business")); I18n.init(); Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/entity/UserAccountImpl.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/entity/UserAccountImpl.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/entity/UserAccountImpl.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -18,7 +18,30 @@ private static final long serialVersionUID = 1L; + protected String newPassword; + + /** + * Get the value of newPassword + * + * @return the value of newPassword + */ @Override + public String getNewPassword() { + return newPassword; + } + + /** + * Set the value of newPassword + * + * @param newPassword new value of newPassword + */ + @Override + public void setNewPassword(String newPassword) { + this.newPassword = newPassword; + } + + + @Override public void addFavoriteList(PollAccount list) { throw new UnsupportedOperationException("Not supported yet."); } @@ -26,11 +49,13 @@ @Override public String getDisplayName() { String name = ""; + String separator = ""; if (StringUtils.isNotEmpty(getFirstName())) { name += getFirstName(); + separator = " "; } if (StringUtils.isNotEmpty(getLastName())) { - name += getLastName(); + name += separator + getLastName(); } if (StringUtils.isEmpty(name)) { name = getLogin(); Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceEmailImpl.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceEmailImpl.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceEmailImpl.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -6,6 +6,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail; +import org.chorem.pollen.PollenBusinessException; +import org.chorem.pollen.PollenBusinessException.PollenExceptionType; import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenException; import org.chorem.pollen.bean.PollenEmail; @@ -53,27 +55,36 @@ @Override protected void executeSendEmail(List<Object> errorArgs, - PollenEmail pollenEmail) throws EmailException { + PollenEmail pollenEmail) throws PollenBusinessException { errorArgs.add(pollenEmail.getHost()); errorArgs.add(pollenEmail.getPort()); errorArgs.add(pollenEmail.getTo()); errorArgs.add(pollenEmail.getFrom()); + try { - // Create the SimpleEmail to send - SimpleEmail email = pollenEmail.createSimpleEmail(); - email.send(); + // Create the SimpleEmail to send + SimpleEmail email = pollenEmail.createSimpleEmail(); + email.send(); - if (log.isInfoEnabled()) { - log.info("Mail sent to : " + pollenEmail.getTo()); + if (log.isInfoEnabled()) { + log.info("Mail sent to : " + pollenEmail.getTo()); - if (log.isDebugEnabled()) { - log.debug("Email infos : " + - "\ndate: " + email.getSentDate() + - "\nhostname: " + email.getHostName() + - "\nport: " + email.getSmtpPort() + - "\nfrom: " + email.getFromAddress().toString()); + if (log.isDebugEnabled()) { + log.debug("Email infos : " + + "\ndate: " + email.getSentDate() + + "\nhostname: " + email.getHostName() + + "\nport: " + email.getSmtpPort() + + "\nfrom: " + email.getFromAddress().toString()); + } } + } catch (EmailException eee) { + if (log.isErrorEnabled()) { + log.error("Error on email send", eee); + } + throw new PollenBusinessException( + PollenExceptionType.SMTP_NOT_AVAILABLE, + pollenEmail.getTo()); } } Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -4,6 +4,8 @@ import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.PollenBusinessException.PollenExceptionType; import org.chorem.pollen.PollenContext; @@ -15,6 +17,8 @@ import org.chorem.pollen.entity.UserAccountImpl; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaQuery; +import org.nuiton.topia.framework.TopiaQuery.Op; /** * ServiceUserImpl @@ -29,6 +33,8 @@ */ public class ServiceUserImpl extends ServiceUserAbstract { + private Log log = LogFactory.getLog(ServiceUserImpl.class); + private PollenContext context; public void setContext(PollenContext context) { @@ -51,12 +57,107 @@ context.closeTransaction(transaction); } + /** + * Used to manage the new password of the user. This newPassword will be + * encoded then set into the real password. + * + * @param user to treate + * @return true if the newPassword is encoded and set, false otherwise + */ + protected boolean manageNewPassword(UserAccount user) { + // Manage password encoding + String newPassword = user.getNewPassword(); + if (StringUtils.isNotEmpty(newPassword)) { + user.setPassword(context.encodePassword(newPassword)); + if (log.isDebugEnabled()) { + log.debug("Reset newPassword from UserAccount"); + } + user.setNewPassword(null); + return true; + } + return false; + } + + /** + * Check if the {@code login} and {@code password} correspond to an + * existing user. + * + * @param dao used to execute the query + * @param login to check + * @param password to check + * @throws TopiaException for ToPIA errors + * @throws PollenBusinessException USER_WRONG_PASSWORD + */ + protected void checkPassword(UserAccountDAO dao, String login, + String password) throws TopiaException, PollenBusinessException { + int count = dao.createQuery(). + add(UserAccount.LOGIN, login). + add(UserAccount.PASSWORD, password). + executeCount(); + // no user found + if (count == 0) { + throw new PollenBusinessException( + PollenExceptionType.USER_WRONG_PASSWORD, login); + } + } + + /** + * Check if the {@code login} doesn't already exist. + * + * @param dao used to execute the query + * @param login to check + * @throws TopiaException for ToPIA errors + * @throws PollenBusinessException USER_LOGIN_EXIST + */ + protected void checkLoginNotExist(UserAccountDAO dao, String login) + throws PollenBusinessException, TopiaException { + int count = dao.createQuery(). + add(UserAccount.LOGIN, login). + executeCount(); + // existing user found + if (count > 0) { + throw new PollenBusinessException( + PollenExceptionType.USER_LOGIN_EXIST); + } + } + + /** + * Check if the {@code email} doesn't already exist, only if not empty. + * + * @param dao used to execute the query + * @param email to check + * @param query existing query to execute. A new one will be created if this + * param is null. + * @throws TopiaException for ToPIA errors + * @throws PollenBusinessException USER_EMAIL_EXIST + */ + protected void checkEmailNotExist(UserAccountDAO dao, String email, + TopiaQuery query) throws PollenBusinessException, TopiaException { + // Don't check if email is empty + if (StringUtils.isEmpty(email)) { + return; + } + if (query == null) { + query = dao.createQuery(); + } + int count = query.add(UserAccount.EMAIL, email). + executeCount(); + // existing user found + if (count > 0) { + throw new PollenBusinessException( + PollenExceptionType.USER_EMAIL_EXIST); + } + } + @Override protected UserAccount executeConnect(TopiaContext transaction, List<Object> errorArgs, String login, String password) throws PollenBusinessException, TopiaException { + + String encodedPassword = context.encodePassword(password); + errorArgs.add(login); - errorArgs.add(password); + errorArgs.add(encodedPassword); UserAccountDAO dao = PollenDAOHelper.getUserAccountDAO(transaction); @@ -65,10 +166,8 @@ if (user == null) { throw new PollenBusinessException( PollenExceptionType.USER_NOT_EXIST, login); - } else if (!user.getPassword().equals(password)) { - throw new PollenBusinessException( - PollenExceptionType.USER_WRONG_PASSWORD, login); } + checkPassword(dao, login, encodedPassword); return user; } @@ -81,7 +180,7 @@ } @Override - protected void executeCreateUpdateUser(TopiaContext transaction, + protected void executeCreateUser(TopiaContext transaction, List<Object> errorArgs, UserAccount user) throws TopiaException, PollenBusinessException { @@ -90,27 +189,53 @@ errorArgs.add(user.getAdmin()); UserAccountDAO dao = PollenDAOHelper.getUserAccountDAO(transaction); + + // Check login not exist + checkLoginNotExist(dao, user.getLogin()); - // New User - if (StringUtils.isEmpty(user.getTopiaId())) { - // Check login exist - UserAccount userFound = dao.findByLogin(user.getLogin()); - if (userFound != null) { - throw new PollenBusinessException( - PollenExceptionType.USER_LOGIN_EXIST); - } - // Check email exist - userFound = dao.findByEmail(user.getEmail()); - if (userFound != null) { - throw new PollenBusinessException( - PollenExceptionType.USER_EMAIL_EXIST); - } - dao.create(user); - // Update existing user - } else { - dao.update(user); + // Check email not exist + checkEmailNotExist(dao, user.getEmail(), null); + + // Execute create + manageNewPassword(user); + dao.create(user); + + transaction.commitTransaction(); + } + + + + @Override + protected void executeUpdateUser(TopiaContext transaction, + List<Object> errorArgs, UserAccount user) + throws TopiaException, PollenBusinessException { + + errorArgs.add(user.getLogin()); + errorArgs.add(user.getEmail()); + errorArgs.add(user.getAdmin()); + + UserAccountDAO dao = PollenDAOHelper.getUserAccountDAO(transaction); + + // Check the password + String encodedPassword = context.encodePassword(user.getPassword()); + checkPassword(dao, user.getLogin(), encodedPassword); + + // Change password if needed + boolean passwordChanged = manageNewPassword(user); + // Otherwise set the encodedPassword to properly save the user + if (!passwordChanged) { + user.setPassword(encodedPassword); } + // In case of email change, check if an other user has not already + // the new email + TopiaQuery query = dao.createQuery(). + add(UserAccount.LOGIN, Op.NEQ, user.getLogin()); + checkEmailNotExist(dao, user.getEmail(), query); + + // Execute update + dao.update(user); + transaction.commitTransaction(); } Modified: trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties =================================================================== --- trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -37,6 +37,7 @@ pollen.error.serviceUser.createDefaultAdmin= pollen.error.serviceUser.createUpdateList= pollen.error.serviceUser.createUpdateUser= +pollen.error.serviceUser.createUser= pollen.error.serviceUser.deleteList= pollen.error.serviceUser.deleteUser= pollen.error.serviceUser.getFavoriteLists= @@ -45,11 +46,13 @@ pollen.error.serviceUser.getNewUser= pollen.error.serviceUser.getPerson= pollen.error.serviceUser.getUsers= +pollen.error.serviceUser.updateUser= pollen.error.serviceVote.getVote= pollen.error.serviceVote.getVotesByPoll=Unable to load votes from poll with uid \= %1$s pollen.error.serviceVote.hasAlreadyVoted=Unable test vote existing for account with votingId \= %1$s and poll with uid \= %2$s pollen.exception.load_configuration= pollen.exception.poll_not_exist=No such poll exists. Please make sure that you are using the correct link and copy it completely into your browser's address field. +pollen.exception.smtp_not_available= pollen.exception.user_email_exist= pollen.exception.user_login_exist= pollen.exception.user_not_exist= Modified: trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties =================================================================== --- trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -36,6 +36,7 @@ pollen.error.serviceUser.createDefaultAdmin=Impossible de cr\u00E9er l'administrateur par d\u00E9faut \: %1$s (%2$s) pollen.error.serviceUser.createUpdateList= pollen.error.serviceUser.createUpdateUser=Impossible de cr\u00E9er l'utilisateur '%1$s' <%2$s> (admin \= %$3b) +pollen.error.serviceUser.createUser= pollen.error.serviceUser.deleteList= pollen.error.serviceUser.deleteUser= pollen.error.serviceUser.getFavoriteLists= @@ -44,11 +45,13 @@ pollen.error.serviceUser.getNewUser=Impossible d'instancier un nouvel utilisateur. pollen.error.serviceUser.getPerson= pollen.error.serviceUser.getUsers= +pollen.error.serviceUser.updateUser= pollen.error.serviceVote.getVote= pollen.error.serviceVote.getVotesByPoll= pollen.error.serviceVote.hasAlreadyVoted= pollen.exception.load_configuration=La configuration n'a pas \u00E9t\u00E9 charg\u00E9e correctement \! Veuillez v\u00E9rifier le d\u00E9marrage de l'application. pollen.exception.poll_not_exist=Il n'y a pas de sondage \u00E0 cette adresse. Veuillez verifier que vous utilisez le lien correcte et copiez-le compl\u00E8tement dans le champ d'adresse de votre navigateur. +pollen.exception.smtp_not_available=Impossible d'envoyer un email \u00E0 %1$s. Serveur smtp indisponible pour l'envoi d'email, veuillez contacter un administrateur. pollen.exception.user_email_exist=Un utilisateur est d\u00E9j\u00E0 enregistr\u00E9 avec cet email. pollen.exception.user_login_exist=Un utilisateur est d\u00E9j\u00E0 enregistr\u00E9 avec cet identifiant. pollen.exception.user_not_exist=L'identifiant '%1$s' ne correspond \u00E0 aucun utilisateur connu. Modified: trunk/pollen-business/src/main/xmi/pollen.properties =================================================================== --- trunk/pollen-business/src/main/xmi/pollen.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/main/xmi/pollen.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -3,5 +3,6 @@ #model.tagvalue.dbSchema=Pollen model.tagvalue.java.lang.String=text model.tagvalue.exceptionClass=org.chorem.pollen.PollenException -#org.chorem.pollen.business.persistence.PollAccount.attribute.accountId.tagvalue.naturalId=true -#org.chorem.pollen.business.persistence.Poll.attribute.pollId.tagvalue.naturalId=true \ No newline at end of file + +org.chorem.pollen.entity.UserAccount.attribute.login.tagvalue.naturalId=true +org.chorem.pollen.entity.UserAccount.attribute.email.tagvalue.unique=true \ No newline at end of file Modified: trunk/pollen-business/src/main/xmi/pollen.zargo =================================================================== (Binary files differ) Modified: trunk/pollen-business/src/test/java/org/chorem/pollen/business/TestManager.java =================================================================== --- trunk/pollen-business/src/test/java/org/chorem/pollen/business/TestManager.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/test/java/org/chorem/pollen/business/TestManager.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -78,19 +78,19 @@ return getContext().beginTransaction(); } - public static ServiceUser getServiceUser() { + public static ServiceUserImpl getServiceUser() { ServiceUserImpl instance = new ServiceUserImpl(); instance.setContext(getContext()); return instance; } - public static ServiceEmail getServiceEmail() { + public static ServiceEmailImpl getServiceEmail() { ServiceEmailImpl instance = new ServiceEmailImpl(); instance.setContext(getContext()); return instance; } - public static ServicePoll getServicePoll() { + public static ServicePollImpl getServicePoll() { ServicePollImpl instance = new ServicePollImpl(); instance.setContext(getContext()); return instance; Modified: trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java =================================================================== --- trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -7,14 +7,19 @@ import org.apache.commons.logging.LogFactory; import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.PollenBusinessException.PollenExceptionType; +import org.chorem.pollen.PollenDAOHelper; +import org.chorem.pollen.PollenException; import org.chorem.pollen.business.TestManager; import org.chorem.pollen.entity.UserAccount; +import org.chorem.pollen.entity.UserAccountDAO; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; /** * @@ -44,12 +49,99 @@ TestManager.stop(); } + @Test + public void testManageNewPassword() throws Exception { + TestManager.start("testManageNewPassword"); + + ServiceUserImpl serviceUser = TestManager.getServiceUser(); + + UserAccount user = serviceUser.getNewUser(Locale.FRENCH); + user.setLogin("homer"); + user.setNewPassword("wouhou"); + + log.info("test 1 : Encode new password"); + boolean result = serviceUser.manageNewPassword(user); + Assert.assertTrue(result); + + String expected = TestManager.getContext().encodePassword("wouhou"); + Assert.assertEquals(expected, user.getPassword()); + Assert.assertNull(user.getNewPassword()); + + log.info("test 2 : Do not encode new password -> newPassword empty"); + result = serviceUser.manageNewPassword(user); + Assert.assertFalse(result); + } + + @Test + public void testCheckPassword() throws Exception { + TestManager.start("testCheckPassword"); + + ServiceUserImpl serviceUser = TestManager.getServiceUser(); + + UserAccount user = serviceUser.getNewUser(Locale.FRENCH); + user.setLogin("homer"); + user.setNewPassword("wouhou"); + serviceUser.createUser(user); + + String encodedPassword = + TestManager.getContext().encodePassword("wouhou"); + + TopiaContext transaction = TestManager.beginTransaction(); + try { + UserAccountDAO dao = PollenDAOHelper.getUserAccountDAO(transaction); + + log.info("test 1 : Good password"); + serviceUser.checkPassword(dao, "homer", encodedPassword); + + log.info("test 2 : Wrong password"); + try { + serviceUser.checkPassword(dao, "homer", "bad"); + } catch (PollenBusinessException eee) { + log.error("Error : " + eee.getMessage()); + Assert.assertEquals(PollenExceptionType.USER_WRONG_PASSWORD, + eee.getType()); + } + } finally { + transaction.closeContext(); + } + } + /** * Test of executeConnect method, of class ServiceUserImpl. */ - //@Test + @Test public void testExecuteConnect() throws Exception { TestManager.start("testExecuteConnect"); + + ServiceUser serviceUser = TestManager.getServiceUser(); + + UserAccount user = serviceUser.getNewUser(Locale.FRENCH); + user.setLogin("hsimpson"); + user.setEmail("hsimpson@springfield.us"); + user.setNewPassword("wouhou"); + serviceUser.createUser(user); + + log.info("test 1 : Connection OK"); + UserAccount connected = serviceUser.connect("hsimpson", "wouhou"); + Assert.assertEquals(user, connected); + + log.info("test 2 : Connection problem on login -> user not exist"); + try { + serviceUser.connect("homer", "wouhou"); + } catch (PollenBusinessException eee) { + log.error("Error : " + eee.getMessage()); + Assert.assertEquals(PollenExceptionType.USER_NOT_EXIST, + eee.getType()); + } + + log.info("test 3 : Connection problem on password -> don't match with login"); + try { + serviceUser.connect("hsimpson", "coucou"); + } catch (PollenBusinessException eee) { + log.error("Error : " + eee.getMessage()); + Assert.assertEquals(PollenExceptionType.USER_WRONG_PASSWORD, + eee.getType()); + } } /** @@ -71,55 +163,114 @@ * Test of executeCreateUpdateUser method, of class ServiceUserImpl. */ @Test - public void testExecuteCreateUpdateUser() throws Exception { - TestManager.start("testCreateUpdateUser"); + public void testExecuteCreateUser() throws Exception { + TestManager.start("testCreateUser"); ServiceUser serviceUser = TestManager.getServiceUser(); UserAccount user = serviceUser.getNewUser(Locale.FRENCH); user.setLogin("hsimpson"); user.setEmail("hsimpson@springfield.us"); + user.setNewPassword("wouhou"); + String encodedPassword = TestManager.getContext().encodePassword("wouhou"); - user.setPassword(encodedPassword); - serviceUser.createUpdateUser(user); + log.info("test 1 : Creation OK"); + serviceUser.createUser(user); Assert.assertNotNull(user.getTopiaId()); - Assert.assertNotSame("wouhou", user.getPassword()); + Assert.assertNotSame(encodedPassword, user.getPassword()); - // User 2 with same login + log.info("test 2 : Creation problem on login -> user exist"); UserAccount user2 = serviceUser.getNewUser(Locale.FRENCH); user2.setLogin("hsimpson"); // Not the same email user2.setEmail("hsimpson@springfield.com"); - user2.setPassword("troubidou"); + user2.setNewPassword("troubidou"); try { - serviceUser.createUpdateUser(user2); + serviceUser.createUser(user2); } catch (PollenBusinessException eee) { - log.error("Error : " + eee.getMessage(), eee); + log.error("Error : " + eee.getMessage()); Assert.assertEquals(PollenExceptionType.USER_LOGIN_EXIST, eee.getType()); } - // User 3 with same email as user + log.info("test 3 : Creation problem on email -> user exist"); UserAccount user3 = serviceUser.getNewUser(Locale.FRENCH); user3.setLogin("homer"); user3.setEmail("hsimpson@springfield.us"); - user3.setPassword("troubidou"); + user3.setNewPassword("troubidou"); try { - serviceUser.createUpdateUser(user3); + serviceUser.createUser(user3); } catch (PollenBusinessException eee) { - log.error("Error : " + eee.getMessage(), eee); + log.error("Error : " + eee.getMessage()); Assert.assertEquals(PollenExceptionType.USER_EMAIL_EXIST, eee.getType()); } + log.info("test 4 : Creation OK with no email"); + UserAccount user4 = serviceUser.getNewUser(Locale.FRENCH); + user4.setLogin("marge"); + user4.setNewPassword("troubidou"); + + serviceUser.createUser(user4); + Assert.assertNull(user4.getEmail()); } /** * Test of executeDeleteUser method, of class ServiceUserImpl. */ + @Test + public void testExecuteUpdateUser() throws Exception { + TestManager.start("testUpdateUser"); + ServiceUser serviceUser = TestManager.getServiceUser(); + + UserAccount user1 = serviceUser.getNewUser(Locale.FRENCH); + user1.setLogin("hsimpson"); + user1.setEmail("hsimpson@springfield.us"); + user1.setNewPassword("wouhou"); + serviceUser.createUser(user1); + + UserAccount user2 = serviceUser.getNewUser(Locale.FRENCH); + String user2Password = "wouhou"; + user2.setLogin("homer"); + user2.setEmail("hsimpson@springfield.fr"); + user2.setNewPassword(user2Password); + serviceUser.createUser(user2); + + log.info("test 1 : Can't change login -> don't match with password"); + user2.setLogin("homersimpson"); + user2.setPassword(user2Password); + try { + serviceUser.updateUser(user2); + } catch (PollenBusinessException eee) { + log.error("Error : " + eee.getMessage()); + Assert.assertEquals(PollenExceptionType.USER_WRONG_PASSWORD, + eee.getType()); + } + user2.setLogin("homer"); + + log.info("test 2 : Change email OK"); + user2.setEmail("homersimpson@springield.fr"); + user2.setPassword(user2Password); + serviceUser.updateUser(user2); + + log.info("test 3 : Change email problem -> user exist"); + user2.setEmail(user1.getEmail()); + user2.setPassword(user2Password); + try { + serviceUser.updateUser(user2); + } catch (PollenBusinessException eee) { + log.error("Error : " + eee.getMessage()); + Assert.assertEquals(PollenExceptionType.USER_EMAIL_EXIST, + eee.getType()); + } + } + + /** + * Test of executeDeleteUser method, of class ServiceUserImpl. + */ //@Test public void testExecuteDeleteUser() throws Exception { System.out.println("executeDeleteUser"); Modified: trunk/pollen-business/src/test/resources/log4j.properties =================================================================== --- trunk/pollen-business/src/test/resources/log4j.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-business/src/test/resources/log4j.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -8,7 +8,7 @@ log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%p] %c{2} %m%n -log4j.logger.org.chorem.pollen=debug +log4j.logger.org.chorem.pollen=info log4j.logger.org.chorem.pollen.business.PollenContextImpl=warn log4j.logger.org.chorem.pollen.business.services.SendMail=warn Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/Border.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/Border.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/Border.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -33,7 +33,6 @@ import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.services.PersistentLocale; import org.apache.tapestry5.services.Request; -import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenProperty; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.ui.base.ContextLink; @@ -42,7 +41,7 @@ import org.chorem.pollen.service.ServiceUser; import org.chorem.pollen.ui.data.AddressBar; import org.chorem.pollen.ui.pages.Index; -import org.chorem.pollen.ui.utils.BusinessUtils; +import org.chorem.pollen.ui.services.PollenManager; import org.slf4j.Logger; /** @@ -150,7 +149,7 @@ private PersistentLocale localeService; @Inject - private PollenContext pollen; + private PollenManager manager; /** Injection des services */ @Inject @@ -245,14 +244,14 @@ // No need to connect if user exists if (!userExists) { try { - String encodedPassword = pollen.encodePassword(password); - UserAccount current = - serviceUser.connect(login, encodedPassword); + UserAccount current = serviceUser.connect(login, password); user = current; + // Change locale for user + localeService.set(new Locale(user.getLanguage())); feedback.addInfo(messages.get("loginOk")); } catch (PollenBusinessException eee) { feedback.addError( - BusinessUtils.getErrorMessage(eee, messages, logger)); + manager.getErrorMessage(eee, messages, logger)); } } return this; Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/FeedContextLink.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/FeedContextLink.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/FeedContextLink.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -3,9 +3,9 @@ import java.io.File; import org.apache.tapestry5.ioc.annotations.Inject; -import org.chorem.pollen.PollenContext; import org.chorem.pollen.ui.base.ContextLink; import org.chorem.pollen.PollenProperty; +import org.chorem.pollen.ui.services.PollenManager; /** * FeedLink @@ -21,11 +21,11 @@ public class FeedContextLink implements ContextLink { @Inject - private PollenContext pollen; + private PollenManager manager; @Override public String getContextPath() { - return pollen.getProperty(PollenProperty.FEED_DIR); + return manager.getProperty(PollenProperty.FEED_DIR); } @Override Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/LoginComponent.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/LoginComponent.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/LoginComponent.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -55,13 +55,13 @@ * Champ login du formulaire d'identification */ @Property - private String loginComp; + private String connectionLogin; /** * Champ password du formulaire d'identification */ @Property - private String passwordComp; + private String connectionPassword; @Inject private Messages messages; @@ -82,14 +82,13 @@ // Récupération de l'utilisateur identifié UserAccount current; try { - current = serviceUser.connect(loginComp, - manager.encodePassword(passwordComp)); + current = serviceUser.connect(connectionLogin, connectionPassword); if (current != null) { user = current; } else { feedback.addError(messages.get("loginFailed")); } - } catch (PollenBusinessException ex) { + } catch (PollenBusinessException eee) { // TODO feedback.addError(messages.get("loginFailed")); } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/Index.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/Index.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/Index.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -16,9 +16,9 @@ package org.chorem.pollen.ui.pages; -import org.apache.tapestry5.annotations.Property; +import org.apache.tapestry5.annotations.InjectComponent; +import org.chorem.pollen.ui.components.Border; import org.chorem.pollen.ui.data.AddressBar; -import org.chorem.pollen.ui.data.AddressBarItem; /** * Page de départ de l'application. @@ -30,7 +30,18 @@ */ public class Index { + @InjectComponent + private Border border; + public AddressBar getAddressBar() { return AddressBar.newEmptyBar().appendCurrent("Pollen"); } + + public void addInfo(String message) { + border.addInfo(message); + } + + public void addError(String message) { + border.addError(message); + } } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/admin/UsersAdmin.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/admin/UsersAdmin.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/admin/UsersAdmin.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -31,13 +31,13 @@ import org.apache.tapestry5.annotations.SessionState; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; -import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenProperty; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.mail.PreventRuleManager; import org.chorem.pollen.service.ServiceUser; import org.chorem.pollen.ui.components.FeedBack; import org.chorem.pollen.ui.data.AddressBarItem; +import org.chorem.pollen.ui.services.PollenManager; /** * Classe d'administration des comptes utilisateurs. Si l'utilisateur n'est pas @@ -204,14 +204,14 @@ } @Inject - private PollenContext pollen; + private PollenManager manager; /** Envoi du mail de notification */ private void sendMailNotification(UserAccount newUser, String password) { Map<String, String> data = new HashMap<String, String>(); - data.put("host", pollen.getProperty(PollenProperty.EMAIL_HOST)); - data.put("port", pollen.getProperty(PollenProperty.EMAIL_PORT)); - data.put("from", pollen.getProperty(PollenProperty.EMAIL_FROM)); + data.put("host", manager.getProperty(PollenProperty.EMAIL_HOST)); + data.put("port", manager.getProperty(PollenProperty.EMAIL_PORT)); + data.put("from", manager.getProperty(PollenProperty.EMAIL_FROM)); data.put("to", newUser.getEmail()); data.put("title", messages.format("registerEmail_subject", newUser .getLogin())); Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/poll/VoteForPoll.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/poll/VoteForPoll.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/poll/VoteForPoll.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -42,7 +42,6 @@ import org.apache.tapestry5.ioc.annotations.Inject; import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.PollenBusinessException.PollenExceptionType; -import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenProperty; import org.chorem.pollen.entity.Choice; import org.chorem.pollen.entity.Comment; @@ -60,6 +59,7 @@ import org.chorem.pollen.ui.data.AddressBar; import org.chorem.pollen.ui.data.ChoiceField; import org.chorem.pollen.ui.data.PollUri; +import org.chorem.pollen.ui.services.PollenManager; import org.chorem.pollen.ui.services.ServiceImage; import org.slf4j.Logger; @@ -932,7 +932,7 @@ private Messages messages; @Inject - private PollenContext pollen; + private PollenManager manager; @Property private PollUri uri; @@ -1171,7 +1171,7 @@ public int getPagerRange() { return Integer.parseInt( - pollen.getProperty(PollenProperty.NB_VOTES_PER_PAGE)); + manager.getProperty(PollenProperty.NB_VOTES_PER_PAGE)); } public String getNoPagerText() throws PollenBusinessException { Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -16,9 +16,14 @@ package org.chorem.pollen.ui.pages.user; +import java.util.Locale; +import org.apache.commons.lang.StringUtils; import org.apache.tapestry5.BindingConstants; +import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.IncludeStylesheet; +import org.apache.tapestry5.annotations.InjectComponent; +import org.apache.tapestry5.annotations.Log; import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.annotations.Property; @@ -26,12 +31,15 @@ import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.PasswordField; import org.apache.tapestry5.corelib.components.TextField; -import org.apache.tapestry5.corelib.components.Zone; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; +import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.service.ServiceUser; -import org.chorem.pollen.ui.data.AddressBarItem; +import org.chorem.pollen.ui.components.Border; +import org.chorem.pollen.ui.data.AddressBar; +import org.chorem.pollen.ui.services.PollenManager; +import org.slf4j.Logger; /** * Classe de la page d'un utilisateur. @@ -43,6 +51,15 @@ @IncludeStylesheet("context:css/account.css") public class UserProfile { + @Inject + private Logger logger; + + @Inject + private PollenManager manager; + + @InjectComponent + private Border border; + /** * Objet de session représentant l'utilisateur identifié. */ @@ -52,137 +69,121 @@ @Property private boolean userExists; - /** - * Utilisateur dont les données sont affichées et modifiées dans le - * formulaire - */ + @Parameter(defaultPrefix = BindingConstants.MESSAGE, value = "title") @Property - @Persist - private UserAccount newUser; + private String title; - /** Ancien mot de passe */ - @Persist - private String oldEmail; + @Inject + private ServiceUser serviceUser; - @Component - private Zone myAccountZone; + @Inject + private Messages messages; - @Component - private Form myAccountForm; + public AddressBar getAddressBar() { + return AddressBar.newBar().appendCurrent(title); + } - @Component(id = "password") - private PasswordField passwordField; + /***************************** DISPLAY MODE *******************************/ - @Component(id = "newPassword1") - private PasswordField newPasswordField; - - @Component(id = "email") - private TextField emailField; - /** - * Champ password du formulaire d'enregsitrement d'un utilisateur + * State of the form. is currently edited or not. */ + @Persist(PersistenceConstants.FLASH) @Property - private String password; + private boolean edited; + + void onActionFromEditAccount() { + edited = true; + // Don't refresh the form zone to reset border messages + } + /***************************** EDIT MODE **********************************/ + /** - * Champ password1 du formulaire d'enregsitrement d'un utilisateur + * UserAccount for form edition */ - @Property - private String newPassword1; - /** - * Champ password2 du formulaire d'enregsitrement d'un utilisateur - */ - @Property - private String newPassword2; + private UserAccount userEditable; @Inject - private Messages messages; + private Locale currentLocale; - @Parameter(defaultPrefix = BindingConstants.MESSAGE, value = "title") - @Property - private String title; + @InjectComponent + private Form accountForm; - @SuppressWarnings("unused") - @Property - private AddressBarItem[] address; + @Component(id = "password") + private PasswordField passwordField; - /** - * Vrai lorsque l'utilisateur modifie son compte. - */ - @SuppressWarnings("unused") - @Property - private boolean modify = false; + @Component(id = "newPassword1") + private PasswordField newPasswordField; - /** Injection des services */ - @Inject - private ServiceUser serviceUser; -// @Inject -// private ServiceAuth serviceAuth; + @Component(id = "email") + private TextField emailField; /** - * Méthode appelée quand l'utilisateur modifie ses données - * - * @return la zone de compte mise à jour + * Property to check password (newPassword must be equals to passwordVerify) */ - Object onSuccessFromMyAccountForm() { - modify = true; -// -// // L'utilisateur a renseigné le mauvais mot de passe -// if (!serviceAuth.isLoginRight(newUser.getLogin(), MD5.encode(password))) { -// myAccountForm.recordError(passwordField, messages -// .get("badPassword")); -// } -// -// // L'utilisateur ne s'est pas trompé en répétant son mot de passe -// if (newPassword1 != null && !newPassword1.equals("")) { -// if (!newPassword1.equals(newPassword2)) { -// myAccountForm.recordError(newPasswordField, messages -// .get("passwords-dont-match")); -// } -// } -// -// // L'email existe déjà -// if (!oldEmail.equals(newUser.getEmail())) { -// if (serviceUser.isUserEmailExisting(newUser.getEmail())) { -// myAccountForm.recordError(emailField, messages -// .get("emailAlreadyExists")); -// } -// } -// -// // Modification de l'utilisateur -// if (!myAccountForm.getHasErrors()) { -// if (serviceUser.updateUser(newUser)) { -// if (newPassword1 != null && !newPassword1.equals("")) { -// serviceUser.updatePasswordUser(newUser, MD5 -// .encode(newPassword1)); -// } -// modify = false; -// } -// } + @Property + private String passwordVerify; - return myAccountZone.getBody(); + public UserAccount getUserEditable() { + if (userEditable == null) { + userEditable = user; + } + return userEditable; } /** - * Méthode appelée quand l'utilisateur veut modifier son compte - * - * @return le formulaire de modification du compte + * ON_VALIDATE_FORM :: <br \> + * UI validation : check if the two passwords are equals. <br \> + * BUSINESS validation : execute {@link org.chorem.pollen.service.ServiceUser#updateUser(org.chorem.pollen.entity.UserAccount) } + * which throws errors + * {@link org.chorem.pollen.PollenBusinessException.PollenExceptionType.USER_WRONG_PASSWORD} + * and {@link org.chorem.pollen.PollenBusinessException.PollenExceptionType.USER_EMAIL_EXIST}. */ - Object onActionFromModifyButton() { - modify = true; - return myAccountZone.getBody(); + @Log + void onValidateFormFromAccountForm() { + // Check newPassword that must be equals to passwordVerify + String newPassword = userEditable.getNewPassword(); + if (StringUtils.isNotEmpty(newPassword) && + !newPassword.equals(passwordVerify)) { + accountForm.recordError(newPasswordField, + messages.get("pollen.ui.user.passwordsDontMatch")); + } + // If no UI errors, call business to save the user + if (!accountForm.getHasErrors()) { + try { + // Update the user + if (logger.isDebugEnabled()) { + logger.debug("TopiaId : " + user.getTopiaId()); + logger.debug("Login : " + user.getLogin()); + logger.debug("Password : " + user.getPassword()); + logger.debug("NewPassword : " + user.getNewPassword()); + } + serviceUser.updateUser(userEditable); + } catch (PollenBusinessException eee) { + String message = manager.getErrorMessage(eee, messages, logger); + switch (eee.getType()) { + case USER_WRONG_PASSWORD: + accountForm.recordError(passwordField, message); break; + case USER_EMAIL_EXIST: + accountForm.recordError(emailField, message); + } + } + } } - /** - * Initialisation de l'affichage - */ - void setupRender() { - address = new AddressBarItem[] { new AddressBarItem("Pollen", "Index"), - new AddressBarItem(title, null) }; - if (userExists) { - newUser = user; - oldEmail = user.getEmail(); - } + @Log + Object onSuccessFromAccountForm() { + border.addInfo(messages.get("pollen.ui.user.updateSuccess")); + return this; } + + @Log + Object onFailureFromAccountForm() { + // Stay in edited mode to show errors + edited = true; + // Reset new password + userEditable.setNewPassword(null); + return accountForm; + } } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserRegister.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserRegister.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserRegister.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -18,10 +18,12 @@ import java.util.Locale; +import org.apache.commons.lang.StringUtils; import org.apache.tapestry5.BindingConstants; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.IncludeStylesheet; import org.apache.tapestry5.annotations.InjectComponent; +import org.apache.tapestry5.annotations.InjectPage; import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.SessionState; @@ -31,14 +33,14 @@ import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; import org.chorem.pollen.PollenBusinessException; -import org.chorem.pollen.PollenContext; import org.chorem.pollen.bean.PollenEmail; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.service.ServiceEmail; import org.chorem.pollen.service.ServiceUser; +import org.chorem.pollen.ui.components.Border; import org.chorem.pollen.ui.data.AddressBar; import org.chorem.pollen.ui.pages.Index; -import org.chorem.pollen.ui.utils.BusinessUtils; +import org.chorem.pollen.ui.services.PollenManager; import org.slf4j.Logger; /** @@ -55,8 +57,11 @@ @Inject private Logger logger; + @InjectComponent + private Border border; + /** - * Objet de session représentant l'utilisateur identifié. + * Identified user */ @SessionState private UserAccount user; @@ -64,16 +69,14 @@ @Property private boolean userExists; - /** Injection des services */ @Inject private ServiceUser serviceUser; - /** Injection des services */ @Inject private ServiceEmail serviceEmail; @Inject - private PollenContext pollen; + private PollenManager manager; @Inject private Messages messages; @@ -83,17 +86,17 @@ private String title; /** - * Objet de session représentant l'url du site. + * Session property loaded from configuration to know what is the current + * server url */ @SessionState private String siteURL; - /** Locale courante */ @Inject private Locale currentLocale; /** - * Utilisateur créé via le formulaire + * New user to create */ private UserAccount newUser; @@ -110,22 +113,16 @@ private PasswordField passwordField; /** - * Champ password1 du formulaire d'enregsitrement d'un utilisateur + * password2 field to verify if equals to password1 */ @Property - private String password1; - /** - * Champ password2 du formulaire d'enregsitrement d'un utilisateur - */ - @Property - private String password2; + private String passwordVerify; - /** - * Initialisation de l'affichage - */ - void setupRender() { - } + private String passwordForEmail; + @InjectPage + private Index index; + public AddressBar getAddressBar() { return AddressBar.newBar().appendCurrent(title); } @@ -138,15 +135,40 @@ } /** - * ON_VALIDATE_FORM :: Check if two passwords are equals. + * ON_VALIDATE_FORM :: <br \> + * UI validation : check if the two passwords are equals. <br \> + * BUSINESS validation : execute {@link org.chorem.pollen.service.ServiceUser#createUser(org.chorem.pollen.entity.UserAccount) } + * which throws errors + * {@link org.chorem.pollen.PollenBusinessException.PollenExceptionType.USER_LOGIN_EXIST} + * and {@link org.chorem.pollen.PollenBusinessException.PollenExceptionType.USER_EMAIL_EXIST}. */ void onValidateFormFromRegister() { - // L'utilisateur s'est pas trompé en répétant son mot de passe - if (!password1.equals(password2)) { - password1 = null; + // Check newPassword that must be equals to passwordVerify + String password = newUser.getNewPassword(); + if (!password.equals(passwordVerify)) { register.recordError(passwordField, - messages.get("passwords-dont-match")); + messages.get("pollen.ui.user.passwordsDontMatch")); } + + // If no UI errors, call business to save the user + if (!register.getHasErrors()) { + try { + // Set passwordForEmail, newPassword will be reset after + // createUser + passwordForEmail = newUser.getNewPassword(); + + // Saving new user + serviceUser.createUser(newUser); + } catch (PollenBusinessException eee) { + String message = manager.getErrorMessage(eee, messages, logger); + switch (eee.getType()) { + case USER_EMAIL_EXIST: + register.recordError(emailField, message); break; + case USER_LOGIN_EXIST: + register.recordError(loginField, message); + } + } + } } /** @@ -157,38 +179,38 @@ * @return the form if errors are recorded, or Index page otherwise */ Object onSuccessFromRegister() { - try { - // Encode the password before saving user - getNewUser().setPassword(pollen.encodePassword(password1)); - - // Saving new user - serviceUser.createUpdateUser(getNewUser()); + // Set the newUser in session : connect the new registered user + user = newUser; - // Send an email to the new user - PollenEmail mail = serviceEmail.getNewEmail(getNewUser()); + index.addInfo( + messages.format("pollen.ui.user.autoConnection", + user.getLogin())); - mail.setSubject( - messages.format("pollen.mail.userRegister.subject", - getNewUser().getLogin())); - mail.setContent( - messages.format("pollen.mail.userRegister.content", - getNewUser().getDisplayName(), getNewUser().getLogin(), - password1, siteURL)); + // Send an email to the new user if not empty + if (StringUtils.isNotEmpty(user.getEmail())) { + try { + PollenEmail mail = serviceEmail.getNewEmail(user); - serviceEmail.sendEmail(mail); + mail.setSubject( + messages.format("pollen.email.userRegister.subject", + user.getLogin())); + mail.setContent( + messages.format("pollen.email.userRegister.content", + user.getDisplayName(), user.getLogin(), + passwordForEmail, siteURL)); - return Index.class; - } catch (PollenBusinessException eee) { - String message = - BusinessUtils.getErrorMessage(eee, messages, logger); - switch (eee.getType()) { - case USER_EMAIL_EXIST: - register.recordError(emailField, message); break; - case USER_LOGIN_EXIST: - register.recordError(loginField, message); + serviceEmail.sendEmail(mail); + + index.addInfo( + messages.format("pollen.ui.user.sendRegisterEmail", + user.getEmail())); + + } catch (PollenBusinessException eee) { + String message = manager.getErrorMessage(eee, messages, logger); + index.addError(message); } } - return register; + return index; } /** @@ -197,6 +219,8 @@ * @return the form */ Object onFailureFromRegister() { + // Reset password from session + newUser.setNewPassword(null); return register; } } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -29,7 +29,6 @@ import org.apache.tapestry5.services.ApplicationStateContribution; import org.apache.tapestry5.services.ApplicationStateCreator; import org.apache.tapestry5.upload.services.UploadSymbols; -import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenContextImpl; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.entity.UserAccountImpl; @@ -40,6 +39,8 @@ import org.chorem.pollen.service.ServiceUser; import org.chorem.pollen.service.ServiceUserImpl; import org.chorem.pollen.ui.data.PollUri; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This module is automatically included as part of the Tapestry IoC Registry, @@ -50,18 +51,18 @@ */ public class AppModule { + private static Logger logger = LoggerFactory.getLogger(AppModule.class); + public static void bind(ServiceBinder binder) { } /** * Build the application manager. * - * @param hub to register the manager for tapestry registry shutdown * @return PollenManager */ - public static PollenManager buildPollenManager(RegistryShutdownHub hub) { + public static PollenManager buildPollenManager() { PollenManager manager = new PollenManager(new PollenContextImpl()); - hub.addRegistryShutdownListener(manager); return manager; } @@ -87,8 +88,31 @@ return new ServiceImageImpl(manager.getContext()); } + /** + * Execute PollenManager when registry startup. + * The manager will be instantiated using + * {@link #buildPollenManager(org.apache.tapestry5.ioc.services.RegistryShutdownHub) }. + * The serviceUser is needed to start the application. + * + * @param configuration to add the manager to registry startup + * @param manager to launch at startup + * @param shutdownHub to register manager for registry shutdown + */ + public static void contributeRegistryStartup( + OrderedConfiguration<Runnable> configuration, + PollenManager manager, RegistryShutdownHub shutdownHub) { + if (logger.isInfoEnabled()) { + logger.info("Execute contributeRegistryStartup"); + } + shutdownHub.addRegistryShutdownListener(manager); + configuration.add("PollenStartup", manager); + } + public static void contributeApplicationDefaults( MappedConfiguration<String, String> configuration) { + if (logger.isInfoEnabled()) { + logger.info("Execute contributeApplicationDefaults"); + } // Contributions to ApplicationDefaults will override any contributions to // FactoryDefaults (with the same key). Here we're restricting the supported // locales to just "en" (English). As you add localised message catalogs and other assets, @@ -109,6 +133,24 @@ } /** + * Contribution SymbolSource service to access our configuration + * symbols from our services, pages and components. + * + * @param configuration + * @param symbolProvider PollenManager + */ + public static void contributeSymbolSource( + OrderedConfiguration<SymbolProvider> configuration, + @InjectService("PollenManager") SymbolProvider symbolProvider) { + if (logger.isInfoEnabled()) { + logger.info("Execute contributeSymbolSource"); + } + configuration.add( + "PollenManager", symbolProvider, + "after:SystemProperties", "before:ApplicationDefaults"); + } + + /** * TypeCoercion for PollUri. This will convert automatically between String * and PollUri. So pollUri can be used in activation/passivation page * context. @@ -116,7 +158,10 @@ * @param configuration */ public static void contributeTypeCoercer( - Configuration<CoercionTuple> configuration) { + Configuration<CoercionTuple<?, ?>> configuration) { + if (logger.isInfoEnabled()) { + logger.info("Execute contributeTypeCoercer"); + } Coercion<String, PollUri> coercion1 = new Coercion<String, PollUri>() { @Override @@ -154,35 +199,18 @@ // return new BackgroundWorkerImpl(messages, servicePoll, context); // } - /** - * Make configuration from a Properties file available as symbols. - * @param context - * @return - */ - public PropertiesFileSymbolProvider buildConfigPropertiesFileSymbolProvider( - @InjectService("PollenContext") PollenContext context) { - return new PropertiesFileSymbolProvider(context); - } /** - * Contribution SymbolSource service so that we can access our configuration - * symbols from our services, pages and components. - */ - public static void contributeSymbolSource( - OrderedConfiguration<SymbolProvider> configuration, - @InjectService("ConfigPropertiesFileSymbolProvider") SymbolProvider configPropertiesFileSymbolProvider) { - configuration.add("ConfigPropertiesFile", - configPropertiesFileSymbolProvider, "after:SystemProperties", - "before:ApplicationDefaults"); - } - - - /** - * Used to instanciate SessionState WaoUser when session expires. + * Used to instanciate SessionState UserAccount when session expires. * * @param configuration to add the ApplicationStateCreator. */ - public void contributeApplicationStateManager(MappedConfiguration<Class<?>, ApplicationStateContribution> configuration) { + public void contributeApplicationStateManager(MappedConfiguration<Class<?>, + ApplicationStateContribution> configuration) { + if (logger.isInfoEnabled()) { + logger.info("Execute contributeApplicationStateManager"); + } + ApplicationStateCreator<UserAccount> creator = new ApplicationStateCreator<UserAccount>() { @Override Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PollenManager.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PollenManager.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PollenManager.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -21,13 +21,19 @@ package org.chorem.pollen.ui.services; +import java.util.Arrays; import java.util.Date; +import java.util.Map; +import java.util.Properties; +import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.services.RegistryShutdownListener; +import org.apache.tapestry5.ioc.services.SymbolProvider; +import org.apache.tapestry5.ioc.util.CaseInsensitiveMap; +import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenProperty; import org.nuiton.util.ApplicationConfig; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * WaoManager @@ -40,11 +46,16 @@ * Mise a jour: $Date$ * par : $Author$ */ -public class PollenManager implements Runnable, RegistryShutdownListener { +public class PollenManager implements Runnable, + RegistryShutdownListener, + SymbolProvider { - private static final Logger log = - LoggerFactory.getLogger(PollenManager.class); +// private static final Logger logger = +// LoggerFactory.getLogger(PollenManager.class); + private final Map<String, String> propertiesMap = + new CaseInsensitiveMap<String>(); + private PollenContext context; /** @@ -62,8 +73,19 @@ @Override public void run() { context.start(); + // Copy properties to propertiesMap (insentitive) for SymbolProvider + Properties properties = getConfiguration().getOptions(); + for (Object key : properties.keySet()) { + propertiesMap.put((String)key, + properties.getProperty((String) key)); + } } + @Override + public String valueForSymbol(String key) { + return propertiesMap.get(key); + } + /** * Called to stop the application */ @@ -93,8 +115,19 @@ return context.getCurrentDate(); } - public String encodePassword(String password) { - return context.encodePassword(password); + public String getErrorMessage(PollenBusinessException eee, + Messages messages, Logger logger) { + if (logger.isDebugEnabled()) { + logger.debug("ERROR from business : " + eee.getMessage() + + " _ args = " + Arrays.toString(eee.getArgs())); + } + String message = null; + if (eee.getArgs() != null) { + message = messages.format(eee.getMessage(), eee.getArgs()); + } else { + message = messages.get(eee.getMessage()); + } + return message; } } Deleted: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PropertiesFileSymbolProvider.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PropertiesFileSymbolProvider.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/PropertiesFileSymbolProvider.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,138 +0,0 @@ -package org.chorem.pollen.ui.services; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Map; -import java.util.Properties; - -import org.apache.tapestry5.ioc.services.SymbolProvider; -import org.apache.tapestry5.ioc.util.CaseInsensitiveMap; -import org.chorem.pollen.PollenContext; -import org.slf4j.Logger; - -public class PropertiesFileSymbolProvider implements SymbolProvider { - - private final Map<String, String> propertiesMap = new CaseInsensitiveMap<String>(); - - private PollenContext context; - - /** - * Instantiate a new PropertiesFileSymbolProvider using a given resource - * name - * - * @param logger the logger to log error messages to - * @param resourceName the name of the resource to load - * @param classPath whether to look on the classpath or filesystem - */ - public PropertiesFileSymbolProvider(Logger logger, String resourceName, - boolean classPath) { - try { - InputStream in; - - if (classPath) { - in = ClassLoader.getSystemResourceAsStream(resourceName); - - // ClassLoader.getSystemResourceAsStream() returns null if - // the resource cannot be found on the classpath - if (in == null) - throw new FileNotFoundException(); - } else - in = new FileInputStream(resourceName); - - initialize(logger, in); - - } catch (FileNotFoundException e) { - String msg = "Could not find '" + resourceName + "'"; - - logger.error(msg); - - throw new IllegalArgumentException(msg, e); - } - } - - /** - * Instantiate a new PropertiesFileSymbolProvider using a given resource - * name (looking in filesystem and classpath) - * - * @param context PollenContext - */ - public PropertiesFileSymbolProvider(PollenContext context) { - Properties conf = context.getConfiguration().getOptions(); - initializeProperties(conf); - } - - /** - * Instantiate a PropertiesFileSymbolProvider using a given InputStream - * - * @param logger the logger - * @param in an InputStream representing the resource - */ - public PropertiesFileSymbolProvider(Logger logger, InputStream in) { - initialize(logger, in); - } - - /** - * Instantiate a PropertiesFileSymbolProvider from a given URL. - * - * @param logger the logger - * @param url an URL to open - */ - public PropertiesFileSymbolProvider(Logger logger, URL url) { - try { - initialize(logger, url.openStream()); - } catch (IOException e) { - String msg = "IOException while opening URL '" + url + "': " - + e.getMessage(); - - logger.error(msg); - - throw new IllegalArgumentException(msg, e); - } - } - - /** - * Instantiate a PropertiesFileSymbolProvider from a given Properties. - * - * @param logger the logger - * @param properties a Properties object - */ - public PropertiesFileSymbolProvider(Logger logger, Properties properties) { - initializeProperties(properties); - } - - private void initialize(Logger logger, InputStream in) { - Properties properties = new Properties(); - - try { - properties.load(in); - - for (Object key : properties.keySet()) { - propertiesMap.put((String) key, properties - .getProperty((String) key)); - } - } catch (IOException e) { - String msg = "IOEception while loading properties: " - + e.getMessage(); - - logger.error(msg); - - throw new IllegalArgumentException(msg, e); - } - } - - private void initializeProperties(Properties properties) { - for (Object key : properties.keySet()) { - propertiesMap.put((String) key, properties - .getProperty((String) key)); - } - } - - @Override - public String valueForSymbol(String arg0) { - return propertiesMap.get(arg0); - } - -} \ No newline at end of file Deleted: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/utils/BusinessUtils.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/utils/BusinessUtils.java 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/utils/BusinessUtils.java 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,37 +0,0 @@ - -package org.chorem.pollen.ui.utils; - -import java.util.Arrays; -import org.apache.tapestry5.ioc.Messages; -import org.chorem.pollen.PollenBusinessException; -import org.slf4j.Logger; - -/** - * BusinessUtils - * - * Created: 30 mars 2010 - * - * @author fdesbois - * @version $Revision$ - * - * Mise a jour: $Date$ - * par : $Author$ - */ -public class BusinessUtils { - - public static String getErrorMessage( - PollenBusinessException eee, Messages messages, Logger logger) { - if (logger.isDebugEnabled()) { - logger.debug("ERROR from business : " + eee.getMessage() + - " _ args = " + Arrays.toString(eee.getArgs())); - } - String message = null; - if (eee.getArgs() != null) { - message = messages.format(eee.getMessage(), eee.getArgs()); - } else { - message = messages.get(eee.getMessage()); - } - return message; - } - -} Modified: trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties =================================================================== --- trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,6 +1,6 @@ # User registration emails -pollen.mail.userRegister.subject=[Pollen] Confirmation de cr\u00E9ation du compte %s -pollen.mail.userRegister.content=Bienvenue %1$s. Vous venez de cr\u00E9er un compte sur l'application de sondage en ligne Pollen.\n\nIdentifiant : %2$s\nMot de passe : %3$s\n\nVous pouvez d\u00E8s maintenant g\u00E9rer vos sondages en vous identifiant sur le site : \n%4$s +pollen.email.userRegister.subject=[Pollen] Confirmation de cr\u00E9ation du compte %s +pollen.email.userRegister.content=Bienvenue %1$s. Vous venez de cr\u00E9er un compte sur l'application de sondage en ligne Pollen.\n\nIdentifiant : %2$s\nMot de passe : %3$s\n\nVous pouvez d\u00E8s maintenant g\u00E9rer vos sondages en vous identifiant sur le site : \n%4$s # Poll creation emails creatorEmail_subject=[Pollen] Cr\u00E9ation d'un sondage (%s) @@ -41,6 +41,11 @@ return=Retour help=Aide +pollen.ui.user.autoConnection=Vous \u00EAtes maintenant connect\u00E9 avec l'identifiant %1$s. +pollen.ui.user.sendRegisterEmail=Un email vous a \u00E9t\u00E9 envoy\u00E9 \u00E0 l'adresse %1$s. +pollen.ui.user.passwordsDontMatch=Les deux mots de passe ne correspondent pas. +pollen.ui.user.updateSuccess=Modification enregistr\u00E9e avec succ\u00E8s. + pollen.ui.choice.delete.confirm=Etes-vous s\u00FBr de vouloir d\u00E9finitivement supprimer ce choix ? pollen.ui.choice.delete.title=Supprimer ce choix pollen.ui.vote.noVote=Aucune personne n'a encore particip\u00E9 au sondage Modified: trunk/pollen-ui/src/main/resources/log4j.properties =================================================================== --- trunk/pollen-ui/src/main/resources/log4j.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/resources/log4j.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,5 +1,5 @@ # Default to info level output; this is very handy if you eventually use Hibernate as well. -log4j.rootCategory=warn, A1 +log4j.rootCategory=warn, A1, globalfile # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender @@ -8,6 +8,17 @@ log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%p] %c{2} %m%n +log4j.appender.globalfile=org.apache.log4j.RollingFileAppender +# pollen.log.home must be defined when starting server +# ex : -Dpollen.log.home=/home/user/.local/pollen +log4j.appender.globalfile.File=${pollen.log.home}/pollen.log +log4j.appender.globalfile.MaxFileSize=500KB +log4j.appender.globalfile.Append=true +log4j.appender.globalfile.MaxBackupIndex=10 +log4j.appender.globalfile.Threshold=TRACE +log4j.appender.globalfile.layout=org.apache.log4j.PatternLayout +log4j.appender.globalfile.layout.ConversionPattern=%d{yyyy/MM/dd hh:mm:ss} %5p (%F:%L) %m%n + # Service category names are the name of the defining module class # and then the service id. log4j.category.org.chorem.test.services.AppModule.TimingFilter=info Modified: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/LoginComponent.tml =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/LoginComponent.tml 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/LoginComponent.tml 2010-04-09 23:28:55 UTC (rev 2969) @@ -4,12 +4,12 @@ <legend>${message:connectionLegend}</legend> <t:feedback t:id="loginCompFeedback" /> <div> - <t:label for="loginComp" /> - <input t:type="TextField" t:id="loginComp" validate="required" /> + <t:label for="connectionLogin" /> + <input t:type="TextField" t:id="connectionLogin" validate="required" /> </div> <div> - <t:label for="passwordComp" /> - <input t:type="PasswordField" t:id="passwordComp" validate="required" /> + <t:label for="connectionPassword" /> + <input t:type="PasswordField" t:id="connectionPassword" validate="required" /> </div> <div class="buttons"> <input t:id="submitLoginCompForm" t:type="Submit" t:value="${message:loginSubmit}" /> Deleted: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_en.properties =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_en.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_en.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,23 +0,0 @@ -title=My Account -login-label=User name -password-label=Password * -newPassword1-label=New password -newPassword2-label=Reenter new password -firstName-label=First name -lastName-label=Last name -email-label=Em@il * -submit-label=Submit -modify=Modify -connectionInfoLegend=Connection information -userInfoLegend=User information -email-regexp=^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$ -email-regexp-message=Invalid email. -login-required-message=You must provide a username. -password1-required-message=You must provide a password. -password1-minlength-message=Your password must be at least 6 characters long. -password2-required-message=You must repeat your password for confirmation. -password2-minlength-message=Your password must be at least 6 characters long. -passwords-dont-match=Two versions of password do not match. -noUser=You must be logged to access to your account.\n Please fill the form below. -badPassword=Your password is invalid. -emailAlreadyExists=A user already registered with this email. \ No newline at end of file Deleted: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_fr.properties =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_fr.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_fr.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,23 +0,0 @@ -title=Mon Compte -login-label=Identifiant -password-label=Mot de passe * -newPassword1-label=Nouveau mot de passe -newPassword2-label=R\u00E9p\u00E9tez votre nouveau mot de passe -firstName-label=Pr\u00E9nom -lastName-label=Nom -email-label=Em@il * -submit-label=Valider -modify=Modifier -connectionInfoLegend=Informations de connexion -userInfoLegend=Informations de l'utilisateur -email-regexp=^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$ -email-regexp-message=Email invalide. -login-required-message=Vous devez fournir un identifiant. -password1-required-message=Vous devez fournir un mot de passe. -password1-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. -password2-required-message=Vous devez r\u00E9p\u00E9ter votre mot de passe pour confirmation. -password2-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. -passwords-dont-match=Les deux mots de passe ne correspondent pas. -noUser=Vous devez \u00EAtre identifi\u00E9 pour pouvoir acc\u00E9der \u00E0 votre compte.\n Veuillez remplir le formulaire ci-dessous. -badPassword=Votre mot de passe est invalide. -emailAlreadyExists=Un utilisateur est d\u00E9j\u00E0 enregistr\u00E9 avec cet email. \ No newline at end of file Copied: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_en.properties (from rev 2966, trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_en.properties) =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_en.properties (rev 0) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_en.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -0,0 +1,23 @@ +title=My Account +login-label=User name +password-label=Password * +newPassword1-label=New password +newPassword2-label=Reenter new password +firstName-label=First name +lastName-label=Last name +email-label=Em@il * +submit-label=Submit +editAccount-action=Modify +connectionInfoLegend=Connection information +userInfoLegend=User information +email-regexp=^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$ +email-regexp-message=Invalid email. +login-required-message=You must provide a username. +password1-required-message=You must provide a password. +password1-minlength-message=Your password must be at least 6 characters long. +password2-required-message=You must repeat your password for confirmation. +password2-minlength-message=Your password must be at least 6 characters long. +passwords-dont-match=Two versions of password do not match. +noUser=You must be logged to access to your account.\n Please fill the form below. +badPassword=Your password is invalid. +emailAlreadyExists=A user already registered with this email. \ No newline at end of file Property changes on: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_en.properties ___________________________________________________________________ Added: svn:mergeinfo + Copied: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_fr.properties (from rev 2966, trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/Account_fr.properties) =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_fr.properties (rev 0) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_fr.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -0,0 +1,23 @@ +title=Mon Compte +login-label=Identifiant +password-label=Mot de passe * +newPassword1-label=Nouveau mot de passe +passwordVerify-label=R\u00E9p\u00E9tez votre nouveau mot de passe +firstName-label=Pr\u00E9nom +lastName-label=Nom +email-label=Em@il +submit-label=Valider +edit-action=Modifier +cancel-action=Annuler +connectionInfoLegend=Informations de connexion +userInfoLegend=Informations de l'utilisateur +email-regexp=^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$ +email-regexp-message=Email invalide. +login-required-message=Vous devez fournir un identifiant. +password1-required-message=Vous devez fournir un mot de passe. +password1-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. +passwordVerify-required-message=Vous devez r\u00E9p\u00E9ter votre mot de passe pour confirmation. +passwordVerify-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. +noUser=Vous devez \u00EAtre identifi\u00E9 pour pouvoir acc\u00E9der \u00E0 votre compte.\n Veuillez remplir le formulaire ci-dessous. +badPassword=Votre mot de passe est invalide. +emailAlreadyExists=Un utilisateur est d\u00E9j\u00E0 enregistr\u00E9 avec cet email. \ No newline at end of file Property changes on: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserProfile_fr.properties ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserRegister_fr.properties =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserRegister_fr.properties 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/pages/user/UserRegister_fr.properties 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,10 +1,10 @@ title=S'enregistrer login-label=Identifiant * password1-label=Mot de passe * -password2-label=R\u00E9p\u00E9tez votre mot de passe * +passwordVerify-label=R\u00E9p\u00E9tez votre mot de passe * firstName-label=Pr\u00E9nom lastName-label=Nom -email-label=Em@il * +email-label=Em@il submit-label=S'enregistrer connectionInfoLegend=Informations de connexion userInfoLegend=Informations de l'utilisateur @@ -13,6 +13,6 @@ login-required-message=Vous devez fournir un identifiant. password1-required-message=Vous devez fournir un mot de passe. password1-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. -password2-required-message=Vous devez r\u00E9p\u00E9ter votre mot de passe pour confirmation. -password2-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. +passwordVerify-required-message=Vous devez r\u00E9p\u00E9ter votre mot de passe pour confirmation. +passwordVerify-minlength-message=Votre mot de passe doit comporter au moins 6 caract\u00E8res. passwords-dont-match=Les deux mots de passe ne correspondent pas. \ No newline at end of file Modified: trunk/pollen-ui/src/main/webapp/css/common.css =================================================================== --- trunk/pollen-ui/src/main/webapp/css/common.css 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/webapp/css/common.css 2010-04-09 23:28:55 UTC (rev 2969) @@ -44,6 +44,7 @@ border: solid; border-color: #f00; border-width: 2px; + margin-bottom: 10px; } .fb-info { Deleted: trunk/pollen-ui/src/main/webapp/user/Account.tml =================================================================== --- trunk/pollen-ui/src/main/webapp/user/Account.tml 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/webapp/user/Account.tml 2010-04-09 23:28:55 UTC (rev 2969) @@ -1,95 +0,0 @@ - -<t:border t:address="address" t:pageLogo="literal:Creation" - xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> - <h1 class="titleCreation">${message:title}</h1> - <t:if test="userExists"> - - <t:zone t:id="myAccountZone" show="show" update="show"> - <div id="myAccountFormDiv"> - <t:form t:id="myAccountForm" zone="myAccountZone"> - <div id="myAccountError"> - <t:errors /> - </div> - - <FieldSet> - <legend>${message:connectionInfoLegend}</legend> - <div> - <label>${message:login-label}</label> - ${user.login} - </div> - <t:if test="modify"> - <div> - <t:label for="password" /> - <t:PasswordField t:id="password" t:value="password" t:validate="required,minlength=6" /> - </div> - <div> - <t:label for="newPassword1" /> - <t:PasswordField t:id="newPassword1" t:value="newPassword1" t:validate="minlength=6" /> - </div> - <div> - <t:label for="newPassword2" /> - <t:PasswordField t:id="newPassword2" t:value="newPassword2" t:validate="minlength=6" /> - </div> - </t:if> - </FieldSet> - - <FieldSet> - <legend>${message:userInfoLegend}</legend> - <div> - <t:label for="email" /> - <t:if test="modify"> - <t:TextField t:id="email" t:value="newUser.email" t:validate="required,regexp" /> - <p:else> - <t:if test="user.email"> - ${user.email} - <p:else>-</p:else> - </t:if> - </p:else> - </t:if> - </div> - <div> - <t:label for="firstName" /> - <t:if test="modify"> - <t:TextField t:id="firstName" t:value="newUser.firstName" /> - <p:else> - <t:if test="user.firstName"> - ${user.firstName} - <p:else>-</p:else> - </t:if> - </p:else> - </t:if> - </div> - <div> - <t:label for="lastName" /> - <t:if test="modify"> - <t:TextField t:id="lastName" t:value="newUser.lastName" /> - <p:else> - <t:if test="user.lastName"> - ${user.lastName} - <p:else>-</p:else> - </t:if> - </p:else> - </t:if> - </div> - </FieldSet> - - <div class="buttons"> - <t:if test="modify"> - <input type="submit" value="${message:submit-label}" /> - <p:else> - <t:actionLink t:id="modifyButton" t:zone="myAccountZone" style="text-decoration: none;"> - <input type="button" value="${message:modify}" /> - </t:actionLink> - </p:else> - </t:if> - </div> - </t:form> - </div> - </t:zone> - - <p:else> - <h4>${message:noUser}</h4> - <t:LoginComponent /> - </p:else> - </t:if> -</t:border> \ No newline at end of file Copied: trunk/pollen-ui/src/main/webapp/user/UserProfile.tml (from rev 2966, trunk/pollen-ui/src/main/webapp/user/Account.tml) =================================================================== --- trunk/pollen-ui/src/main/webapp/user/UserProfile.tml (rev 0) +++ trunk/pollen-ui/src/main/webapp/user/UserProfile.tml 2010-04-09 23:28:55 UTC (rev 2969) @@ -0,0 +1,98 @@ + +<t:border t:addressBar="addressBar" t:pageLogo="literal:Creation" + xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> + <h1 class="titleCreation">${message:title}</h1> + <t:if test="userExists"> + + <t:zone t:id="accountZone" show="show" update="show"> + <t:form t:id="accountForm" zone="accountZone"> + <div id="myAccountFormDiv"> + <div id="myAccountError"> + <t:errors /> + </div> + + <FieldSet> + <legend>${message:connectionInfoLegend}</legend> + <div> + <label>${message:login-label}</label> + ${user.login} + </div> + <t:if test="edited"> + <div> + <t:label for="password" /> + <t:PasswordField t:id="password" t:value="userEditable.password" t:validate="required,minlength=6" /> + </div> + <div> + <t:label for="newPassword1" /> + <t:PasswordField t:id="newPassword1" t:value="userEditable.newPassword" t:validate="minlength=6" /> + </div> + <div> + <t:label for="passwordVerify" /> + <t:PasswordField t:id="passwordVerify" t:value="passwordVerify" t:validate="minlength=6" /> + </div> + </t:if> + </FieldSet> + + <FieldSet> + <legend>${message:userInfoLegend}</legend> + <div> + <t:label for="email" /> + <t:if test="edited"> + <t:TextField t:id="email" t:value="userEditable.email" t:validate="regexp" /> + <p:else> + <t:if test="user.email"> + ${user.email} + <p:else>-</p:else> + </t:if> + </p:else> + </t:if> + </div> + <div> + <t:label for="firstName" /> + <t:if test="edited"> + <t:TextField t:id="firstName" t:value="userEditable.firstName" /> + <p:else> + <t:if test="user.firstName"> + ${user.firstName} + <p:else>-</p:else> + </t:if> + </p:else> + </t:if> + </div> + <div> + <t:label for="lastName" /> + <t:if test="edited"> + <t:TextField t:id="lastName" t:value="userEditable.lastName" /> + <p:else> + <t:if test="user.lastName"> + ${user.lastName} + <p:else>-</p:else> + </t:if> + </p:else> + </t:if> + </div> + </FieldSet> + + <div class="buttons"> + <t:if test="edited"> + <input type="submit" value="${message:submit-label}" /> + <a t:type="pagelink" t:page="user/profile" style="text-decoration: none;"> + <input type="button" value="${message:cancel-action}" /> + </a> + <p:else> + <a t:type="actionlink" t:id="editAccount" style="text-decoration: none;"> + <input type="button" value="${message:edit-action}" /> + </a> + </p:else> + </t:if> + </div> + </div> + </t:form> + </t:zone> + + <p:else> + <h4>${message:noUser}</h4> + <t:LoginComponent /> + </p:else> + </t:if> +</t:border> \ No newline at end of file Property changes on: trunk/pollen-ui/src/main/webapp/user/UserProfile.tml ___________________________________________________________________ Added: svn:mergeinfo + Modified: trunk/pollen-ui/src/main/webapp/user/UserRegister.tml =================================================================== --- trunk/pollen-ui/src/main/webapp/user/UserRegister.tml 2010-04-08 10:23:22 UTC (rev 2968) +++ trunk/pollen-ui/src/main/webapp/user/UserRegister.tml 2010-04-09 23:28:55 UTC (rev 2969) @@ -18,11 +18,11 @@ </div> <div> <t:label for="password1"/> - <t:PasswordField t:id="password1" t:value="password1" t:validate="required, minlength=6"/> + <t:PasswordField t:id="password1" t:value="newUser.newPassword" t:validate="required, minlength=6"/> </div> <div> - <t:label for="password2"/> - <t:PasswordField t:id="password2" t:value="password2" t:validate="required, minlength=6"/> + <t:label for="passwordVerify"/> + <t:PasswordField t:id="passwordVerify" t:value="passwordVerify" t:validate="required, minlength=6"/> </div> </fieldset> @@ -30,7 +30,7 @@ <legend>${message:userInfoLegend}</legend> <div> <t:label for="email"/> - <t:TextField t:id="email" t:value="newUser.email" t:validate="required,regexp"/> + <t:TextField t:id="email" t:value="newUser.email" t:validate="regexp"/> </div> <div> <t:label for="firstName"/>