001/*
002 *  Copyright 2012 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.web.usermanagement;
017
018import java.sql.Timestamp;
019import java.time.LocalDate;
020import java.time.ZoneId;
021import java.time.ZonedDateTime;
022import java.util.Arrays;
023import java.util.Date;
024import java.util.HashMap;
025import java.util.Iterator;
026import java.util.List;
027import java.util.Map;
028import java.util.Set;
029import java.util.UUID;
030
031import javax.mail.MessagingException;
032
033import org.apache.avalon.framework.configuration.Configuration;
034import org.apache.avalon.framework.configuration.ConfigurationException;
035import org.apache.avalon.framework.service.ServiceException;
036import org.apache.avalon.framework.service.ServiceManager;
037import org.apache.commons.lang.StringUtils;
038import org.apache.commons.lang3.RandomStringUtils;
039import org.apache.ibatis.session.SqlSession;
040
041import org.ametys.cms.repository.Content;
042import org.ametys.cms.transformation.URIResolver;
043import org.ametys.cms.transformation.URIResolverExtensionPoint;
044import org.ametys.core.datasource.AbstractMyBatisDAO;
045import org.ametys.core.user.InvalidModificationException;
046import org.ametys.core.user.User;
047import org.ametys.core.user.UserManager;
048import org.ametys.core.user.directory.ModifiableUserDirectory;
049import org.ametys.core.user.directory.NotUniqueUserException;
050import org.ametys.core.user.directory.UserDirectory;
051import org.ametys.core.user.population.PopulationContextHelper;
052import org.ametys.core.user.population.UserPopulation;
053import org.ametys.core.user.population.UserPopulationDAO;
054import org.ametys.core.util.I18nUtils;
055import org.ametys.core.util.URIUtils;
056import org.ametys.core.util.mail.SendMailHelper;
057import org.ametys.plugins.repository.AmetysObjectIterable;
058import org.ametys.plugins.repository.AmetysObjectResolver;
059import org.ametys.plugins.repository.AmetysRepositoryException;
060import org.ametys.plugins.repository.query.expression.Expression;
061import org.ametys.plugins.repository.query.expression.Expression.Operator;
062import org.ametys.runtime.i18n.I18nizableTextParameter;
063import org.ametys.runtime.i18n.I18nizableText;
064import org.ametys.runtime.parameter.Errors;
065import org.ametys.web.repository.page.Page;
066import org.ametys.web.repository.page.PageQueryHelper;
067import org.ametys.web.repository.page.ZoneItem;
068import org.ametys.web.repository.site.Site;
069import org.ametys.web.repository.site.SiteManager;
070import org.ametys.web.site.SiteConfigurationExtensionPoint;
071import org.ametys.web.tags.TagExpression;
072
073import com.google.common.collect.Multimap;
074
075/**
076 * Manages registration and password recovery of users.
077 */
078public class UserSignupManager extends AbstractMyBatisDAO
079{
080
081    /** The component role. */
082    public static final String ROLE = UserSignupManager.class.getName();
083
084    /** Return code which indicates no error. */
085    public static final int SIGNUP_NO_ERROR = 0;
086
087    /** Temporary signup return code: a user tried to sign-up but the e-mail already exists in the temporary table. */
088    public static final int SIGNUP_ERROR_TEMP_EMAIL_ALREADY_EXISTS = 1;
089
090    /** Temporary signup return code: a user tried to sign-up but the FO UsersManager already possesses a user with this e-mail as login. */
091    public static final int SIGNUP_ERROR_USER_ALREADY_EXISTS = 2;
092
093    /** Token return code: a user provided a token, but it doesn't exist. */
094    public static final int SIGNUP_TOKEN_UNKNOWN = 3;
095
096    /** Token return code: a user provided a token, but it isn't valid anymore. */
097    public static final int SIGNUP_TOKEN_EXPIRED = 4;
098    
099    /** Token return code: undefined error. */
100    public static final int SIGNUP_ERROR = 5;
101    
102    /** Reset token return code: a user asked for a new token, but no subscription request can be found with this e-mail. */
103    public static final int SIGNUP_RESET_ERROR_EMAIL_UNKNOWN = 5;
104
105    /** The user manager. */
106    protected UserManager _userManager;
107    
108    /** The DAO for user populations */
109    protected UserPopulationDAO _userPopulationDAO;
110
111    /** The site manager. */
112    protected SiteManager _siteManager;
113
114    /** The site configuration extension point. */
115    protected SiteConfigurationExtensionPoint _siteConf;
116
117    /** The ametys object resolver. */
118    protected AmetysObjectResolver _resolver;
119
120    /** The ametys object resolver. */
121    protected URIResolverExtensionPoint _uriResolverEP;
122
123    /** The page URI resolver. */
124    protected URIResolver _pageUriResolver;
125
126    /** The i18n utils. */
127    protected I18nUtils _i18nUtils;
128
129    /** The user sign up configuration */
130    protected UserSignUpConfiguration _userSignUpConfiguration;
131    
132    /** The temporary users table. */
133    protected String _tempUsersTable;
134
135    /** The password change table. */
136    protected String _pwdChangeTable;
137
138    /** The population context helper. */
139    protected PopulationContextHelper _populationContextHelper;
140
141    /** Enumeration for different cases of lost password errors */
142    public enum LostPasswordError
143    {
144        /** User not connected */
145        NOT_CONNECTED,
146        /** Lost password return code: the login or e-mail the user provided doesn't correspond to a population. */
147        USER_UNKNOWN,
148        /** Lost password return code: the population the user provided doesn't correspond to a user. */
149        POPULATION_UNKNOWN,
150        /** Lost password return code: the user provided belongs to an unmodifiable user directory */
151        UNMODIFIABLE_USER_DIRECTORY,
152        /** Lost password return code: the user provided have an empty email */
153        EMPTY_EMAIL,
154        /** Lost password return code: the informations the user provided match several users */
155        SEVERAL_USERS,
156        /** Token return code: a user provided a token, but it doesn't exist. */
157        TOKEN_UNKNOWN,
158        /** Token return code: a user provided a token, but it isn't valid anymore. */
159        TOKEN_EXPIRED;
160    }
161    
162    @Override
163    public void service(ServiceManager serviceManager) throws ServiceException
164    {
165        super.service(serviceManager);
166        
167        _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE);
168        _userPopulationDAO = (UserPopulationDAO) serviceManager.lookup(UserPopulationDAO.ROLE);
169        _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE);
170        _siteConf = (SiteConfigurationExtensionPoint) serviceManager.lookup(SiteConfigurationExtensionPoint.ROLE);
171        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
172        _uriResolverEP = (URIResolverExtensionPoint) serviceManager.lookup(URIResolverExtensionPoint.ROLE);
173        _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE);
174        _userSignUpConfiguration = (UserSignUpConfiguration) serviceManager.lookup(UserSignUpConfiguration.ROLE);
175        _populationContextHelper = (PopulationContextHelper) serviceManager.lookup(PopulationContextHelper.ROLE);
176    }
177
178    @Override
179    public void configure(Configuration configuration) throws ConfigurationException
180    {
181        super.configure(configuration);
182        
183        // Configure pool and tables.
184        _tempUsersTable = configuration.getChild("temp-users-table").getValue();
185        _pwdChangeTable = configuration.getChild("pwd-change-table").getValue();
186    }
187
188    /**
189     * Test if public signup is allowed in a site.
190     * @param siteName the site to test.
191     * @return true if public signup is allowed, false otherwise.
192     */
193    public boolean isPublicSignupAllowed(String siteName)
194    {
195        Site site = _siteManager.getSite(siteName);
196        return site.getValue("public-signup", false, false);
197    }
198
199    /**
200     * Get the sign-up page in a given site and sitemap.<br>
201     * If more than one page are tagged "sign-up", return the first.
202     * @param siteName the site name.
203     * @param language the sitemap name.
204     * @return the sign-up page or null if not found.
205     */
206    public Page getSignupPage(String siteName, String language)
207    {
208        Page page = null;
209
210        try (AmetysObjectIterable<Page> pages = getSignupPages(siteName, language);)
211        {
212            Iterator<Page> it = pages.iterator();
213            if (it.hasNext())
214            {
215                page = it.next();
216            }
217        }
218
219        return page;
220    }
221
222    /**
223     * Get all the pages tagged "sign-up".
224     * @param siteName the site name.
225     * @param language the sitemap name.
226     * @return an iterable on all the pages tagged "sign-up".
227     */
228    public AmetysObjectIterable<Page> getSignupPages(String siteName, String language)
229    {
230        Expression expression = new TagExpression(Operator.EQ, "USER_SIGNUP");
231        String query = PageQueryHelper.getPageXPathQuery(siteName, language, null, expression, null);
232
233        return _resolver.query(query);
234    }
235
236    /**
237     * Get the password change page in a given site and sitemap.
238     * If more than one page are tagged "password change", return the first.
239     * @param siteName the site name.
240     * @param language the sitemap name.
241     * @return the password change page or null if not found.
242     */
243    public Page getPwdChangePage(String siteName, String language)
244    {
245        Page page = null;
246
247        try (AmetysObjectIterable<Page> pages = getPwdChangePages(siteName, language);)
248        {
249            Iterator<Page> it = pages.iterator();
250            if (it.hasNext())
251            {
252                page = it.next();
253            }
254        }
255
256        return page;
257    }
258    
259    /**
260     * Get the GTU page
261     * Returns null if not found or empty
262     * @param zoneItem the zone item
263     * @return the GTU page or null.
264     */
265    public Page getGTUPage(ZoneItem zoneItem)
266    {
267        Page page = null;
268
269        try
270        {
271            String tosMode = zoneItem.getServiceParameters().getValue("terms-of-service-mode");
272            if ("PAGE".equals(tosMode))
273            {
274                String tosPageId = zoneItem.getServiceParameters().getValue("terms-of-service-page");
275                if (StringUtils.isNotEmpty(tosPageId))
276                {
277                    page = _resolver.resolveById(tosPageId);
278                }
279            }
280        }
281        catch (AmetysRepositoryException e)
282        {
283            // Nothing
284        }
285
286        return page;
287    }
288    
289    /**
290     * Get the GTU content
291     * Returns null if not found or empty
292     * @param zoneItem the zone item
293     * @return the GTU content or null.
294     */
295    public Content getGTUContent(ZoneItem zoneItem)
296    {
297        Content content = null;
298
299        try
300        {
301            String tosMode = zoneItem.getServiceParameters().getValue("terms-of-service-mode");
302            if ("CONTENT".equals(tosMode))
303            {
304                String tosContentId = zoneItem.getServiceParameters().getValue("terms-of-service-content");
305                if (StringUtils.isNotEmpty(tosContentId))
306                {
307                    content = _resolver.resolveById(tosContentId);
308                }
309            }
310            
311        }
312        catch (AmetysRepositoryException e)
313        {
314            // Nothing
315        }
316
317        return content;
318    }
319    
320    /**
321     * Get the GTU page
322     * Returns null if not found or empty
323     * @param zoneItem the zone item
324     * @return the success page or null.
325     */
326    public Page getSuccessPage(ZoneItem zoneItem)
327    {
328        Page page = null;
329
330        try
331        {
332            String successMode = zoneItem.getServiceParameters().getValue("success-mode");
333            if ("PAGE".equals(successMode))
334            {
335                String successPageId = zoneItem.getServiceParameters().getValue("success-page");
336                if (StringUtils.isNotEmpty(successPageId))
337                {
338                    page = _resolver.resolveById(successPageId);
339                }
340            }
341        }
342        catch (AmetysRepositoryException e)
343        {
344            // Nothing
345        }
346
347        return page;
348    }
349    
350    /**
351     * Get the success content
352     * Returns null if not found or empty
353     * @param zoneItem the zone item
354     * @return the success content or null.
355     */
356    public Content getSuccessContent(ZoneItem zoneItem)
357    {
358        Content content = null;
359
360        try
361        {
362            String successMode = zoneItem.getServiceParameters().getValue("success-mode");
363            if ("CONTENT".equals(successMode))
364            {
365                String successContentId = zoneItem.getServiceParameters().getValue("success-content");
366                if (StringUtils.isNotEmpty(successContentId))
367                {
368                    content = _resolver.resolveById(successContentId);
369                }
370            }
371        }
372        catch (AmetysRepositoryException e)
373        {
374            // Nothing
375        }
376
377        return content;
378    }
379
380    /**
381     * Get all the pages tagged "password change".
382     * @param siteName the site name.
383     * @param language the sitemap name.
384     * @return an iterable on all the pages tagged "password change".
385     */
386    public AmetysObjectIterable<Page> getPwdChangePages(String siteName, String language)
387    {
388        Expression expression = new TagExpression(Operator.EQ, "USER_PASSWORD_CHANGE");
389        String query = PageQueryHelper.getPageXPathQuery(siteName, language, null, expression, null);
390
391        return _resolver.query(query);
392    }
393    
394    /**
395     * Tests if the user already exists in the populations 
396     * @param email the e-mail to test.
397     * @param siteName The site name
398     * @return true if the user exists, false otherwise.
399     * @throws UserManagementException if an error occurs.
400     */
401    public boolean userExists(String email, String siteName) throws UserManagementException
402    {
403        try
404        {
405            Set<String> populationIds = _populationContextHelper.getUserPopulationsOnContexts(Arrays.asList("/sites/" + siteName, "/sites-fo/" + siteName), false, false);
406            for (String population : populationIds)
407            {
408                if (_userManager.getUser(population, email) != null || _userManager.getUserByEmail(population, email) != null)
409                {
410                    return true;
411                }
412            }
413            
414            return false;
415        }
416        catch (NotUniqueUserException e)
417        {
418            return true;
419        }
420    }
421
422    /**
423     * Validate the user subscription data.
424     * @param siteName the site name.
425     * @param email the user e-mail.
426     * @param additionalValues the additional user values.
427     * @return a Map of the Errors by field.
428     * @throws UserManagementException if an error occurs.
429     */
430    public Map<String, Errors> validate(String siteName, String email, Map<String, String> additionalValues) throws UserManagementException
431    {
432        Map<String, String> userInfos = new HashMap<>();
433        
434        userInfos.putAll(additionalValues);
435        
436        // Standard info for user (provide a dummy password, as we do not know it yet).
437        userInfos.put("login", email);
438        userInfos.put("email", email);
439        userInfos.put("password", "password");
440
441        Map<String, Errors> usersManagerErrors = new HashMap<>(); //foUsersManager.validate(userInfos);
442        Map<String, Errors> errors = new HashMap<>(usersManagerErrors);
443
444        // If there are errors on the login, do not return it except if
445        if (errors.containsKey("login"))
446        {
447            if (!errors.containsKey("email"))
448            {
449                errors.put("email", errors.get("login"));
450            }
451            errors.remove("login");
452        }
453
454        return errors;
455    }
456
457    /**
458     * Validate the user password.
459     * @param siteName the site name.
460     * @param password the password to validate.
461     * @param login the login of the user
462     * @param population The id of the population
463     * @return a Map of the Errors by field.
464     * @throws UserManagementException if an error occurs.
465     */
466    public Map<String, Errors> validatePassword(String siteName, String password, String login, String population) throws UserManagementException
467    {
468        Map<String, String> userInfos = new HashMap<>();
469
470        userInfos.put("password", password);
471
472        UserDirectory userDirectory = _userManager.getUserDirectory(population, login);
473        if (!(userDirectory instanceof ModifiableUserDirectory))
474        {
475            throw new UserManagementException("The user subscription feature can't be used, as the UserDirectory is not modifiable.");
476        }
477        Map<String, Errors> usersManagerErrors = ((ModifiableUserDirectory) userDirectory).validate(userInfos);
478        Map<String, Errors> errors = new HashMap<>();
479
480        // Keep only errors related to the password field.
481        if (usersManagerErrors.containsKey("password"))
482        {
483            errors.put("password", usersManagerErrors.get("password"));
484        }
485
486        return errors;
487    }
488
489    /**
490     * Validate and store a sign-up request and send a confirmation e-mail.
491     * @param siteName the site name.
492     * @param language the sitemap name.
493     * @param email the user e-mail address.
494     * @param population the population
495     * @param userDirectoryId the id of the user directory of the population
496     * @return a status code indicating success or error.
497     * @throws UserManagementException if an error occurs.
498     */
499    public int temporarySignup(String siteName, String language, String email, String population, String userDirectoryId) throws UserManagementException
500    {
501        return temporarySignup(siteName, language, email, population, userDirectoryId, true);
502    }
503    
504    /**
505     * Validate and store a sign-up request and send a confirmation e-mail.
506     * @param siteName the site name.
507     * @param language the sitemap name.
508     * @param email the user e-mail address.
509     * @param population the population
510     * @param userDirectoryId the id of the user directory of the population
511     * @param sendMail Set to false to not send mail at end of process
512     * @return a status code indicating success or error.
513     * @throws UserManagementException if an error occurs.
514     */
515    public int temporarySignup(String siteName, String language, String email, String population, String userDirectoryId, boolean sendMail) throws UserManagementException
516    {
517        // Verify that public sign-up is allowed and throw an exception otherwise.
518        checkPublicSignup(siteName);
519
520        if (getLogger().isDebugEnabled())
521        {
522            getLogger().debug("A user is requesting a sign-up: " + email);
523        }
524
525        // Generate unique token.
526        String token = UUID.randomUUID().toString().replace("-", "");
527
528        int status = addTemporaryUser(siteName, email, token, population, userDirectoryId);
529
530        // Send validation e-mail with token.
531        if (status == SIGNUP_NO_ERROR && sendMail)
532        {
533            sendSignupConfirmMail(siteName, language, email, token);
534        }
535
536        return status;
537    }
538    
539    /**
540     * Get a token for temp user
541     * @param siteName the site name.
542     * @param email the user e-mail address.
543     * @param population The id of the population
544     * @param userDirectoryId The id of the user directory of the population
545     * @return the user token or null if not found
546     * @throws UserManagementException if an error occurs.
547     */
548    public String getToken(String siteName, String email, String population, String userDirectoryId) throws UserManagementException
549    {
550        TempUser tempUser = getTempUser(siteName, email, population, userDirectoryId);
551        if (tempUser != null)
552        {
553            return tempUser.getToken();
554        }
555        
556        return null;
557    }
558
559    /**
560     * Reset a sign-up request: generate a new token and re-send the confirmation e-mail.
561     * @param siteName the site name.
562     * @param language the sitemap name.
563     * @param email the user e-mail address.
564     * @param population The id of the population
565     * @param userDirectoryId The id of the user directory of the population
566     * @return a status code indicating success or error.
567     * @throws UserManagementException if an error occurs.
568     */
569    public int resetTempSignup(String siteName, String language, String email, String population, String userDirectoryId) throws UserManagementException
570    {
571        // Verify that public sign-up is allowed and throw an exception otherwise.
572        checkPublicSignup(siteName);
573
574        if (getLogger().isDebugEnabled())
575        {
576            getLogger().debug("Resetting temporary signup for email: " + email + " in site " + siteName);
577        }
578
579        // Generate a new token.
580        String newToken = UUID.randomUUID().toString().replace("-", "");
581
582        // Test if the subscription request really exists.
583        TempUser tempUser = getTempUser(siteName, email, population, userDirectoryId);
584
585        if (tempUser == null)
586        {
587            // No subscription request with this e-mail.
588            return SIGNUP_RESET_ERROR_EMAIL_UNKNOWN;
589        }
590
591        updateTempToken(siteName, email, newToken, population, userDirectoryId);
592
593        sendSignupConfirmMail(siteName, language, email, newToken);
594
595        return SIGNUP_NO_ERROR;
596    }
597
598
599    /**
600     * Create the user in the FO UsersManager from his temporary request.
601     * @param siteName the site name.
602     * @param language the current language
603     * @param firstname the user firstname
604     * @param lastname the user lastname
605     * @param email the user e-mail address.
606     * @param token the request token.
607     * @param password the user password.
608     * @param population The id of the population
609     * @param userDirectoryId The id of the user directory of the population
610     * @param errors the errors
611     * @return a status code indicating success or error.
612     * @throws UserManagementException if an error occurs.
613     */
614    public int signup(String siteName, String language, String firstname, String lastname, String email, String token, String password, String population, String userDirectoryId, Multimap<String, I18nizableText> errors) throws UserManagementException
615    {
616        // Verify that public sign-up is allowed and throw an exception otherwise.
617        checkPublicSignup(siteName);
618
619        Map<String, String> userInfos = new HashMap<>();
620
621        TempUser tempUser = getTempUser(siteName, email, token, population, userDirectoryId);
622
623        if (tempUser == null)
624        {
625            return SIGNUP_TOKEN_UNKNOWN;
626        }
627        
628        // Generate login
629        String login = RandomStringUtils.randomNumeric(10);
630
631        // Standard info for user.
632        userInfos.put("login", login);
633        userInfos.put("email", email);
634        userInfos.put("firstname", firstname);
635        userInfos.put("lastname", lastname);
636        userInfos.put("password", password);
637
638        try
639        {
640            validationBeforeSignup(errors);
641            
642            if (errors.isEmpty())
643            {
644                // Add the user.
645                ModifiableUserDirectory userDirectory = (ModifiableUserDirectory) _userPopulationDAO.getUserPopulation(population).getUserDirectory(userDirectoryId);
646                userDirectory.add(userInfos);
647
648                // Remove the temporary user.
649                removeTempUser(siteName, email, token, population, userDirectoryId);
650                
651                User createdUser = userDirectory.getUser(login);
652                
653                // Do additional operations after signup
654                additionalSignupOperations(createdUser, errors);
655                
656                if (errors.isEmpty())
657                {
658                    sendSignupValidatedMail(siteName, language, createdUser);
659                    return SIGNUP_NO_ERROR;
660                }
661            }
662            
663            return SIGNUP_ERROR;
664        }
665        catch (InvalidModificationException e)
666        {
667            throw new UserManagementException("An error occurred signing up the user.", e);
668        }
669    }
670    
671    /**
672     * Do some validation before signup
673     * @param errors the map of errors to fill in cause of errors during validation
674     */
675    public void validationBeforeSignup(Multimap<String, I18nizableText> errors)
676    {
677        // Nothing
678    }
679    
680    /**
681     * Process additional operations after creation of user
682     * @param createdUser the created user
683     * @param errors the map of errors to fill in case of errors during additional operations
684     * @throws UserManagementException if an error occurs.
685     */
686    public void additionalSignupOperations(User createdUser, Multimap<String, I18nizableText> errors) throws UserManagementException
687    {
688        // Nothing
689    }
690    
691
692    /**
693     * Create a reset password request and send a confirmation e-mail.
694     * @param siteName the site name.
695     * @param language the sitemap name.
696     * @param loginOrEmail the user login or email.
697     * @param populationId the population
698     * @return a status code indicating success or error.
699     * @throws UserManagementException if an error occurs.
700     */
701    public LostPasswordError resetPassword(String siteName, String language, String loginOrEmail, String populationId) throws UserManagementException
702    {
703        // Check if the population exists
704        UserPopulation population = _userPopulationDAO.getUserPopulation(populationId);
705        if (population == null)
706        {
707            return LostPasswordError.POPULATION_UNKNOWN;
708        }
709        
710        // Check if the user exists and get it
711        User user = _userManager.getUser(populationId, loginOrEmail);
712        if (user == null)
713        {
714            try
715            {
716                user = _userManager.getUserByEmail(populationId, loginOrEmail);
717                if (user == null)
718                {
719                    // No user with this e-mail or login.
720                    return LostPasswordError.USER_UNKNOWN;
721                }
722            }
723            catch (NotUniqueUserException e)
724            {
725                return LostPasswordError.SEVERAL_USERS;
726            }
727        }
728        
729        // Check if the user directory is modifiable
730        if (!(user.getUserDirectory() instanceof ModifiableUserDirectory))
731        {
732            return LostPasswordError.UNMODIFIABLE_USER_DIRECTORY;
733        }
734        
735        if (StringUtils.isEmpty(user.getEmail()))
736        {
737            return LostPasswordError.EMPTY_EMAIL;
738        }
739
740        // Generate a new token.
741        String token = UUID.randomUUID().toString().replace("-", "");
742
743        // Insert the token in the database.
744        addPasswordToken(siteName, user.getIdentity().getLogin(), token, populationId);
745
746        // Send the e-mail.
747        sendResetPasswordMail(siteName, language, user, token);
748
749        return null;
750    }
751
752    /**
753     * Change the user password.
754     * @param siteName the site name.
755     * @param login the user login.
756     * @param token the password change request token.
757     * @param newPassword the new password.
758     * @param population the population
759     * @return a status code indicating success or error.
760     * @throws UserManagementException if an error occurs.
761     */
762    public int changeUserPassword(String siteName, String login, String token, String newPassword, String population) throws UserManagementException
763    {
764        int tokenStatus = checkPasswordToken(siteName, login, token, population);
765
766        if (tokenStatus != SIGNUP_NO_ERROR)
767        {
768            return tokenStatus;
769        }
770
771        Map<String, String> userInfos = new HashMap<>();
772
773        userInfos.put("login", login);
774        userInfos.put("password", newPassword);
775
776        try
777        {
778            UserDirectory userDirectory = _userManager.getUserDirectory(population, login);
779            if (!(userDirectory instanceof ModifiableUserDirectory))
780            {
781                throw new UserManagementException("The user's password can't be changed, as the UserDirectory is not modifiable.");
782            }
783            ((ModifiableUserDirectory) userDirectory).update(userInfos);
784
785            removePasswordToken(siteName, login, token, population);
786
787            return SIGNUP_NO_ERROR;
788        }
789        catch (InvalidModificationException e)
790        {
791            throw new UserManagementException("An error occurred signing up the user.", e);
792        }
793    }
794    
795    /**
796     * Check the sign-up request token.
797     * @param siteName the site name.
798     * @param email the user e-mail.
799     * @param token the sign-up request token.
800     * @param population The id of the population
801     * @param userDirectoryId The id of the user directory of the population
802     * @return a status code indicating success or error.
803     * @throws UserManagementException if an error occurs.
804     */
805    public int checkToken(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException
806    {
807        removeExpiredTokens();
808
809        try (SqlSession sqlSession = getSession())
810        {
811            String stmtId = "UserSignupManager.getSubscriptionDate";
812            
813            Map<String, Object> params = new HashMap<>();
814            params.put("tempUsersTable", _tempUsersTable);
815            
816            params.put("site", siteName);
817            params.put("email", email);
818            params.put("token", token);
819            params.put("population", population);
820            params.put("userDirectory", userDirectoryId);
821            
822            Date rawSubscriptionDate = sqlSession.selectOne(stmtId, params);
823
824            // Date verification.
825            if (rawSubscriptionDate == null)
826            {
827                return SIGNUP_TOKEN_UNKNOWN;
828            }
829            
830            // The validity limit
831            ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity());
832            ZonedDateTime subscriptionDate = rawSubscriptionDate.toInstant().atZone(ZoneId.systemDefault());
833
834            if (subscriptionDate.isBefore(limit))
835            {
836                return SIGNUP_TOKEN_EXPIRED;
837            }
838
839            return SIGNUP_NO_ERROR;
840        }
841        catch (Exception e)
842        {
843            throw new UserManagementException("Database error while testing the token for user [" + email + "]", e);
844        }
845    }
846
847    /**
848     * Check the password change request token.
849     * @param siteName the site name.
850     * @param login the user login.
851     * @param token the password change request token.
852     * @param population the population
853     * @return a status code indicating success or error.
854     * @throws UserManagementException if an error occurs.
855     */
856    public int checkPasswordToken(String siteName, String login, String token, String population) throws UserManagementException
857    {
858        removeExpiredPasswordTokens();
859
860        try (SqlSession sqlSession = getSession())
861        {
862            String stmtId = "UserSignupManager.getRequestDate";
863            
864            Map<String, Object> params = new HashMap<>();
865            params.put("pwdChangeTable", _pwdChangeTable);
866            
867            params.put("site", siteName);
868            params.put("login", login);
869            params.put("token", token);
870            params.put("population", population);
871            
872            Date rawRequestDate = sqlSession.selectOne(stmtId, params);
873
874            // Date verification.
875            if (rawRequestDate == null)
876            {
877                return SIGNUP_TOKEN_UNKNOWN;
878            }
879
880            // Check the validity.
881            ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity());
882            ZonedDateTime requestDate = rawRequestDate.toInstant().atZone(ZoneId.systemDefault());
883
884            if (requestDate.isBefore(limit))
885            {
886                return SIGNUP_TOKEN_EXPIRED;
887            }
888
889            return SIGNUP_NO_ERROR;
890        }
891        catch (Exception e)
892        {
893            throw new UserManagementException("Database error while testing the password token for user " + login, e);
894        }
895    }
896
897    /**
898     * Remove the expired sign-up request tokens.
899     * @throws UserManagementException if an error occurs.
900     */
901    public void removeExpiredTokens() throws UserManagementException
902    {
903        try (SqlSession sqlSession = getSession())
904        {
905            String stmtId = "UserSignupManager.deleteExpiredTokens";
906            
907            Map<String, Object> params = new HashMap<>();
908            params.put("tempUsersTable", _tempUsersTable);
909            
910            ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity());
911            Timestamp limitTimestamp = Timestamp.from(limit.toInstant());
912            params.put("threshold", limitTimestamp);
913            
914            sqlSession.delete(stmtId, params);
915            sqlSession.commit();
916        }
917        catch (Exception e)
918        {
919            throw new UserManagementException("Database error while removing the expired tokens.", e);
920        }
921    }
922
923    /**
924     * Remove the expired change password request tokens.
925     * @throws UserManagementException if an error occurs.
926     */
927    public void removeExpiredPasswordTokens() throws UserManagementException
928    {
929        try (SqlSession sqlSession = getSession())
930        {
931            String stmtId = "UserSignupManager.deleteExpiredPasswordTokens";
932            
933            Map<String, Object> params = new HashMap<>();
934            params.put("pwdChangeTable", _pwdChangeTable);
935            
936            ZonedDateTime limit = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).minusDays(_userSignUpConfiguration.getTokenValidity());
937            Timestamp limitTimestamp = Timestamp.from(limit.toInstant());
938            params.put("threshold", limitTimestamp);
939            
940            sqlSession.delete(stmtId, params);
941            sqlSession.commit();
942        }
943        catch (Exception e)
944        {
945            throw new UserManagementException("Database error while removing the expired tokens.", e);
946        }
947    }
948
949    /**
950     * Verify that public sign-up is allowed. If not, throw an exception.
951     * @param siteName the site name.
952     * @throws UserManagementException if public sign-up is not enabled.
953     */
954    protected void checkPublicSignup(String siteName) throws UserManagementException
955    {
956        if (!isPublicSignupAllowed(siteName))
957        {
958            throw new UserManagementException("Public signup is disabled for this site.");
959        }
960    }
961
962    /**
963     * Create a user sign-up request ("temporary" user) in the database.
964     * @param siteName the site name.
965     * @param email the user e-mail.
966     * @param token the generated token.
967     * @param population the population
968     * @param userDirectoryId the id of the user directory of the population
969     * @return a status code indicating success or error.
970     * @throws UserManagementException if an error occurs.
971     */
972    protected int addTemporaryUser(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException
973    {
974        try (SqlSession sqlSession = getSession())
975        {
976            // Does this email already exists
977            String stmtId = "UserSignupManager.tempEmailExists";
978            
979            Map<String, Object> params = new HashMap<>();
980            params.put("tempUsersTable", _tempUsersTable);
981            
982            params.put("site", siteName);
983            params.put("email", email);
984            params.put("population", population);
985            params.put("userDirectory", userDirectoryId);
986            
987            List<String> emails = sqlSession.selectList(stmtId, params);
988            
989            if (!emails.isEmpty())
990            {
991                return SIGNUP_ERROR_TEMP_EMAIL_ALREADY_EXISTS;
992            }
993            
994            // Add temp user
995            stmtId = "UserSignupManager.addTempUser";
996            params = new HashMap<>();
997            params.put("tempUsersTable", _tempUsersTable);
998            
999            Timestamp now = new Timestamp(System.currentTimeMillis());
1000            
1001            params.put("site", siteName);
1002            params.put("email", email);
1003            params.put("population", population);
1004            params.put("userDirectory", userDirectoryId);
1005            params.put("subscription_date", now);
1006            params.put("token", token);
1007            
1008            sqlSession.insert(stmtId, params);
1009            sqlSession.commit();
1010            
1011            return SIGNUP_NO_ERROR;
1012        }
1013        catch (Exception e)
1014        {
1015            throw new UserManagementException("Database error while signing up a new user [" + email + "]", e);
1016        }
1017    }
1018
1019    /**
1020     * Send a sign-up confirmation link by e-mail.
1021     * @param siteName the site name.
1022     * @param language the e-mail language.
1023     * @param email the user e-mail.
1024     * @param token the generated token.
1025     * @throws UserManagementException if an error occurs.
1026     */
1027    protected void sendSignupConfirmMail(String siteName, String language, String email, String token) throws UserManagementException
1028    {
1029        if (getLogger().isDebugEnabled())
1030        {
1031            getLogger().debug("Sending signup confirmation e-mail to " + email);
1032        }
1033
1034        Site site = _siteManager.getSite(siteName);
1035        String from = site.getValue("site-mail-from");
1036
1037        // Prepare mail.
1038        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
1039        i18nParams.put("siteName", new I18nizableText(siteName));
1040        i18nParams.put("email", new I18nizableText(email));
1041        i18nParams.put("token", new I18nizableText(token));
1042
1043        Page signupPage = getSignupPage(siteName, language);
1044        if (signupPage != null)
1045        {
1046            if (_pageUriResolver == null)
1047            {
1048                _pageUriResolver = _uriResolverEP.getResolverForType("page");
1049            }
1050
1051            String encodedEmail = URIUtils.encodeParameter(email);
1052
1053            // Compute the confirmation URI and add it to the parameters.
1054            String confirmUri = _pageUriResolver.resolve(signupPage.getId(), false, true, false);
1055            confirmUri = confirmUri + "?email=" + encodedEmail + "&token=" + token;
1056
1057            i18nParams.put("confirmUri", new I18nizableText(confirmUri));
1058        }
1059
1060        // Add site information in the parameters.
1061        i18nParams.put("siteTitle", new I18nizableText(site.getTitle()));
1062        i18nParams.put("siteUrl", new I18nizableText(site.getUrl()));
1063
1064        String subject = _userSignUpConfiguration.getSubjectForSignUpEmail(i18nParams, language);
1065        String textBody = _userSignUpConfiguration.getTextBodyForSignUpEmail(i18nParams, language);
1066        String htmlBody = _userSignUpConfiguration.getHtmlBodyForSignUpEmail(i18nParams, language);
1067
1068        try
1069        {
1070            // Send the e-mail.
1071            SendMailHelper.sendMail(subject, htmlBody, textBody, email, from);
1072        }
1073        catch (MessagingException e)
1074        {
1075            throw new UserManagementException("Error sending the sign-up confirmation mail.", e);
1076        }
1077    }
1078    
1079    /**
1080     * Send a sign-up confirmation link by e-mail.
1081     * @param siteName the site name.
1082     * @param language the e-mail language.
1083     * @param user the created user
1084     * @throws UserManagementException if an error occurs.
1085     */
1086    protected void sendSignupValidatedMail(String siteName, String language, User user) throws UserManagementException
1087    {
1088        Site site = _siteManager.getSite(siteName);
1089        String from = site.getValue("site-mail-from");
1090        String email = user.getEmail();
1091
1092        if (getLogger().isDebugEnabled())
1093        {
1094            getLogger().debug("Sending signup validation e-mail to " + email);
1095        }
1096        
1097        // Prepare mail.
1098        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
1099        i18nParams.put("siteName", new I18nizableText(siteName));
1100        i18nParams.put("fullName", new I18nizableText(user.getFullName()));
1101        i18nParams.put("email", new I18nizableText(user.getEmail()));
1102        i18nParams.put("login", new I18nizableText(user.getIdentity().getLogin()));
1103
1104        // Add site information in the parameters.
1105        i18nParams.put("siteTitle", new I18nizableText(site.getTitle()));
1106        i18nParams.put("siteUrl", new I18nizableText(site.getUrl()));
1107
1108        String subject = _userSignUpConfiguration.getSubjectForSignUpValidatedEmail(i18nParams, language);
1109        String textBody = _userSignUpConfiguration.getTextBodyForSignUpValidatedEmail(i18nParams, language);
1110        String htmlBody = _userSignUpConfiguration.getHtmlBodyForSignUpValidatedEmail(i18nParams, language);
1111
1112        try
1113        {
1114            // Send the e-mail.
1115            SendMailHelper.sendMail(subject, htmlBody, textBody, email, from);
1116        }
1117        catch (MessagingException e)
1118        {
1119            throw new UserManagementException("Error sending the sign-up validation mail.", e);
1120        }
1121    }
1122
1123    /**
1124     * Update the sign-up request token: reset the date and set a new token.
1125     * @param siteName the site name.
1126     * @param email the user e-mail.
1127     * @param newToken the new token.
1128     * @param population The id of the population
1129     * @param userDirectoryId The id of the user directory of the population
1130     * @throws UserManagementException if an error occurs.
1131     */
1132    protected void updateTempToken(String siteName, String email, String newToken, String population, String userDirectoryId) throws UserManagementException
1133    {
1134        try (SqlSession sqlSession = getSession())
1135        {
1136            String stmtId = "UserSignupManager.updateTempToken";
1137            
1138            Map<String, Object> params = new HashMap<>();
1139            params.put("tempUsersTable", _tempUsersTable);
1140            
1141            Timestamp now = new Timestamp(System.currentTimeMillis());
1142            params.put("subscription_date", now);
1143            params.put("token", newToken);
1144            params.put("site", siteName);
1145            params.put("email", email);
1146            params.put("population", population);
1147            params.put("userDirectory", userDirectoryId);
1148            
1149            sqlSession.update(stmtId, params);
1150            sqlSession.commit();
1151        }
1152        catch (Exception e)
1153        {
1154            throw new UserManagementException("Database error while resetting the subscription for user [" + email + "]", e);
1155        }
1156    }
1157
1158    /**
1159     * Create a user password change request in the database.
1160     * @param siteName the site name.
1161     * @param login the user login.
1162     * @param token the generated token.
1163     * @param population the population
1164     * @throws UserManagementException if an error occurs.
1165     */
1166    protected void addPasswordToken(String siteName, String login, String token, String population) throws UserManagementException
1167    {
1168        try (SqlSession sqlSession = getSession())
1169        {
1170            String stmtId = "UserSignupManager.hasToken";
1171            
1172            Map<String, Object> params = new HashMap<>();
1173            params.put("pwdChangeTable", _pwdChangeTable);
1174            
1175            params.put("site", siteName);
1176            params.put("login", login);
1177            params.put("population", population);
1178            
1179            List<Object> pwdEntries = sqlSession.selectList(stmtId, params);
1180            
1181            if (pwdEntries.isEmpty())
1182            {
1183                // Insert a new token.
1184                stmtId = "UserSignupManager.addPasswordToken";
1185                params = new HashMap<>();
1186                params.put("pwdChangeTable", _pwdChangeTable);
1187                
1188                Timestamp now = new Timestamp(System.currentTimeMillis());
1189                params.put("site", siteName);
1190                params.put("login", login);
1191                params.put("request_date", now);
1192                params.put("token", token);
1193                params.put("population", population);
1194                
1195                sqlSession.insert(stmtId, params);
1196            }
1197            else
1198            {
1199                // Update the existing token.
1200                stmtId = "UserSignupManager.updatePasswordToken";
1201                params = new HashMap<>();
1202                params.put("pwdChangeTable", _pwdChangeTable);
1203                
1204                Timestamp now = new Timestamp(System.currentTimeMillis());
1205                params.put("request_date", now);
1206                params.put("token", token);
1207                params.put("site", siteName);
1208                params.put("login", login);
1209                params.put("population", population);
1210                
1211                sqlSession.update(stmtId, params);
1212            }
1213            
1214            // commit insert or update
1215            sqlSession.commit();
1216        }
1217        catch (Exception e)
1218        {
1219            throw new UserManagementException("Database error while inserting a password change token for " + login, e);
1220        }
1221    }
1222
1223    /**
1224     * Get a temporary user from his site name and e-mail.
1225     * @param siteName the site name.
1226     * @param email The temporary user e-mail. Cannot be null.
1227     * @param population the population
1228     * @param userDirectoryId the id of the user directory of the population
1229     * @return the temporary user or null if not found.
1230     * @throws UserManagementException if an error occurs.
1231     */
1232    protected TempUser getTempUser(String siteName, String email, String population, String userDirectoryId) throws UserManagementException
1233    {
1234        return getTempUser(siteName, email, null, population, userDirectoryId);
1235    }
1236
1237    /**
1238     * Get a temporary user from his site name, e-mail and/or token.
1239     * At least one of e-mail and token must be provided.
1240     * @param siteName the site name.
1241     * @param email The temporary user e-mail. Can be null.
1242     * @param token The temporary user token. Can be null.
1243     * @param population the population. Must be not null if email is not null
1244     * @param userDirectoryId the id of the user directory of the population. Must be not null if email is not null
1245     * @return the temporary user or null if not found.
1246     * @throws UserManagementException if an error occurs.
1247     */
1248    protected TempUser getTempUser(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException
1249    {
1250        if (StringUtils.isEmpty(email) && StringUtils.isEmpty(token))
1251        {
1252            throw new UserManagementException("Either e-mail or token must be provided.");
1253        }
1254        
1255        try (SqlSession sqlSession = getSession())
1256        {
1257            // Does this email already exists
1258            String stmtId = "UserSignupManager.getTempUser";
1259            
1260            Map<String, Object> params = new HashMap<>();
1261            params.put("tempUsersTable", _tempUsersTable);
1262            
1263            params.put("site", siteName);
1264            if (StringUtils.isNotEmpty(email))
1265            {
1266                params.put("email", email);
1267                params.put("population", population);
1268                params.put("userDirectory", userDirectoryId);
1269            }
1270            if (StringUtils.isNotEmpty(token))
1271            {
1272                params.put("token", token);
1273            }
1274            
1275            return sqlSession.selectOne(stmtId, params);
1276        }
1277        catch (Exception e)
1278        {
1279            throw new UserManagementException("Database error while getting the request for user [" + email + "] and token [" + token + "]", e);
1280        }
1281    }
1282
1283    /**
1284     * Remove the temporary .
1285     * @param siteName the site name.
1286     * @param email the user e-mail address.
1287     * @param token the request token.
1288     * @param population the population
1289     * @param userDirectoryId the id of the user directory of the population
1290     * @throws UserManagementException if an error occurs.
1291     */
1292    protected void removeTempUser(String siteName, String email, String token, String population, String userDirectoryId) throws UserManagementException
1293    {
1294        try (SqlSession sqlSession = getSession())
1295        {
1296            String stmtId = "UserSignupManager.removeTempUser";
1297            
1298            Map<String, Object> params = new HashMap<>();
1299            params.put("tempUsersTable", _tempUsersTable);
1300            
1301            params.put("site", siteName);
1302            params.put("email", email);
1303            params.put("token", token);
1304            params.put("population", population);
1305            params.put("userDirectory", userDirectoryId);
1306            
1307            sqlSession.delete(stmtId, params);
1308            sqlSession.commit();
1309        }
1310        catch (Exception e)
1311        {
1312            throw new UserManagementException("Database error while removing the token of user " + email, e);
1313        }
1314    }
1315
1316    /**
1317     * Remove the password change request.
1318     * @param siteName the site name.
1319     * @param login the user login.
1320     * @param token the request token.
1321     * @param population the population
1322     * @throws UserManagementException if an error occurs.
1323     */
1324    protected void removePasswordToken(String siteName, String login, String token, String population) throws UserManagementException
1325    {
1326        try (SqlSession sqlSession = getSession())
1327        {
1328            String stmtId = "UserSignupManager.removePasswordToken";
1329            
1330            Map<String, Object> params = new HashMap<>();
1331            params.put("pwdChangeTable", _pwdChangeTable);
1332            
1333            params.put("site", siteName);
1334            params.put("login", login);
1335            params.put("token", token);
1336            params.put("population", population);
1337            
1338            sqlSession.delete(stmtId, params);
1339            sqlSession.commit();
1340        }
1341        catch (Exception e)
1342        {
1343            throw new UserManagementException("Database error while removing the token of user " + login, e);
1344        }
1345    }
1346
1347    /**
1348     * Send a sign-up confirmation link by e-mail.
1349     * @param siteName the site name.
1350     * @param language the e-mail language.
1351     * @param user the user object.
1352     * @param token the generated token.
1353     * @throws UserManagementException if an error occurs.
1354     */
1355    protected void sendResetPasswordMail(String siteName, String language, User user, String token) throws UserManagementException
1356    {
1357        String login = user.getIdentity().getLogin();
1358        String population = user.getIdentity().getPopulationId();
1359
1360        if (getLogger().isDebugEnabled())
1361        {
1362            getLogger().debug("Sending reset password e-mail to " + login);
1363        }
1364
1365        Site site = _siteManager.getSite(siteName);
1366        String from = site.getValue("site-mail-from");
1367
1368        // Prepare mail
1369        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
1370        i18nParams.put("siteName", new I18nizableText(siteName));
1371        i18nParams.put("login", new I18nizableText(login));
1372        i18nParams.put("email", new I18nizableText(user.getEmail()));
1373        i18nParams.put("fullName", new I18nizableText(user.getFullName()));
1374        i18nParams.put("token", new I18nizableText(token));
1375
1376        Page passwordPage = getPwdChangePage(siteName, language);
1377        if (passwordPage != null)
1378        {
1379            if (_pageUriResolver == null)
1380            {
1381                _pageUriResolver = _uriResolverEP.getResolverForType("page");
1382            }
1383
1384            String encodedLogin = URIUtils.encodeParameter(login);
1385            String encodedPopulation = URIUtils.encodeParameter(population);
1386
1387            // Compute the confirmation URI and add it to the parameters.
1388            String confirmUri = _pageUriResolver.resolve(passwordPage.getId(), false, true, false);
1389            confirmUri = confirmUri + "?login=" + encodedLogin + "&population=" + encodedPopulation + "&token=" + token;
1390
1391            i18nParams.put("confirmUri", new I18nizableText(confirmUri));
1392        }
1393
1394        // Add site information in the parameters.
1395        i18nParams.put("siteTitle", new I18nizableText(site.getTitle()));
1396        i18nParams.put("siteUrl", new I18nizableText(site.getUrl()));
1397
1398        String subject = _userSignUpConfiguration.getSubjectForResetPwdEmail(i18nParams, language);
1399        String textBody = _userSignUpConfiguration.getTextBodyForResetPwdEmail(i18nParams, language);
1400        String htmlBody = _userSignUpConfiguration.getHtmlBodyForResetPwdEmail(i18nParams, language);
1401
1402        try
1403        {
1404            // Send the e-mail.
1405            SendMailHelper.sendMail(subject, htmlBody, textBody, user.getEmail(), from);
1406        }
1407        catch (MessagingException e)
1408        {
1409            throw new UserManagementException("Error sending a password reset e-mail.", e);
1410        }
1411    }
1412
1413    /**
1414     * Bean representing a user sign-up request.
1415     */
1416    public static class TempUser
1417    {
1418        /** The site name. */
1419        protected String _site;
1420        
1421        /** The user e-mail. */
1422        protected String _email;
1423
1424        /** The user subscription date. */
1425        protected Date _subscriptionDate;
1426
1427        /** The request token. */
1428        protected String _token;
1429
1430        /** The id of the population */
1431        protected String _population;
1432
1433        /** The id of the user directory of the population */
1434        protected String _userDirectoryId;
1435
1436        /**
1437         * Constructor.
1438         * @param site the site
1439         * @param email the user's email
1440         * @param subscriptionDate the date of subscription
1441         * @param token the user's token
1442         * @param population The id of the population
1443         * @param userDirectoryId The id of the user directory of the population
1444         */
1445        public TempUser(String site, String email, Date subscriptionDate, String token, String population, String userDirectoryId)
1446        {
1447            this._site = site;
1448            this._email = email;
1449            this._subscriptionDate = subscriptionDate;
1450            this._token = token;
1451            this._population = population;
1452            this._userDirectoryId = userDirectoryId;
1453        }
1454        /**
1455         * Get the site.
1456         * @return the site
1457         */
1458        public String getSite()
1459        {
1460            return _site;
1461        }
1462        /**
1463         * Set the site.
1464         * @param site the site to set
1465         */
1466        public void setSite(String site)
1467        {
1468            this._site = site;
1469        }
1470        /**
1471         * Get the email.
1472         * @return _the email
1473         */
1474        public String getEmail()
1475        {
1476            return _email;
1477        }
1478        /**
1479         * Set the email.
1480         * @param email the email to set
1481         */
1482        public void setEmail(String email)
1483        {
1484            this._email = email;
1485        }
1486        /**
1487         * Get the subscriptionDate.
1488         * @return _the subscriptionDate
1489         */
1490        public Date getSubscriptionDate()
1491        {
1492            return _subscriptionDate;
1493        }
1494        /**
1495         * Set the subscriptionDate.
1496         * @param subscriptionDate the subscriptionDate to set
1497         */
1498        public void setSubscriptionDate(Date subscriptionDate)
1499        {
1500            this._subscriptionDate = subscriptionDate;
1501        }
1502        /**
1503         * Get the token.
1504         * @return _the token
1505         */
1506        public String getToken()
1507        {
1508            return _token;
1509        }
1510        /**
1511         * Set the token.
1512         * @param token the token to set
1513         */
1514        public void setToken(String token)
1515        {
1516            this._token = token;
1517        }
1518        /**
1519         * Get the population.
1520         * @return the population
1521         */
1522        public String getPopulation()
1523        {
1524            return _population;
1525        }
1526        /**
1527         * Set the population.
1528         * @param population the population to set
1529         */
1530        public void setPopulation(String population)
1531        {
1532            this._population = population;
1533        }
1534        /**
1535         * Get the user directory id.
1536         * @return the user directory id
1537         */
1538        public String getUserDirectoryId()
1539        {
1540            return _userDirectoryId;
1541        }
1542        /**
1543         * Set the user directory index.
1544         * @param userDirectoryId the user directory id to set
1545         */
1546        public void setUserDirectoryIndex(String userDirectoryId)
1547        {
1548            this._userDirectoryId = userDirectoryId;
1549        }
1550
1551    }
1552
1553}