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