001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.portlets.registration;
018:
019: import java.io.FileNotFoundException;
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.Arrays;
023: import java.util.Date;
024: import java.util.HashMap;
025: import java.util.LinkedList;
026: import java.util.List;
027: import java.util.Locale;
028: import java.util.Map;
029: import java.util.MissingResourceException;
030: import java.util.ResourceBundle;
031:
032: import javax.portlet.ActionRequest;
033: import javax.portlet.ActionResponse;
034: import javax.portlet.PortletConfig;
035: import javax.portlet.PortletException;
036: import javax.portlet.PortletMode;
037: import javax.portlet.PortletPreferences;
038: import javax.portlet.PortletRequest;
039: import javax.portlet.PortletResponse;
040: import javax.portlet.RenderRequest;
041: import javax.portlet.RenderResponse;
042: import javax.portlet.WindowState;
043:
044: import org.apache.jetspeed.CommonPortletServices;
045: import org.apache.jetspeed.JetspeedActions;
046: import org.apache.jetspeed.PortalReservedParameters;
047: import org.apache.jetspeed.administration.AdministrationEmailException;
048: import org.apache.jetspeed.administration.PortalAdministration;
049: import org.apache.jetspeed.locator.JetspeedTemplateLocator;
050: import org.apache.jetspeed.locator.LocatorDescriptor;
051: import org.apache.jetspeed.locator.TemplateDescriptor;
052: import org.apache.jetspeed.locator.TemplateLocatorException;
053: import org.apache.jetspeed.request.RequestContext;
054: import org.apache.jetspeed.security.SecurityException;
055: import org.apache.jetspeed.security.User;
056: import org.apache.jetspeed.security.UserManager;
057: import org.apache.portals.bridges.util.PreferencesHelper;
058: import org.apache.portals.bridges.velocity.AbstractVelocityMessagingPortlet;
059: import org.apache.portals.gems.util.ValidationHelper;
060: import org.apache.velocity.context.Context;
061:
062: /**
063: * This portlet allows a logged on user to change its password.
064: *
065: * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
066: * @author <a href="mailto:chris@bluesunrise.com">Chris Schaefer</a>
067: * @version $Id: $
068: */
069: public class UserRegistrationPortlet extends
070: AbstractVelocityMessagingPortlet {
071:
072: private PortalAdministration admin;
073:
074: private UserManager userManager;
075:
076: // commonly USED attributes
077:
078: private static final String USER_ATTRIBUTE_EMAIL = "user.business-info.online.email";
079:
080: // Messages
081: private static final String MSG_MESSAGE = "MSG";
082:
083: private static final String MSG_USERINFO = "user";
084:
085: private static final String MSG_REGED_USER_MSG = "registeredUserMsg";
086:
087: // Init Parameters
088: private static final String IP_ROLES = "roles"; // comma separated
089:
090: private static final String IP_GROUPS = "groups"; // comma separated
091:
092: private static final String IP_TEMPLATE_LOCATION = "emailTemplateLocation";
093:
094: private static final String IP_TEMPLATE_NAME = "emailTemplateName";
095:
096: private static final String IP_RULES_NAMES = "rulesNames";
097:
098: private static final String IP_RULES_VALUES = "rulesValues";
099:
100: private static final String IP_REDIRECT_PATH = "redirectPath";
101:
102: private static final String IP_RETURN_URL = "returnURL";
103:
104: private static final String IP_OPTION_EMAILS_SYSTEM_UNIQUE = "Option_Emails_System_Unique";
105:
106: private static final String IP_OPTION_GENERATE_PASSWORDS = "Option_Generate_Passwords";
107:
108: private static final String IP_OPTION_USE_EMAIL_AS_USERNAME = "Option_Use_Email_As_Username";
109:
110: // Context Variables
111: private static final String CTX_RETURN_URL = "returnURL";
112:
113: private static final String CTX_MESSAGE = "MSG";
114:
115: private static final String CTX_USERINFO = "user";
116:
117: private static final String CTX_FIELDS = "fieldsInOrder";
118:
119: private static final String CTX_OPTIONALS = "optionalMap";
120:
121: private static final String CTX_REGED_USER_MSG = "registeredUserMsg";
122:
123: private static final String CTX_OPTION_GENERATE_PASSWORDS = "CTX_Option_Generate_Passwords";
124:
125: private static final String CTX_OPTION_USE_EMAIL_AS_USERNAME = "CTX_Option_Use_Email_As_Username";
126:
127: // Resource Bundle
128: private static final String RB_EMAIL_SUBJECT = "email.subject.registration";
129:
130: private static final String PATH_SEPARATOR = "/";
131:
132: /** email template to use for merging */
133: private String templateLocation;
134:
135: private String templateName;
136:
137: private JetspeedTemplateLocator templateLocator;
138:
139: /** localized emailSubject */
140: private String emailSubject = null;
141:
142: /** path where to redirect to after pressing submit on the form */
143: private String redirectPath;
144:
145: /** servlet path of the return url to be printed and href'd in email template */
146: private String returnUrlPath;
147:
148: /** roles */
149: private List roles;
150:
151: /** groups */
152: private List groups;
153:
154: /** profile rules */
155: private Map rules;
156:
157: /** will force the passwords to be generated instead of picked by the user */
158: private boolean optionForceGeneratedPasswords = false;
159:
160: /**
161: * will use cause the portlet to use a user request username instead
162: * otherwise forces emailaddress
163: */
164: private boolean optionForceEmailAsUsername = true;
165:
166: /** will check to make sure the email address is unique to the system */
167: private boolean optionForceEmailsToBeSystemUnique = true;
168:
169: public void init(PortletConfig config) throws PortletException {
170: super .init(config);
171: admin = (PortalAdministration) getPortletContext()
172: .getAttribute(
173: CommonPortletServices.CPS_PORTAL_ADMINISTRATION);
174: if (null == admin) {
175: throw new PortletException(
176: "Failed to find the Portal Administration on portlet initialization");
177: }
178: userManager = (UserManager) getPortletContext().getAttribute(
179: CommonPortletServices.CPS_USER_MANAGER_COMPONENT);
180: if (null == userManager) {
181: throw new PortletException(
182: "Failed to find the User Manager on portlet initialization");
183: }
184:
185: // roles
186: this .roles = getInitParameterList(config, IP_ROLES);
187:
188: // groups
189: this .groups = getInitParameterList(config, IP_GROUPS);
190:
191: // rules (name,value pairs)
192: List names = getInitParameterList(config, IP_RULES_NAMES);
193: List values = getInitParameterList(config, IP_RULES_VALUES);
194: rules = new HashMap();
195: for (int ix = 0; ix < ((names.size() < values.size()) ? names
196: .size() : values.size()); ix++) {
197: rules.put(names.get(ix), values.get(ix));
198: }
199:
200: this .templateLocation = config
201: .getInitParameter(IP_TEMPLATE_LOCATION);
202: if (templateLocation == null) {
203: templateLocation = "/WEB-INF/view/userreg/";
204: }
205: templateLocation = getPortletContext().getRealPath(
206: templateLocation);
207: this .templateName = config.getInitParameter(IP_TEMPLATE_NAME);
208: if (templateName == null) {
209: templateName = "userRegistrationEmail.vm";
210: }
211:
212: ArrayList roots = new ArrayList(1);
213: roots.add(templateLocation);
214:
215: try {
216: templateLocator = new JetspeedTemplateLocator(roots,
217: "email", getPortletContext().getRealPath("/"));
218: templateLocator.start();
219: } catch (FileNotFoundException e) {
220: throw new PortletException(
221: "Could not start the template locator.", e);
222: }
223:
224: // user attributes ?
225:
226: this .optionForceEmailsToBeSystemUnique = Boolean
227: .valueOf(
228: config
229: .getInitParameter(IP_OPTION_EMAILS_SYSTEM_UNIQUE))
230: .booleanValue();
231: this .optionForceGeneratedPasswords = Boolean.valueOf(
232: config.getInitParameter(IP_OPTION_GENERATE_PASSWORDS))
233: .booleanValue();
234: this .optionForceEmailAsUsername = Boolean
235: .valueOf(
236: config
237: .getInitParameter(IP_OPTION_USE_EMAIL_AS_USERNAME))
238: .booleanValue();
239: if (this .optionForceEmailAsUsername) {
240: // just to be sure
241: this .optionForceEmailsToBeSystemUnique = true;
242: }
243: this .returnUrlPath = config.getInitParameter(IP_RETURN_URL);
244: this .redirectPath = config.getInitParameter(IP_REDIRECT_PATH);
245: }
246:
247: public void doEdit(RenderRequest request, RenderResponse response)
248: throws PortletException, IOException {
249: response.setContentType("text/html");
250: doPreferencesEdit(request, response);
251: }
252:
253: protected void doDispatch(RenderRequest request,
254: RenderResponse response) throws PortletException,
255: IOException {
256: if (!request.getWindowState().equals(WindowState.MINIMIZED)) {
257: PortletMode curMode = request.getPortletMode();
258: if (JetspeedActions.EDIT_DEFAULTS_MODE.equals(curMode)) {
259: //request.setAttribute(PARAM_EDIT_PAGE, DEFAULT_EDIT_DEFAULTS_PAGE);
260: doEdit(request, response);
261: } else {
262: super .doDispatch(request, response);
263: }
264: }
265:
266: }
267:
268: public void doView(RenderRequest request, RenderResponse response)
269: throws PortletException, IOException {
270: response.setContentType("text/html");
271: Context context = getContext(request);
272:
273: Object userinfoObject = this .receiveRenderMessage(request,
274: MSG_USERINFO);
275: context.put(CTX_USERINFO, userinfoObject);
276: context.put(CTX_FIELDS, getListOfNonSpecialFormKeys());
277: context.put(CTX_OPTIONALS, getOptionalMap());
278: context.put(CTX_MESSAGE, consumeRenderMessage(request,
279: MSG_MESSAGE));
280: String guid = request.getParameter("newUserGUID");
281: if (guid != null) {
282: // we'll ignore the possibility of an invalid guid for now.
283:
284: // NOTE this would be a good place to put the actual registration if
285: // that's the process you want to have happen.
286:
287: ResourceBundle resource = getPortletConfig()
288: .getResourceBundle(request.getLocale());
289: context.put(CTX_REGED_USER_MSG, resource
290: .getString("success.login_above"));
291: } else {
292: // not a returning url, but perhaps we just got redirected from the
293: // form ?
294: // if this is non-null, then we know that we registered
295: context.put(CTX_REGED_USER_MSG, consumeRenderMessage(
296: request, MSG_REGED_USER_MSG));
297: }
298: // next two control the existence of some of the fields in the form
299: if (this .optionForceEmailAsUsername) {
300: context.put(CTX_OPTION_USE_EMAIL_AS_USERNAME, "TRUE");
301: }
302: if (this .optionForceGeneratedPasswords) {
303: context.put(CTX_OPTION_GENERATE_PASSWORDS, "TRUE");
304: }
305:
306: super .doView(request, response);
307: }
308:
309: private static final Boolean required = new Boolean(true);
310:
311: private static final Boolean optional = new Boolean(false);
312:
313: private static final Integer IS_STRING = new Integer(1);
314:
315: private static final Integer IS_EMAIL = new Integer(2);
316:
317: private static final Integer IS_PHONE = new Integer(3);
318:
319: private static final Integer IS_URL = new Integer(4);
320:
321: private static final Integer IS_BDATE = new Integer(5);
322:
323: protected List getListOfNonSpecialFormKeys() {
324: List l = new ArrayList();
325: for (int i = 0; i < formKeys.length; i++) {
326: String key = (String) formKeys[i][0];
327: if (key.equals("user.name")) {
328: // don't put this in
329: } else if (key.equals("user.business-info.online.email")) {
330: // don't put this in
331: } else if (key.equals("password")) {
332: // don't put this in
333: } else if (key.equals("verifyPassword")) {
334: // don't put this in
335: } else {
336: // but DO add this
337: l.add(key);
338: }
339: }
340: return l;
341: }
342:
343: protected Map getOptionalMap() {
344: Map m = new HashMap();
345: for (int i = 0; i < formKeys.length; i++) {
346: boolean isRequired = ((Boolean) formKeys[i][1])
347: .booleanValue();
348: if (!isRequired) {
349: m.put(formKeys[i][0], "");
350: }
351: }
352: return m;
353: }
354:
355: // PLT name, required, max length, validation type
356:
357: protected static Object[][] formKeys = {
358: // the next four items are special cases
359:
360: // this is the offical email used by jetspeed. You can chnage it, but you have to look around in the code
361: { "user.business-info.online.email", required,
362: new Integer(80), IS_EMAIL },
363:
364: // username is required here
365: // chould be commented out if email is used as username...
366: { "user.name", required, new Integer(80), IS_STRING },
367:
368: // These last two are special cases you must have them
369: // comment them out here if you use the generated password option
370: { "password", required, new Integer(80), IS_STRING },
371: { "verifyPassword", required, new Integer(80), IS_STRING },
372:
373: // the following can be placed in any order, and will appear in that order on the page
374:
375: // All of the following are optional and are stored as user attributes if collected.
376:
377: /*
378: {"user.bdate", optional , new Integer(25), IS_BDATE}, // Note: store as a string which is a number, time in milliseconds since 1970... see Portlet Spec.
379: {"user.gender", optional , new Integer(10), IS_STRING},
380: {"user.employer", optional , new Integer(80), IS_STRING},
381: */
382:
383: { "user.department", optional, new Integer(80), IS_STRING },
384: /*
385: {"user.jobtitle", optional , new Integer(80), IS_STRING},
386: {"user.name.prefix", optional , new Integer(10), IS_STRING},
387: */
388: { "user.name.given", optional, new Integer(30), IS_STRING },
389: { "user.name.family", optional, new Integer(30), IS_STRING },
390: /*
391: {"user.name.middle", optional , new Integer(30), IS_STRING},
392: {"user.name.suffix", optional , new Integer(10), IS_STRING},
393: {"user.name.nickName", optional , new Integer(30), IS_STRING},
394: {"user.home-info.postal.name", optional , new Integer(80), IS_STRING},
395: {"user.home-info.postal.street", optional , new Integer(80), IS_STRING},
396: {"user.home-info.postal.city", optional , new Integer(80), IS_STRING},
397: {"user.home-info.postal.stateprov", optional , new Integer(80), IS_STRING},
398: {"user.home-info.postal.postalcode", optional , new Integer(80), IS_STRING},
399: {"user.home-info.postal.country", optional , new Integer(80), IS_STRING},
400: {"user.home-info.postal.organization", optional , new Integer(80), IS_STRING},
401: {"user.home-info.telecom.telephone.intcode", optional , new Integer(80), IS_STRING},
402: {"user.home-info.telecom.telephone.loccode", optional , new Integer(80), IS_STRING},
403: {"user.home-info.telecom.telephone.number", optional , new Integer(80), IS_PHONE},
404: {"user.home-info.telecom.telephone.ext", optional , new Integer(80), IS_STRING},
405: {"user.home-info.telecom.telephone.comment", optional , new Integer(80), IS_STRING},
406: {"user.home-info.telecom.fax.intcode", optional , new Integer(80), IS_STRING},
407: {"user.home-info.telecom.fax.loccode", optional , new Integer(80), IS_STRING},
408: {"user.home-info.telecom.fax.number", optional , new Integer(80), IS_STRING},
409: {"user.home-info.telecom.fax.ext", optional , new Integer(80), IS_STRING},
410: {"user.home-info.telecom.fax.comment", optional , new Integer(80), IS_STRING},
411: {"user.home-info.telecom.mobile.intcode", optional , new Integer(80), IS_STRING},
412: {"user.home-info.telecom.mobile.loccode", optional , new Integer(80), IS_STRING},
413: {"user.home-info.telecom.mobile.number",optional , new Integer(80), IS_PHONE},
414: {"user.home-info.telecom.mobile.ext", optional , new Integer(80), IS_STRING},
415: {"user.home-info.telecom.mobile.comment", optional , new Integer(80), IS_STRING},
416: {"user.home-info.telecom.pager.intcode", optional , new Integer(80), IS_STRING},
417: {"user.home-info.telecom.pager.loccode", optional , new Integer(80), IS_STRING},
418: {"user.home-info.telecom.pager.number", optional , new Integer(80), IS_PHONE},
419: {"user.home-info.telecom.pager.ext", optional , new Integer(80), IS_STRING},
420: {"user.home-info.telecom.pager.comment", optional , new Integer(80), IS_STRING},
421: {"user.home-info.online.email", optional , new Integer(80), IS_EMAIL},
422: {"user.home-info.online.uri", optional , new Integer(80), IS_URL},
423: */
424: { "user.business-info.postal.name", optional,
425: new Integer(80), IS_STRING },
426: { "user.business-info.postal.street", optional,
427: new Integer(80), IS_STRING },
428: { "user.business-info.postal.city", optional,
429: new Integer(80), IS_STRING },
430: { "user.business-info.postal.stateprov", optional,
431: new Integer(80), IS_STRING },
432: { "user.business-info.postal.postalcode", optional,
433: new Integer(80), IS_STRING },
434: { "user.business-info.postal.country", optional,
435: new Integer(80), IS_STRING },
436: { "user.business-info.postal.organization", optional,
437: new Integer(80), IS_STRING },
438: /*
439: {"user.business-info.telecom.telephone.intcode", optional , new Integer(80), IS_STRING},
440: {"user.business-info.telecom.telephone.loccode", optional , new Integer(80), IS_STRING},
441: {"user.business-info.telecom.telephone.number", optional , new Integer(80), IS_PHONE},
442: {"user.business-info.telecom.telephone.ext", optional , new Integer(80), IS_STRING},
443: {"user.business-info.telecom.telephone.comment", optional , new Integer(80), IS_STRING},
444: {"user.business-info.telecom.fax.intcode", optional , new Integer(80), IS_STRING},
445: {"user.business-info.telecom.fax.loccode", optional , new Integer(80), IS_STRING},
446: {"user.business-info.telecom.fax.number", optional , new Integer(80), IS_PHONE},
447: {"user.business-info.telecom.fax.ext", optional , new Integer(80), IS_STRING},
448: {"user.business-info.telecom.fax.comment", optional , new Integer(80), IS_STRING},
449: {"user.business-info.telecom.mobile.intcode", optional , new Integer(80), IS_STRING},
450: {"user.business-info.telecom.mobile.loccode", optional , new Integer(80), IS_STRING},
451: {"user.business-info.telecom.mobile.number", optional , new Integer(80), IS_PHONE},
452: {"user.business-info.telecom.mobile.ext", optional , new Integer(80), IS_STRING},
453: {"user.business-info.telecom.mobile.comment", optional , new Integer(80), IS_STRING},
454: {"user.business-info.telecom.pager.intcode", optional , new Integer(80), IS_STRING},
455: {"user.business-info.telecom.pager.loccode", optional , new Integer(80), IS_STRING},
456: {"user.business-info.telecom.pager.number", optional , new Integer(80), IS_PHONE},
457: {"user.business-info.telecom.pager.ext", optional , new Integer(80), IS_STRING},
458: {"user.business-info.telecom.pager.comment", optional , new Integer(80), IS_STRING},
459: // --- special case see above user.business-info.online.email
460: {"user.business-info.online.uri", optional , new Integer(80), IS_URL},
461: */
462: };
463:
464: protected boolean validateFormValue(String value, Integer length,
465: Integer validationType) {
466:
467: if (validationType.equals(IS_STRING)) {
468: if (!ValidationHelper.isAny(value, true, length.intValue())) {
469: return false;
470: }
471: } else if (validationType.equals(IS_EMAIL)) {
472: if (!ValidationHelper.isEmailAddress(value, true, length
473: .intValue())) {
474: return false;
475: }
476: } else if (validationType.equals(IS_PHONE)) {
477: if (!ValidationHelper.isPhoneNumber(value, true, length
478: .intValue())) {
479: return false;
480: }
481: } else if (validationType.equals(IS_URL)) {
482: if (!ValidationHelper.isURL(value, true, length.intValue())) {
483: return false;
484: }
485: } else if (validationType.equals(IS_BDATE)) {
486: if (!ValidationHelper.isValidDatetime(value)) {
487: return false;
488: }
489: } else {
490: // unkown type assume string for now
491: if (!ValidationHelper.isAny(value, true, length.intValue())) {
492: return false;
493: }
494: }
495: return true;
496:
497: }
498:
499: protected String convertIfNeed(String key, String value) {
500: if ("user.bdate".equals(key)) {
501: // this one needs conversion
502: Date d = ValidationHelper.parseDate(value);
503: long timeInmS = d.getTime();
504: return "" + timeInmS;
505: }
506: return value;
507: }
508:
509: public void processAction(ActionRequest actionRequest,
510: ActionResponse actionResponse) throws PortletException,
511: IOException {
512: List errors = new LinkedList();
513:
514: Map userAttributes = new HashMap();
515:
516: Map userInfo = new HashMap();
517: ResourceBundle resource = getPortletConfig().getResourceBundle(
518: actionRequest.getLocale());
519:
520: PortletMode curMode = actionRequest.getPortletMode();
521:
522: if (curMode == PortletMode.EDIT
523: || curMode.equals(JetspeedActions.EDIT_DEFAULTS_MODE)) {
524: PortletPreferences prefs = actionRequest.getPreferences();
525: PreferencesHelper.requestParamsToPreferences(actionRequest);
526: prefs.store();
527: actionResponse.setPortletMode(PortletMode.VIEW);
528: return;
529: }
530:
531: try {
532:
533: for (int i = 0; i < formKeys.length; i++) {
534: try {
535: String key = (String) formKeys[i][0];
536: Boolean isRequired = (Boolean) formKeys[i][1];
537: String value = actionRequest.getParameter(key);
538: if ((value != null) && (value.length() > 0)) {
539:
540: userInfo.put(key, value);
541:
542: // do some validation
543: if (!validateFormValue(value,
544: (Integer) formKeys[i][2],
545: (Integer) formKeys[i][3])) {
546: errors.add(resource
547: .getString("error.invalid-format."
548: + key));
549: }
550:
551: if (key.startsWith("user.")) {
552: value = convertIfNeed(key, value);
553: // we'll assume that these map back to PLT.D values
554: userAttributes.put(key, value);
555: }
556: } else {
557: // don't have that value or it's too short... is it
558: // required ?
559: if (isRequired.booleanValue()) {
560: errors.add(resource
561: .getString("error.lacking." + key));
562: }
563: // place an empty version in userInfo anyway
564: // so that the template will display the correct fields
565: userInfo.put(key, "");
566: }
567: } catch (MissingResourceException mre) {
568: errors.add(resource
569: .getString("error.failed_to_add")
570: + mre.toString());
571: }
572:
573: }
574: // publish the whole map so we can reload the form values on error.
575: publishRenderMessage(actionRequest, MSG_USERINFO, userInfo);
576:
577: // These next checks may duplicate previous checks.
578: // however this is a double check given the nature of the values and
579: // how they are used.
580: if (this .optionForceEmailAsUsername) {
581: // email is something special
582: if (!ValidationHelper.isEmailAddress((String) userInfo
583: .get(USER_ATTRIBUTE_EMAIL), true, 80)) {
584: errors.add(resource
585: .getString("error.invalid-format."
586: + USER_ATTRIBUTE_EMAIL));
587: }
588: } else {
589: if (!ValidationHelper.isAny((String) userInfo
590: .get("user.name"), true, 80)) {
591: errors.add(resource
592: .getString("error.lacking.user.name"));
593: }
594: }
595:
596: // if we're not generating make sure it's real
597: if (!this .optionForceGeneratedPasswords) {
598: if (!ValidationHelper.isAny((String) userInfo
599: .get("password"), true, 25)) {
600: errors.add(resource
601: .getString("error.lacking.password"));
602: }
603: }
604:
605: if (optionForceEmailAsUsername) {
606: // force user.name to be same as email
607: userInfo.put("user.name", userInfo
608: .get(USER_ATTRIBUTE_EMAIL));
609: }
610:
611: boolean userIdExistsFlag = true;
612: try {
613: userManager.getUser((String) userInfo.get("user.name"));
614: } catch (SecurityException e) {
615: userIdExistsFlag = false;
616: }
617: //
618: if (userIdExistsFlag) {
619: errors.add(resource
620: .getString("error.userid_already_exists"));
621: publishRenderMessage(actionRequest, MSG_MESSAGE, errors);
622: return;
623: }
624: if (optionForceEmailsToBeSystemUnique) {
625: boolean emailExistsFlag = true;
626: User user = null;
627: try {
628: user = admin.lookupUserFromEmail((String) userInfo
629: .get(USER_ATTRIBUTE_EMAIL));
630: } catch (AdministrationEmailException e1) {
631: emailExistsFlag = false;
632: }
633: if ((emailExistsFlag) || (user != null)) {
634: errors.add(resource
635: .getString("error.email_already_exists"));
636: publishRenderMessage(actionRequest, MSG_MESSAGE,
637: errors);
638: return;
639: }
640:
641: }
642:
643: try {
644: if (optionForceGeneratedPasswords) {
645: String password = admin.generatePassword();
646: userInfo.put("password", password);
647: } else {
648: if (userInfo.get("password").equals(
649: userInfo.get("verifyPassword"))) {
650:
651: } else {
652: errors
653: .add(resource
654: .getString("error.two_passwords_do_not_match"));
655: publishRenderMessage(actionRequest,
656: MSG_MESSAGE, errors);
657: return;
658: }
659: }
660: } catch (Exception e) {
661: errors.add(resource.getString("error.failed_to_add")
662: + e.toString());
663: publishRenderMessage(actionRequest, MSG_MESSAGE, errors);
664: }
665: // make sure no errors have occurred
666: if (errors.size() > 0) {
667: publishRenderMessage(actionRequest, MSG_MESSAGE, errors);
668: return;
669: }
670:
671: // Ok, we think we're good to go, let's create the user!
672: try {
673: PortletPreferences prefs = actionRequest
674: .getPreferences();
675: String template = prefs.getValue(
676: "newUserTemplateDirectory", "");
677: if (template.trim().length() == 0)
678: template = null;
679: String subsiteRootFolder = prefs.getValue(
680: "subsiteRootFolder", "");
681: if (subsiteRootFolder.trim().length() == 0)
682: subsiteRootFolder = null;
683: List prefRoles = getPreferencesList(prefs, IP_ROLES);
684: if (prefRoles.isEmpty())
685: prefRoles = this .roles;
686: List prefGroups = getPreferencesList(prefs, IP_GROUPS);
687: if (prefGroups.isEmpty())
688: prefGroups = this .groups;
689:
690: List names = getPreferencesList(prefs, IP_RULES_NAMES);
691: List values = getPreferencesList(prefs, IP_RULES_VALUES);
692: Map profileRules = new HashMap();
693: for (int ix = 0; ix < ((names.size() < values.size()) ? names
694: .size()
695: : values.size()); ix++) {
696: profileRules.put(names.get(ix), values.get(ix));
697: }
698: if (profileRules.isEmpty())
699: profileRules = this .rules;
700:
701: admin.registerUser((String) userInfo.get("user.name"),
702: (String) userInfo.get("password"), prefRoles,
703: prefGroups, userAttributes, // note use of only
704: // PLT.D values here.
705: profileRules, template, subsiteRootFolder);
706:
707: String urlGUID = ForgottenPasswordPortlet.makeGUID(
708: (String) userInfo.get("user.name"),
709: (String) userInfo.get("password"));
710:
711: userInfo.put(CTX_RETURN_URL, generateReturnURL(
712: actionRequest, actionResponse, urlGUID));
713:
714: String templ = getTemplatePath(actionRequest,
715: actionResponse);
716:
717: if (templ == null) {
718: throw new Exception("email template not available");
719: }
720:
721: boolean sendEmail = prefs.getValue("SendEmail", "true")
722: .equals("true");
723: if (sendEmail) {
724: admin
725: .sendEmail(getPortletConfig(),
726: (String) userInfo
727: .get(USER_ATTRIBUTE_EMAIL),
728: getEmailSubject(actionRequest),
729: templ, userInfo);
730: }
731:
732: if ((this .optionForceEmailAsUsername)
733: || (this .optionForceGeneratedPasswords)) {
734: publishRenderMessage(
735: actionRequest,
736: MSG_REGED_USER_MSG,
737: resource
738: .getString("success.check_your_email"));
739: } else {
740: publishRenderMessage(actionRequest,
741: MSG_REGED_USER_MSG, resource
742: .getString("success.login_above"));
743: }
744:
745: // put an empty map to "erase" all the user info going forward
746: publishRenderMessage(actionRequest, MSG_USERINFO,
747: new HashMap());
748:
749: actionResponse.sendRedirect(this .generateRedirectURL(
750: actionRequest, actionResponse));
751:
752: } catch (Exception e) {
753: errors.add(resource.getString("error.failed_to_add")
754: + e.toString());
755: publishRenderMessage(actionRequest, MSG_MESSAGE, errors);
756: }
757: } catch (MissingResourceException mre) {
758: errors.add(resource.getString("error.failed_to_add")
759: + mre.toString());
760: publishRenderMessage(actionRequest, MSG_MESSAGE, errors);
761: } catch (Exception e) {
762: errors.add(resource.getString("error.failed_to_add")
763: + e.toString());
764: publishRenderMessage(actionRequest, MSG_MESSAGE, errors);
765: }
766:
767: }
768:
769: protected String getEmailSubject(PortletRequest request) {
770: ResourceBundle resource = getPortletConfig().getResourceBundle(
771: request.getLocale());
772: try {
773: this .emailSubject = resource.getString(RB_EMAIL_SUBJECT);
774: } catch (java.util.MissingResourceException mre) {
775: this .emailSubject = null;
776: }
777: if (this .emailSubject == null)
778: this .emailSubject = "Registration Confirmation";
779: return this .emailSubject;
780: }
781:
782: protected List getInitParameterList(PortletConfig config,
783: String ipName) {
784: String temp = config.getInitParameter(ipName);
785: if (temp == null)
786: return new ArrayList();
787:
788: String[] temps = temp.split("\\,");
789: for (int ix = 0; ix < temps.length; ix++)
790: temps[ix] = temps[ix].trim();
791:
792: return Arrays.asList(temps);
793: }
794:
795: protected List getPreferencesList(PortletPreferences prefs,
796: String prefName) {
797: String temp = prefs.getValue(prefName, "");
798: if (temp == null || temp.trim().length() == 0)
799: return new ArrayList();
800:
801: String[] temps = temp.split("\\,");
802: for (int ix = 0; ix < temps.length; ix++)
803: temps[ix] = temps[ix].trim();
804:
805: return Arrays.asList(temps);
806: }
807:
808: protected String generateReturnURL(PortletRequest request,
809: PortletResponse response, String urlGUID) {
810: String fullPath = this .returnUrlPath + "?newUserGUID="
811: + urlGUID;
812: // NOTE: getPortalURL will encode the fullPath for us
813: String url = admin.getPortalURL(request, response, fullPath);
814: return url;
815: }
816:
817: protected String generateRedirectURL(PortletRequest request,
818: PortletResponse response) {
819: return admin.getPortalURL(request, response, this .redirectPath);
820: }
821:
822: protected String getTemplatePath(ActionRequest request,
823: ActionResponse response) {
824: if (templateLocator == null) {
825: return templateLocation + PATH_SEPARATOR + templateName;
826: }
827:
828: RequestContext requestContext = (RequestContext) request
829: .getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
830: Locale locale = request.getLocale();
831:
832: try {
833: LocatorDescriptor locator = templateLocator
834: .createLocatorDescriptor("email");
835: locator.setName(templateName);
836: locator.setMediaType(requestContext.getMediaType());
837: locator.setLanguage(locale.getLanguage());
838: locator.setCountry(locale.getCountry());
839: TemplateDescriptor template = templateLocator
840: .locateTemplate(locator);
841:
842: return template.getAppRelativePath();
843: } catch (TemplateLocatorException e) {
844: return templateLocation + PATH_SEPARATOR + templateName;
845: }
846: }
847: }
|