0001: /* ====================================================================
0002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003: *
0004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005: *
0006: * Redistribution and use in source and binary forms, with or without
0007: * modification, are permitted provided that the following conditions
0008: * are met:
0009: *
0010: * 1. Redistributions of source code must retain the above copyright
0011: * notice, this list of conditions and the following disclaimer.
0012: *
0013: * 2. Redistributions in binary form must reproduce the above copyright
0014: * notice, this list of conditions and the following disclaimer in
0015: * the documentation and/or other materials provided with the
0016: * distribution.
0017: *
0018: * 3. The end-user documentation included with the redistribution,
0019: * if any, must include the following acknowledgment:
0020: * "This product includes software developed by Jcorporate Ltd.
0021: * (http://www.jcorporate.com/)."
0022: * Alternately, this acknowledgment may appear in the software itself,
0023: * if and wherever such third-party acknowledgments normally appear.
0024: *
0025: * 4. "Jcorporate" and product names such as "Expresso" must
0026: * not be used to endorse or promote products derived from this
0027: * software without prior written permission. For written permission,
0028: * please contact info@jcorporate.com.
0029: *
0030: * 5. Products derived from this software may not be called "Expresso",
0031: * or other Jcorporate product names; nor may "Expresso" or other
0032: * Jcorporate product names appear in their name, without prior
0033: * written permission of Jcorporate Ltd.
0034: *
0035: * 6. No product derived from this software may compete in the same
0036: * market space, i.e. framework, without prior written permission
0037: * of Jcorporate Ltd. For written permission, please contact
0038: * partners@jcorporate.com.
0039: *
0040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051: * SUCH DAMAGE.
0052: * ====================================================================
0053: *
0054: * This software consists of voluntary contributions made by many
0055: * individuals on behalf of the Jcorporate Ltd. Contributions back
0056: * to the project(s) are encouraged when you make modifications.
0057: * Please send them to support@jcorporate.com. For more information
0058: * on Jcorporate Ltd. and its products, please see
0059: * <http://www.jcorporate.com/>.
0060: *
0061: * Portions of this software are based upon other open source
0062: * products and are subject to their respective licenses.
0063: */
0064:
0065: /**
0066: * ControllerSecurityMatrix.java Copyright 2000, 2001 Jcorporate Ltd.
0067: */package com.jcorporate.expresso.services.controller;
0068:
0069: import com.jcorporate.expresso.core.controller.Block;
0070: import com.jcorporate.expresso.core.controller.Controller;
0071: import com.jcorporate.expresso.core.controller.ControllerException;
0072: import com.jcorporate.expresso.core.controller.ControllerRequest;
0073: import com.jcorporate.expresso.core.controller.ControllerResponse;
0074: import com.jcorporate.expresso.core.controller.ErrorCollection;
0075: import com.jcorporate.expresso.core.controller.Input;
0076: import com.jcorporate.expresso.core.controller.NonHandleableException;
0077: import com.jcorporate.expresso.core.controller.Output;
0078: import com.jcorporate.expresso.core.controller.ServletControllerRequest;
0079: import com.jcorporate.expresso.core.controller.State;
0080: import com.jcorporate.expresso.core.controller.Transition;
0081: import com.jcorporate.expresso.core.dataobjects.DataObjectMetaData;
0082: import com.jcorporate.expresso.core.dataobjects.jdbc.JDBCObjectMetaData;
0083: import com.jcorporate.expresso.core.db.DBException;
0084: import com.jcorporate.expresso.core.dbobj.DBObject;
0085: import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
0086: import com.jcorporate.expresso.core.logging.LogException;
0087: import com.jcorporate.expresso.core.misc.ConfigManager;
0088: import com.jcorporate.expresso.core.misc.StringUtil;
0089: import com.jcorporate.expresso.core.security.User;
0090: import com.jcorporate.expresso.kernel.util.FastStringBuffer;
0091: import com.jcorporate.expresso.services.controller.ui.DefaultAutoElement;
0092: import com.jcorporate.expresso.services.dbobj.GroupMembers;
0093: import com.jcorporate.expresso.services.dbobj.RegistrationDomain;
0094: import com.jcorporate.expresso.services.dbobj.RegistrationObjectMap;
0095: import com.jcorporate.expresso.services.dbobj.Setup;
0096: import com.jcorporate.expresso.services.dbobj.UserGroup;
0097: import com.jcorporate.expresso.services.validation.AuthValidationException;
0098: import com.jcorporate.expresso.services.validation.ValidationEntry;
0099: import org.apache.log4j.Logger;
0100:
0101: import javax.servlet.http.HttpServletRequest;
0102: import java.util.Iterator;
0103: import java.util.Map;
0104: import java.util.StringTokenizer;
0105:
0106: /**
0107: * SimpleRegistration Controller. This is the implementation example of
0108: * Registration. Depends on:
0109: * <p/>
0110: * <ul>
0111: * <li>
0112: * Login Controller
0113: * </li>
0114: * <li>
0115: * Email Validator
0116: * </li>
0117: * <li>
0118: * Registration Validator
0119: * </li>
0120: * <li>
0121: * Reg Domain DBObjects
0122: * </li>
0123: * <li>
0124: * Reg Domain DBObject Map
0125: * </li>
0126: * </ul>
0127: * <p/>
0128: * <h4>
0129: * <p/>
0130: * <p/>
0131: * The following states are the usual entry points into the registration
0132: * controller
0133: * </p>
0134: * <p/>
0135: * <ul>
0136: * <li>
0137: * showDBMenu - For users that want to change/edit their registraiton info
0138: * </li>
0139: * <li>
0140: * promptAddRecord - Where we prompt the user to fill out the registration
0141: * information
0142: * </li>
0143: * <li>
0144: * promptSelfRegister - Where we prompt for login information et.al. from users
0145: * who wish to self-register
0146: * </li>
0147: * <li>
0148: * promptApproval - For approval administrators only. Shows the registration
0149: * information and asks if a user should be approved or not.
0150: * </li>
0151: * </ul>
0152: * <p/>
0153: * <p/>
0154: * Parameter Explanation: Login Controller == the classname of the login
0155: * controller that should be forwarded to upon transfer back to the login
0156: * controller.
0157: * </p>
0158: * Creation date: (6/23/2001 4:05:05 PM)
0159: *
0160: * @author Shash Chatterjee, refactored by Michael Rimov
0161: */
0162: public class SimpleRegistration extends
0163: com.jcorporate.expresso.services.controller.Registration {
0164: private static Logger log = Logger
0165: .getLogger(SimpleRegistration.class);
0166:
0167: /**
0168: * Registration constructor comment.
0169: */
0170: public SimpleRegistration() {
0171: super ();
0172:
0173: State showDBMenu = new State("showDBMenu",
0174: "Menu of Registration Data");
0175: showDBMenu.addOptionalParameter("loginController");
0176: addState(showDBMenu);
0177:
0178: State emailValidate = new State("emailValidate",
0179: "Validate User's Email Address");
0180: emailValidate.addRequiredParameter("db");
0181: emailValidate.addRequiredParameter("UserName");
0182: emailValidate.addOptionalParameter("loginController");
0183: emailValidate.addOptionalParameter("registrationController");
0184: addState(emailValidate);
0185:
0186: State promptAddRecord = new State("promptAddRecord",
0187: "Prompt Add Registration Info");
0188: promptAddRecord.addRequiredParameter("dbobj");
0189: promptAddRecord.addOptionalParameter("loginController");
0190: addState(promptAddRecord);
0191:
0192: State processAddRecord = new State("processAddRecord",
0193: "Continue Registration");
0194: processAddRecord.addOptionalParameter("loginController");
0195: addState(processAddRecord);
0196:
0197: State promptUpdateRecord = new State("promptUpdateRecord",
0198: "Prompt Update Registration Info");
0199: promptUpdateRecord.addRequiredParameter("dbobj");
0200: promptUpdateRecord.addRequiredParameter("keys");
0201: promptUpdateRecord.addOptionalParameter("loginController");
0202: addState(promptUpdateRecord);
0203:
0204: State processUpdateRecord = new State("processUpdateRecord",
0205: "Update");
0206: processUpdateRecord.addRequiredParameter("keys"); //Needed to transition back to promptUpdate upon error.
0207: processUpdateRecord.addOptionalParameter("loginController");
0208: addState(processUpdateRecord);
0209:
0210: State promptDeleteRecord = new State("promptDeleteRecord",
0211: "Prompt Delete Registration Info");
0212: promptDeleteRecord.addOptionalParameter("loginController");
0213: addState(promptDeleteRecord);
0214:
0215: State processDeleteRecord = new State("processDeleteRecord",
0216: "Delete");
0217: processDeleteRecord.addOptionalParameter("loginController");
0218: addState(processDeleteRecord);
0219:
0220: State processListRecords = new State("processListRecords",
0221: "List Registration Records");
0222: processListRecords.addOptionalParameter("loginController");
0223: addState(processListRecords);
0224:
0225: State promptSelfRegister = new State("promptSelfRegister",
0226: "Prompt the user for basic account setup");
0227: addState(promptSelfRegister);
0228: promptSelfRegister.addRequiredParameter("dbContext");
0229: promptSelfRegister.addOptionalParameter("loginController");
0230:
0231: State processSelfRegister = new State("processSelfRegister",
0232: "Process the self-registration request");
0233: processSelfRegister.addOptionalParameter("loginController");
0234: processSelfRegister.addOptionalParameter("LoginName");
0235: processSelfRegister.addParameter("Email", false,
0236: DBObject.EMAIL_MASK,
0237: "You must enter a valid email address");
0238: processSelfRegister.addOptionalParameter("Email_verify"); // verify field is already matched for equality against email field
0239: processSelfRegister.addOptionalParameter("Password");
0240: processSelfRegister.addOptionalParameter("Password_verify");
0241: processSelfRegister.addRequiredParameter("dbContext");
0242: processSelfRegister.addRequiredParameter("regDomain");
0243: addState(processSelfRegister);
0244:
0245: State promptApproval = new State("promptApproval",
0246: "Prompt adminsitrators for approving users' registration");
0247: promptApproval.addOptionalParameter("loginController");
0248: promptApproval.addRequiredParameter("db");
0249: promptApproval.addRequiredParameter("UserName");
0250: addState(promptApproval);
0251:
0252: State processApproval = new State("processApproval",
0253: "Process adminsitrator action for approving users' registration");
0254: processApproval.addOptionalParameter("loginController");
0255: processApproval.addRequiredParameter("db");
0256: processApproval.addRequiredParameter("UserName");
0257: processApproval.addRequiredParameter("command");
0258: addState(processApproval);
0259:
0260: State processRevalidate = new State("processRevalidate",
0261: "Process Revalidate Registration");
0262: processRevalidate.addRequiredParameter("Email");
0263: addState(processRevalidate);
0264:
0265: setInitialState("showDBMenu");
0266: }
0267:
0268: /**
0269: * Get the title of this registration controller
0270: *
0271: * @return the String title of this registration.
0272: */
0273: public String getTitle() {
0274: return ("Detailed Registration");
0275: }
0276:
0277: /**
0278: * Based upon customization of the registration domain, should a particular
0279: * field name be displayed in the registration form.
0280: *
0281: * @param rd The registration domain that this request is under
0282: * @param db The secured dbobject that will be the container for the
0283: * resulting data
0284: * @param fieldName the field name of the database object.
0285: * @param forListView is this for showing the registration list
0286: * @return true if the field should be visible to the end user.
0287: * @throws ControllerException if there's trouble talking with the dbobject
0288: */
0289: protected boolean isShowable(RegistrationDomain rd, DBObject db,
0290: String fieldName, boolean forListView)
0291: throws ControllerException {
0292: try {
0293: if (db.getMetaData().getFieldMetadata(fieldName)
0294: .isReadOnly()
0295: || db.getMetaData().getFieldMetadata(fieldName)
0296: .isVirtual()) {
0297: return false;
0298: }
0299:
0300: String dbname = db.getClass().getName();
0301: RegistrationObjectMap rom = new RegistrationObjectMap();
0302: rom.setDataContext(rd.getDataContext());
0303: rom.setField("RegDomId", rd.getField("RegDomId"));
0304: rom.setField("RegObj", dbname);
0305:
0306: if (!rom.find()) {
0307: throw new ControllerException(
0308: "Registration object map not created for domain/dbname '"
0309: + rd.getField("Name") + "/" + dbname
0310: + " '");
0311: }
0312:
0313: if (fieldName.equals(rom.getField("UidField"))) {
0314: return false;
0315: }
0316:
0317: String oneFieldName = null;
0318: String fields = "" + rom.getField("RegFields");
0319:
0320: if (fields.equals("")) {
0321: return true;
0322: }
0323:
0324: StringTokenizer stk = new StringTokenizer(fields, ",");
0325:
0326: while (stk.hasMoreTokens()) {
0327: oneFieldName = stk.nextToken();
0328: oneFieldName = oneFieldName.trim();
0329:
0330: if (oneFieldName.startsWith("!")) {
0331: if (oneFieldName.substring(1).equals(fieldName)) {
0332: return false;
0333: }
0334: }
0335:
0336: if (oneFieldName.startsWith("+")) {
0337: if (forListView
0338: && (oneFieldName.substring(1)
0339: .equals(fieldName))) {
0340: return true;
0341: }
0342: }
0343:
0344: if (fieldName.equals(oneFieldName)) {
0345: return true;
0346: }
0347: }
0348: } catch (DBException dbe) {
0349: throw new ControllerException("Database error", dbe);
0350: }
0351:
0352: return true;
0353: }
0354:
0355: /**
0356: * Builds the registration fill-in form.
0357: *
0358: * @param rd The registration domain of this request
0359: * @param db The secured DBObject that contains the data to fill out.
0360: * @param response The controllerResponse handed down by the framework
0361: * @return A block that represents all the fill in forms for this object.
0362: * @throws ControllerException upon error.
0363: */
0364: protected Block buildForm(RegistrationDomain rd, DBObject db,
0365: ControllerResponse response) throws ControllerException {
0366: String dbobjName = db.getClass().getName() + ".";
0367: Block block = new Block("dbobject");
0368: Map map = (Map) response.getCurrentState().getSession()
0369: .getAttribute(DefaultAutoElement.SESSION_KEY);
0370: DBObject dbobj2 = db;
0371:
0372: if (map != null) {
0373: DBObject temp = (DBObject) map.get(db.getClass().getName());
0374:
0375: if (temp != null) {
0376: dbobj2 = temp;
0377: }
0378: }
0379:
0380: response.getCurrentState().getSession().removeAttribute(
0381: DefaultAutoElement.SESSION_KEY);
0382:
0383: //block.setForm("true");
0384: String fieldName = null;
0385:
0386: try {
0387: JDBCObjectMetaData metaData = db.getJDBCMetaData();
0388: block
0389: .add(new Output("block-title", metaData
0390: .getDescription(response.getRequest()
0391: .getLocale())));
0392:
0393: for (Iterator e = metaData.getFieldListArray().iterator(); e
0394: .hasNext();) {
0395: fieldName = (String) e.next();
0396:
0397: if (isShowable(rd, dbobj2, fieldName, false)) {
0398: String fieldValue = StringUtil.notNull(dbobj2
0399: .getField(fieldName));
0400:
0401: if (fieldValue.length() == 0) {
0402: try {
0403: fieldValue = (String) response
0404: .getFormCache().get(
0405: dbobj2.getClass().getName()
0406: + "." + fieldName);
0407: } catch (Exception ex) {
0408: //Ignore this error, we were only trying to see if the
0409: //form cache had anything.
0410: }
0411: }
0412:
0413: Input field = DefaultAutoElement
0414: .getAutoControllerElement()
0415: .renderDBObjectField(response, dbobj2,
0416: fieldName, fieldValue, false);
0417:
0418: if (field != null) {
0419: field.setName(dbobjName + field.getName());
0420: block.add(field);
0421: }
0422: }
0423: }
0424: } catch (DBException dbe) {
0425: throw new ControllerException(dbe);
0426: }
0427:
0428: return block;
0429: }
0430:
0431: /**
0432: * Builds the specially pre-defined block of login information.
0433: *
0434: * @param rd The Registration Domain the user is to register for.
0435: * @param request the ControllerRequest object
0436: * @param response The ControllerResponse object
0437: * @return an instantiated and filled out Block for login information
0438: */
0439: protected Block buildLoginBlock(RegistrationDomain rd,
0440: ControllerRequest request, ControllerResponse response)
0441: throws ControllerException {
0442: Block b = new Block("login-information");
0443: b.add(new Output("block-title", "Login Information"));
0444:
0445: // Retrieve the registration domain information
0446: boolean emailAsLogin = false;
0447: boolean userPasswd = false;
0448:
0449: try {
0450: if (rd.getField("EmailAsLogin").equals("Y")) {
0451: emailAsLogin = true;
0452: }
0453:
0454: if (rd.getField("UserPasswd").equals("Y")) {
0455: userPasswd = true;
0456: }
0457: } catch (DBException dbe) {
0458: throw new ControllerException("DB failure on domain \""
0459: + rd + "\"", dbe);
0460: }
0461:
0462: String errorStyle = null;
0463:
0464: //Unless this site uses the email address as login name, create an input to specify login name
0465: if (!emailAsLogin) {
0466: Input loginName = new Input();
0467: loginName.setName("LoginName");
0468: loginName.setLabel("Login Name*");
0469:
0470: String ln = StringUtil.notNull(response
0471: .getFormCache("LoginName"));
0472: loginName.setDefaultValue(ln);
0473: loginName.setDisplayLength(60);
0474: loginName.setMaxLength(60);
0475: errorStyle = (String) response
0476: .getFormCacheAttribute("LoginName");
0477:
0478: if (errorStyle != null && errorStyle.length() > 0) {
0479: loginName.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0480: errorStyle);
0481: } else {
0482: loginName.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0483: DefaultAutoElement.getAutoControllerElement()
0484: .getRequiredStyle());
0485: }
0486:
0487: b.add(loginName);
0488: }
0489:
0490: //
0491: //
0492: //
0493: Input email = new Input();
0494: email.setName("Email");
0495: email.setLabel("E-Mail Address*");
0496:
0497: String em = StringUtil.notNull(response.getFormCache("Email"));
0498: email.setDefaultValue(em);
0499: email.setDisplayLength(60);
0500: email.setMaxLength(80);
0501: errorStyle = (String) response.getFormCacheAttribute("Email");
0502:
0503: if (errorStyle != null) {
0504: email.setAttribute(Input.ATTRIBUTE_CSS_STYLE, errorStyle);
0505: } else {
0506: email.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0507: DefaultAutoElement.getAutoControllerElement()
0508: .getRequiredStyle());
0509: }
0510:
0511: b.add(email);
0512:
0513: Input email_verify = new Input();
0514: email_verify.setName("Email_verify");
0515: email_verify.setLabel("E-Mail Address(confirm)*");
0516:
0517: String emv = StringUtil.notNull(response
0518: .getFormCache("Email_verify"));
0519: email_verify.setDefaultValue(emv);
0520: email_verify.setDisplayLength(60);
0521: email_verify.setMaxLength(80);
0522: errorStyle = (String) response
0523: .getFormCacheAttribute("Email_verify");
0524:
0525: if (errorStyle != null && errorStyle.length() > 0) {
0526: email_verify.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0527: errorStyle);
0528: } else {
0529: email_verify.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0530: DefaultAutoElement.getAutoControllerElement()
0531: .getRequiredStyle());
0532: }
0533:
0534: b.add(email_verify);
0535:
0536: if (userPasswd) {
0537: Input password = new Input();
0538: password.setName("Password");
0539: password.setLabel("Password*");
0540:
0541: String pw = StringUtil.notNull(response
0542: .getFormCache("Password"));
0543: password.setDefaultValue(pw);
0544: password.setDisplayLength(30);
0545: password.setMaxLength(30);
0546: password.setType("password");
0547: password.setAttribute(Input.ATTRIBUTE_PASSWORD, "Y");
0548: errorStyle = (String) response
0549: .getFormCacheAttribute("Password");
0550:
0551: if (errorStyle != null && errorStyle.length() > 0) {
0552: password.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0553: errorStyle);
0554: } else {
0555: password.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0556: DefaultAutoElement.getAutoControllerElement()
0557: .getRequiredStyle());
0558: }
0559:
0560: b.add(password);
0561:
0562: Input password_verify = new Input();
0563: password_verify.setName("Password_verify");
0564: password_verify.setLabel("Password (confirm)*");
0565:
0566: String pwv = StringUtil.notNull(response
0567: .getFormCache("Password_verify"));
0568: password_verify.setDefaultValue(pwv);
0569: password_verify.setDisplayLength(30);
0570: password_verify.setMaxLength(30);
0571: password_verify.setType("password");
0572: password_verify.setAttribute(Input.ATTRIBUTE_PASSWORD, "Y");
0573: errorStyle = (String) response
0574: .getFormCacheAttribute("Password_verify");
0575:
0576: if (errorStyle != null && errorStyle.length() > 0) {
0577: password_verify.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0578: errorStyle);
0579: } else {
0580: password_verify.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
0581: DefaultAutoElement.getAutoControllerElement()
0582: .getRequiredStyle());
0583: }
0584:
0585: b.add(password_verify);
0586: }
0587:
0588: return b;
0589: }
0590:
0591: /**
0592: * Step #1 in registration - pick a username and password. This function
0593: * performs the guts of the owrk.
0594: *
0595: * @param errors The system fills out the errors collection if there are
0596: * problems with the registration processing.
0597: * @param request The ControllerRequest handed off to a controller by the
0598: * framework
0599: * @param response The ControllerResponse handed off to a controller by the
0600: * framework.
0601: * @param rd if successful, rd will contain an instantiated registration
0602: * domain object representing the registration domain that this
0603: * user belongs to.
0604: * @return an Instantiated User object or null if errors exist.
0605: * @throws DBException upon data access error
0606: * @throws ControllerException upon controller error
0607: * @throws LogException upon logging error
0608: * @throws NonHandleableException upon fatal error
0609: */
0610: protected User processLoginInformation(ErrorCollection errors,
0611: ControllerRequest request, ControllerResponse response,
0612: RegistrationDomain rd) throws DBException,
0613: ControllerException, LogException, NonHandleableException {
0614: String regDomain = request.getParameter("regDomain");
0615: boolean emailAsLogin = false;
0616: boolean userPasswd = false;
0617: boolean emailValidate = false;
0618: boolean approvalRequired = false;
0619: rd.setDataContext(request.getDataContext());
0620: rd.setField("Name", regDomain);
0621:
0622: if (!rd.find()) {
0623: errors.addError("Registration domain \"" + regDomain
0624: + "\" has not been defined");
0625: }
0626:
0627: if (rd.getField("EmailAsLogin").equals("Y")) {
0628: emailAsLogin = true;
0629: }
0630:
0631: if (rd.getField("UserPasswd").equals("Y")) {
0632: userPasswd = true;
0633: }
0634:
0635: if (rd.getField("EmailValidate").equals("Y")) {
0636: emailValidate = true;
0637: }
0638:
0639: if (rd.getField("Approve").equals("Y")) {
0640: approvalRequired = true;
0641: }
0642:
0643: String loginName = "";
0644: String email = "";
0645: String email_verify = "";
0646: String password = "";
0647: String password_verify = "";
0648:
0649: // Hashtable theFormCache = response.getFormCache();
0650: String errorStyle = DefaultAutoElement
0651: .getAutoControllerElement().getErrorStyle();
0652: email = request.getParameter("Email");
0653: email_verify = request.getParameter("Email_verify");
0654:
0655: if (email.equals("")) {
0656: response.setFormCacheAttribute("Email", errorStyle);
0657: errors.addError("Please specify a non-blank email address");
0658: }
0659:
0660: if (!email.equals(email_verify)) {
0661: response.setFormCacheAttribute("Email", errorStyle);
0662: response.setFormCacheAttribute("Email_verify", errorStyle);
0663: errors
0664: .addError("Email address did not match the confirmation email address");
0665: }
0666:
0667: //Unless this site uses the email address as login name, fill in the login name
0668: if (!emailAsLogin) {
0669: loginName = request.getParameter("LoginName");
0670:
0671: if (loginName.equals("")) {
0672: response.setFormCacheAttribute("LoginName", errorStyle);
0673: errors
0674: .addError("Please specify a non-blank login name");
0675: } else if (loginName.indexOf("%") >= 0) {
0676: response.setFormCacheAttribute("LoginName", errorStyle);
0677: errors
0678: .addError("You cannot have percent signs in your login name");
0679: }
0680: } else {
0681: loginName = email;
0682: }
0683:
0684: if (userPasswd) {
0685: password = StringUtil.notNull(request
0686: .getParameter("Password"));
0687: password_verify = StringUtil.notNull(request
0688: .getParameter("Password_verify"));
0689:
0690: if (password.equals("")) {
0691: response.setFormCacheAttribute("Password", errorStyle);
0692: errors.addError("Please specify a non-blank password");
0693: } else {
0694: if (!password.equals(password_verify)) {
0695: response.setFormCacheAttribute("Password_verify",
0696: errorStyle);
0697: errors
0698: .addError("Password did not match the confirmation password");
0699: } else {
0700: try {
0701: int passwordSize = Integer.parseInt(StringUtil
0702: .notNull(ConfigManager.getContext(
0703: request.getDataContext())
0704: .getMinPasswordSize()));
0705:
0706: if (passwordSize > password.length()) {
0707: response.setFormCacheAttribute("Password",
0708: errorStyle);
0709: response.setFormCacheAttribute(
0710: "Password_verify", errorStyle);
0711: errors
0712: .addError("Passwords must be greater than "
0713: + (passwordSize - 1)
0714: + " characters in length");
0715: }
0716: } catch (com.jcorporate.expresso.core.misc.ConfigurationException ce) {
0717: log.error(
0718: "Error getting minimum password length for db context "
0719: + request.getDataContext(), ce);
0720: }
0721: }
0722: }
0723: }
0724:
0725: if (errors.getErrorCount() > 0) {
0726: return null;
0727: }
0728:
0729: User user = new User();
0730: user.setDataContext(request.getDataContext());
0731: user.setLoginName(loginName);
0732:
0733: if (user.find()) {
0734: FastStringBuffer fsb = new FastStringBuffer(64);
0735: fsb.append("Login \"");
0736: fsb.append(loginName);
0737: fsb.append("\" is already registered in db/context '");
0738: fsb.append(request.getDataContext());
0739: fsb.append("', please choose a new login name");
0740: errors.addError(fsb.toString());
0741: }
0742:
0743: user.clear();
0744: user.setEmail(email);
0745:
0746: if (user.find()) {
0747: FastStringBuffer fsb = new FastStringBuffer(64);
0748: fsb.append("Email \"");
0749: fsb.append(email);
0750: fsb.append("\" is already registered in db/context '");
0751: fsb.append(request.getDataContext());
0752: fsb.append("'");
0753: errors.addError(fsb.toString());
0754: }
0755:
0756: if (errors.getErrorCount() > 0) {
0757: delayLogin(); //Make 'em pay :)
0758:
0759: return user;
0760: }
0761:
0762: user.clear();
0763: user.setDataContext(request.getDataContext());
0764: user.setLoginName(loginName);
0765: user.setEmail(email);
0766: user.setDisplayName(loginName);
0767:
0768: if (emailValidate) {
0769: user.setAccountStatus("I");
0770: } else if (approvalRequired) {
0771: user.setAccountStatus("W");
0772: } else {
0773: user.setAccountStatus("A");
0774: }
0775:
0776: if (!userPasswd) {
0777: password = user.randomPassword();
0778: }
0779:
0780: user.setPassword(password);
0781: user.setRegistrationDomain(regDomain);
0782: user.add();
0783:
0784: if (log.isDebugEnabled()) {
0785: log.debug("Added user id '" + user.getUid()
0786: + "' for login name '" + user.getLoginName() + "'");
0787: }
0788:
0789: String groupName = null;
0790:
0791: if (rd.getField("RegRequired").equalsIgnoreCase("Y")) {
0792: groupName = "NotReg";
0793: } else {
0794: groupName = rd.getField(GroupMembers.GROUP_NAME);
0795: }
0796:
0797: GroupMembers gm = new GroupMembers();
0798: gm.setDataContext(request.getDataContext());
0799:
0800: StringTokenizer stk = new StringTokenizer(groupName, " ");
0801:
0802: while (stk.hasMoreTokens()) {
0803: gm.setField(GroupMembers.GROUP_NAME, stk.nextToken());
0804: gm.setField(GroupMembers.EXPUID, user.getUid());
0805: gm.add();
0806: }
0807:
0808: // response.clearFormCache();
0809: // Output successMessage = null;
0810: // Output infoMessage = null;
0811: // ServletControllerRequest sparams = (ServletControllerRequest) request;
0812: // HttpServletRequest hreq = (HttpServletRequest) sparams.getServletRequest();
0813:
0814: /**
0815: * @todo implement code here that gives out the appropriate success
0816: * message
0817: */
0818:
0819: // response.addOutput(successMessage);
0820: // response.addOutput(infoMessage);
0821: // String nextObj = request.getParameter("dbobj");
0822: // If email validation is required or the system generates a password
0823: // for the user, then simply show confirmation of express registration
0824: // since the user needs to receive email first.
0825: // Otherwise, automatically move on to detailed registration (if needed)
0826: // if (nextObj != null) {
0827: // Transition continueRegister = new Transition();
0828: // continueRegister.addParam(Controller.CONTROLLER_PARAM_KEY,this.getClass().getName());
0829: // continueRegister.addParam(STATE_PARAM_KEY, "promptAddRecord");
0830: // continueRegister.addParam("dbobj", nextObj);
0831: // continueRegister.addParam("dbContext", request.getDBName());
0832: // continueRegister.addParam("uid", user.getUidString());
0833: // continueRegister.addParam("loginController",loginController);
0834: // continueRegister.setLabel("Continue Registration");
0835: //
0836: //
0837: // continueRegister.transition(request, response);
0838: // if (log.isDebugEnabled()) {
0839: // log.debug("Transitioned to register...");
0840: // }
0841: // return;
0842: // } else {
0843: // this.processPostRegistration(request,response, user,rd, loginController);
0844: // }
0845: return user;
0846: }
0847:
0848: /**
0849: * Processes post Registration If the user is done.
0850: *
0851: * @param request the ControllerRequest Object
0852: * @param response the ControllerResponse object
0853: * @param user An instantiated user object representing the current User
0854: * registering
0855: * @param rd The RegistrationDomain that this user is registering for
0856: * @param loginControllerName The name of the login controller used for
0857: * referencing back to this class
0858: * @return A completed ControllerResponse object
0859: * @throws NonHandleableException upon fatal error
0860: */
0861: protected ControllerResponse processPostRegistration(
0862: ControllerRequest request, ControllerResponse response,
0863: User user, RegistrationDomain rd, String loginControllerName)
0864: throws DBException, ControllerException,
0865: NonHandleableException {
0866: boolean backToMenu = false;
0867:
0868: if (StringUtil.notNull(request.getParameter("backToMenu"))
0869: .equalsIgnoreCase("Y")) {
0870: backToMenu = true;
0871: }
0872: //Used for generating messages.
0873:
0874: FastStringBuffer fsb = new FastStringBuffer(56);
0875: boolean emailValidate = false;
0876: boolean approvalRequired = false;
0877:
0878: //Set up registration domain parameters
0879: if (rd.getField("EmailValidate").equalsIgnoreCase("Y")) {
0880: emailValidate = true;
0881: }
0882:
0883: if (rd.getField("Approve").equalsIgnoreCase("Y")) {
0884: approvalRequired = true;
0885: }
0886:
0887: Output successMessage = null;
0888: Output infoMessage = null;
0889: HttpServletRequest hreq = (HttpServletRequest) ((ServletControllerRequest) request)
0890: .getServletRequest();
0891:
0892: // No more records to add ... complete registration
0893: //Make sure that this does not require manual approval
0894: if (approvalRequired) {
0895: try {
0896: ValidationEntry ve = new ValidationEntry(request
0897: .getDataContext());
0898: ve
0899: .setValidationHandler("com.jcorporate.expresso.services.validation.ApproveRegistrationValidator");
0900: ve.setTitle("Registration Approval Validation");
0901:
0902: //
0903: //Set admin expiration for 1 week.
0904: //
0905: ve.expiresAfter(24 * 7, 0, 0);
0906: fsb.clear();
0907: fsb.append("user=");
0908: fsb.append(user.getLoginName());
0909: fsb.append(", db=");
0910: fsb.append(request.getDataContext());
0911: ve.setDesc(fsb.toString());
0912: ve.setServer(hreq.getServerName());
0913: ve.setPort(Integer.toString(hreq.getServerPort()));
0914: ve.setContextPath(hreq.getContextPath());
0915: ve.addParam("db", request.getDataContext());
0916: ve.addParam("UserName", user.getLoginName());
0917: ve.addParam("RegistrationController", this .getClass()
0918: .getName());
0919: ve.addParam("LoginController", loginControllerName);
0920: ve.submit();
0921: } catch (AuthValidationException avex) {
0922: throw new ControllerException(
0923: "Validation framework exception", avex);
0924: }
0925:
0926: response
0927: .addOutput(new Output("successMessage", response
0928: .getString("registration.success.approval",
0929: user.getLoginName(), request
0930: .getDataContext())));
0931: response.addOutput(new Output("infoMessage", response
0932: .getString("registration.info.approval")));
0933: } else if (emailValidate) {
0934: setupEmailValidation(request, response, user, rd,
0935: loginControllerName);
0936: successMessage = new Output("successMessage", response
0937: .getString("registration.success.validate", user
0938: .getLoginName(), request.getDataContext()));
0939: infoMessage = new Output("infoMessage", response.getString(
0940: "registration.info.validate", user.getEmail()));
0941: } else {
0942: // If the user is a member of the "Not Regsitered Yet" group,
0943: // move user to group specified in domain
0944: GroupMembers gm = new GroupMembers();
0945: gm.setDataContext(request.getDataContext());
0946: gm.setField(GroupMembers.EXPUID, user.getUid());
0947: gm.setField(GroupMembers.GROUP_NAME, "NotReg");
0948:
0949: if (gm.find()) {
0950: String groupName = rd.getField(GroupMembers.GROUP_NAME);
0951:
0952: if ((groupName == null) || (groupName.equals(""))) {
0953: groupName = UserGroup.ALL_USERS_GROUP;
0954: }
0955:
0956: gm.delete();
0957: gm.clear();
0958: gm.setField(GroupMembers.EXPUID, user.getUid());
0959: gm.setField(GroupMembers.GROUP_NAME, groupName);
0960: gm.add();
0961: }
0962:
0963: successMessage = new Output("successMessage",
0964: "You are fully registered and may log in now.");
0965:
0966: if (!approvalRequired && !emailValidate) {
0967: StringBuffer msg = new StringBuffer(128);
0968: msg.append(response.getString("loginConfEM", user
0969: .getLoginName(),
0970: "<undisclosed for security reasons>", Setup
0971: .getValue(request.getDataContext(),
0972: "CompanyName"), Setup
0973: .getValue(request.getDataContext(),
0974: "HomePageURL")));
0975:
0976: try {
0977: user.notify(response.getString("loginConfSubj"),
0978: msg.toString());
0979: } catch (Exception e) {
0980: log.error(
0981: "Trouble sending registration-welcome email to user: "
0982: + request.getUser(), e);
0983: response.addError("Cannot send response email: "
0984: + e.getClass().getName() + "; "
0985: + e.getMessage());
0986: }
0987: }
0988:
0989: if (backToMenu) {
0990: transition("showDBMenu", request, response);
0991: }
0992:
0993: Transition doLogin = new Transition();
0994: doLogin.setName("promptLogin");
0995: doLogin.setLabel("Go To Login");
0996: doLogin.addParam(Controller.CONTROLLER_PARAM_KEY,
0997: loginControllerName);
0998: doLogin.addParam(STATE_PARAM_KEY, "promptLogin");
0999: doLogin.addParam("dbContext", request.getDataContext());
1000: response.add(doLogin);
1001: }
1002:
1003: checkRegComplete(request, user.getUid());
1004:
1005: if (successMessage != null) {
1006: response.add(successMessage);
1007: }
1008:
1009: if (infoMessage != null) {
1010: response.add(infoMessage);
1011: }
1012:
1013: return response;
1014: }
1015:
1016: /**
1017: * If the user validates correctly, this method completes registration and
1018: * sends the email notification out. If admin. authorization is required
1019: * this will setup the authorization process.
1020: *
1021: * @param request The ControllerRequest object handed down by the framework
1022: * for this request
1023: * @param response The ControllerResponse object returned by this
1024: * controller
1025: * @throws ControllerException upon error of processing this state.
1026: */
1027: protected void runEmailValidateState(ControllerRequest request,
1028: ControllerResponse response) throws ControllerException {
1029: // Check to make sure the request first went through ValidationController
1030: if (request.getSession().getPersistentAttribute(
1031: ValidationEntry.SESSION_KEY) == null) {
1032: throw new SecurityException(
1033: "Attempt to run emailValidate without first validating");
1034: } else {
1035: request.getSession().removePersistentAttribute(
1036: ValidationEntry.SESSION_KEY);
1037: }
1038:
1039: String dbname = StringUtil.notNull(request.getParameter("db"));
1040:
1041: // The login name of the user
1042: String loginName = StringUtil.notNull(request
1043: .getParameter("UserName"));
1044: String registrationController = StringUtil.notNull(request
1045: .getParameter("RegistrationController"));
1046: String loginController = StringUtil.notNull(request
1047: .getParameter("LoginController"));
1048:
1049: try {
1050: ErrorCollection errors = new ErrorCollection();
1051:
1052: // Make sure that the user with this loginName actually exists
1053: User user = new User();
1054: user.setDataContext(dbname);
1055: user.setLoginName(loginName);
1056:
1057: if (!user.find()) {
1058: errors.addError("Account \"" + loginName
1059: + "\" not found");
1060: }
1061:
1062: // Make sure the User record has not been disabled for some reason, or, already authenticated
1063: if (errors.isEmpty()) {
1064: if (user.getAccountStatus().equals("D")) {
1065: errors.addError("Account \"" + loginName
1066: + "\" has been disabled");
1067: } else if (user.getAccountStatus().equals("A")) {
1068: errors.addError("Account \"" + loginName
1069: + "\" was already authenticated");
1070:
1071: Output o = new Output(
1072: "infoMessage",
1073: "This account has been activated previously. "
1074: + "Please use the password that was sent to you via email. "
1075: + "It takes a few minutes after authentication to receive the email. "
1076: + "If you have not received the email after waiting a reasonable amount of time, "
1077: + "please contact us via email so we can assist you.");
1078: response.add(o);
1079: }
1080:
1081: if (!errors.isEmpty()) {
1082: response.saveErrors(errors);
1083:
1084: return;
1085: }
1086:
1087: // If we get here, everything went OK...time to set the user's status as "active"
1088: // Determine if the registration domain defines that the user should specify
1089: // own password or if one should automatically be defined for the user
1090: boolean userPasswd = false;
1091: RegistrationDomain rd = new RegistrationDomain();
1092: rd.setDataContext(dbname);
1093: rd.setField("Name", user.getRegistrationDomain());
1094:
1095: if (!rd.find()) {
1096: throw new ControllerException(
1097: "Registration domain \""
1098: + user.getRegistrationDomain()
1099: + "\" not created yet");
1100: }
1101:
1102: if (rd.getField("UserPasswd").equals("Y")) {
1103: userPasswd = true;
1104: }
1105:
1106: // Create the content of the registration message to be sent
1107: StringBuffer msg = new StringBuffer();
1108: msg.append(response.getString("loginAuthenticatedEM1",
1109: user.getLoginName(), Setup.getValue(dbname,
1110: "CompanyName")));
1111:
1112: if (!userPasswd) {
1113: // User doesn't specify password, create a random password
1114: String password = user.randomPassword();
1115: user.setPassword(password);
1116: msg.append(response.getString(
1117: "loginAuthenticatedEM2", password));
1118: } else {
1119: msg.append(response
1120: .getString("loginAuthenticatedEM3"));
1121: }
1122:
1123: msg.append(response.getString("loginAuthenticatedEM4",
1124: Setup.getValue(dbname, "CompanyName"), Setup
1125: .getValue(dbname, "HomePageURL")));
1126:
1127: // mark this user as "activated"
1128: user.setAccountStatus("A");
1129: user.update();
1130:
1131: // If the user is a member of the "Not Regsitered Yet" group,
1132: // move user to group specified in domain
1133: GroupMembers gm = new GroupMembers();
1134: gm.setDataContext(request.getDataContext());
1135: gm.setField(GroupMembers.EXPUID, user.getUid());
1136: gm.setField(GroupMembers.GROUP_NAME, "NotReg");
1137: if (gm.find()) {
1138: gm.delete();
1139: }
1140:
1141: String groupName = rd.getField(GroupMembers.GROUP_NAME);
1142: if ((groupName == null) || (groupName.equals(""))) {
1143: groupName = UserGroup.ALL_USERS_GROUP;
1144: }
1145: gm.clear();
1146: gm.setField(GroupMembers.EXPUID, user.getUid());
1147: gm.setField(GroupMembers.GROUP_NAME, groupName);
1148: if (!gm.find()) {
1149: gm.add();
1150: }
1151:
1152: // Send the confirmation email
1153: user.notify(response
1154: .getString("loginAuthenticatedSubject"), msg
1155: .toString());
1156:
1157: // Confirmation messages for the UI
1158: Output o1 = new Output("successMessage", "Account \""
1159: + user.getLoginName()
1160: + "\" Validated Successfully");
1161: response.add(o1);
1162:
1163: Output o2 = new Output("infoMessage",
1164: "Your account is now activated. "
1165: + "An email has been sent to \""
1166: + user.getEmail()
1167: + "\" containing your password.");
1168: response.add(o2);
1169:
1170: Transition login = new Transition();
1171: login.setName("promptLogin");
1172: login.addParam(CONTROLLER_PARAM_KEY, loginController);
1173: login.addParam("dbContext", dbname);
1174: response.add(login);
1175:
1176: Transition editPref = new Transition();
1177: editPref.setName("editPreferences");
1178: editPref
1179: .addParam(CONTROLLER_PARAM_KEY,
1180: "com.jcorporate.expresso.services.controller.EditUserPreference");
1181: editPref.addParam(STATE_PARAM_KEY, "edit");
1182: response.add(editPref);
1183:
1184: Transition showDBMenu = new Transition();
1185: showDBMenu.setName("showDBMenu");
1186: showDBMenu.addParam(CONTROLLER_PARAM_KEY,
1187: registrationController);
1188: showDBMenu.addParam(STATE_PARAM_KEY, "showDBMenu");
1189: response.add(showDBMenu);
1190:
1191: Transition sendPW = new Transition();
1192: sendPW.setName("promptSendPassword");
1193: sendPW.addParam(CONTROLLER_PARAM_KEY, loginController);
1194: sendPW.addParam(STATE_PARAM_KEY, "promptSendPassword");
1195: response.add(sendPW);
1196:
1197: Transition logout = new Transition();
1198: logout.setName("processLogout");
1199: logout.addParam(CONTROLLER_PARAM_KEY, loginController);
1200: response.add(logout);
1201: } else {
1202: response.saveErrors(errors);
1203: }
1204: } catch (DBException dbe) {
1205: throw new ControllerException("DB error", dbe);
1206: }
1207: }
1208:
1209: /**
1210: * Processes the addition of a registration record.
1211: *
1212: * @param request The ControllerRequest object handed down by the framework
1213: * for this request
1214: * @param response The ControllerResponse object returned by this
1215: * controller
1216: * @throws ControllerException upon error of processing this state.
1217: * @throws NonHandleableException upon fatal error
1218: */
1219: protected void runProcessAddRecordState(ControllerRequest request,
1220: ControllerResponse response) throws ControllerException,
1221: NonHandleableException {
1222: String dbContext = StringUtil.notNull(request
1223: .getParameter("dbContext"));
1224: String loginControllerName = getLoginController(request);
1225:
1226: if (!dbContext.equals("")) {
1227: request.setDataContext(dbContext);
1228: }
1229:
1230: boolean backToMenu = false;
1231:
1232: if (StringUtil.notNull(request.getParameter("backToMenu"))
1233: .equalsIgnoreCase("Y")) {
1234: backToMenu = true;
1235: }
1236:
1237: User user = null;
1238:
1239: try {
1240: user = new User();
1241: user.setDataContext(request.getDataContext());
1242: user.setUid(request.getUid());
1243: user.retrieve();
1244: } catch (DBException de) {
1245: throw new ControllerException(de);
1246: }
1247:
1248: RegistrationDomain rd = getRegDomain(request, user);
1249: DBObject db = loadDBObject(request, request
1250: .getParameter("dbobj"));
1251:
1252: try {
1253: RegistrationObjectMap rom = new RegistrationObjectMap();
1254: rom.setDataContext(request.getDataContext());
1255: rom.setField("RegDomId", rd.getField("RegDomId"));
1256: rom.setField("RegObj", request.getParameter("dbobj"));
1257:
1258: if (!rom.find()) {
1259: throw new ControllerException(
1260: "Cannot find registration object map entry");
1261: }
1262:
1263: db.setField(rom.getField("UidField"), user.getUid());
1264: db.setDataContext(request.getDataContext());
1265:
1266: //Set up registration domain parameters
1267: ErrorCollection ec = new ErrorCollection();
1268: db = (DBObject) DefaultAutoElement
1269: .getAutoControllerElement().parseBlock(request, db,
1270: ec);
1271:
1272: // for (Iterator e = db.getFieldListIterator(); e.hasNext();) {
1273: // fieldName = (String)e.next();
1274: //
1275: // if (isShowable(rd, db, fieldName, false)) {
1276: // request.validateDBField(fieldName,db,ec);
1277: // }
1278: // }
1279: response.setFormCache();
1280:
1281: if (ec.size() > 0) {
1282: response.saveErrors(ec);
1283:
1284: if (log.isDebugEnabled()) {
1285: log.debug("There were errors");
1286: }
1287:
1288: transition("promptAddRecord", request, response);
1289:
1290: return;
1291: }
1292:
1293: if (db.getMetaData().isField("IPAddress")) {
1294: ServletControllerRequest sparams = (ServletControllerRequest) request;
1295: HttpServletRequest hreq = (HttpServletRequest) sparams
1296: .getServletRequest();
1297: db.setField("IPAddress", hreq.getRemoteAddr());
1298: }
1299:
1300: db.add();
1301:
1302: if (backToMenu) {
1303: request.setParameter("backToMenu", "Y");
1304: transition("showDBMenu", request, response);
1305:
1306: return;
1307: }
1308:
1309: /* If there are more records to be added, continue... */
1310: String nextToAdd = nextToAdd(request);
1311:
1312: if (nextToAdd != null) {
1313: if (!nextToAdd.equals(db.getClass().getName())) {
1314: request.setParameter("dbobj", nextToAdd);
1315: }
1316:
1317: transition("promptAddRecord", request, response);
1318:
1319: return;
1320: } else {
1321: processPostRegistration(request, response, user, rd,
1322: loginControllerName);
1323: }
1324: } catch (DBException dbe) {
1325: throw new ControllerException(dbe);
1326: }
1327: }
1328:
1329: /**
1330: * Processes the 'administrator wishes to process the approval state'
1331: *
1332: * @param request The ControllerRequest object handed down by the framework
1333: * for this request
1334: * @param response The ControllerResponse object returned by this
1335: * controller
1336: * @throws ControllerException upon error of processing this state.
1337: * @throws NonHandleableException upon fatal error
1338: */
1339: protected void runProcessApprovalState(ControllerRequest request,
1340: ControllerResponse response) throws ControllerException,
1341: NonHandleableException {
1342: ErrorCollection errors = new ErrorCollection();
1343: String loginName = request.getUser();
1344: String loginControllerName = getLoginController(request);
1345:
1346: try {
1347: User myUser = new User();
1348: myUser.setDataContext(request.getDataContext());
1349: myUser.setLoginName(loginName);
1350:
1351: //
1352: //NOTE: the below code is no replacement for individually securing
1353: //this controller's states.
1354: //
1355: if (loginName.equals("")
1356: || loginName.equals(User.UNKNOWN_USER)
1357: || !myUser.find()) {
1358: errors.addError("Must login before approving users");
1359: response.saveErrors(errors);
1360: throw new SecurityException(
1361: "Must login before approving users");
1362: }
1363:
1364: String dbContext = request.getParameter("db");
1365: String loginToApprove = request.getParameter("UserName");
1366: String cmd = request.getParameter("command");
1367: User u = new User();
1368:
1369: if (errors.isEmpty()) {
1370: u.setDataContext(dbContext);
1371: u.setLoginName(loginToApprove);
1372:
1373: if (!u.find()) {
1374: errors.addError("User \"" + loginToApprove
1375: + "\" not found");
1376: }
1377: }
1378:
1379: RegistrationDomain rd = new RegistrationDomain();
1380:
1381: if (errors.isEmpty()) {
1382: rd.setDataContext(dbContext);
1383: rd.setField("Name", u.getRegistrationDomain());
1384:
1385: if (!rd.find()) {
1386: errors.addError("Registration domain \""
1387: + u.getRegistrationDomain()
1388: + "\" not found");
1389: } else {
1390: String approvers = rd.getField("Approvers");
1391: StringTokenizer stk = new StringTokenizer(
1392: approvers, ",");
1393: boolean havePermission = false;
1394:
1395: if (loginName.equals(User.ADMIN_USER)) {
1396: havePermission = true;
1397: }
1398:
1399: while (stk.hasMoreTokens() && !havePermission) {
1400: if (stk.nextToken().equals(loginName)) {
1401: havePermission = true;
1402: }
1403: }
1404:
1405: if (!havePermission) {
1406: errors
1407: .addError("You ("
1408: + loginName
1409: + ") do not have permission to approve users in this domain");
1410: }
1411: }
1412: }
1413:
1414: if (errors.isEmpty()) {
1415: StringBuffer msg = new StringBuffer();
1416: String subject = null;
1417: Output successMessage = new Output("successMessage",
1418: "Approval for user \"" + loginToApprove
1419: + "\" processed successfully");
1420: Output infoMessage = null;
1421:
1422: if (cmd.equals("approve")) {
1423: if (rd.getField("EmailValidate").equalsIgnoreCase(
1424: "Y")) {
1425: u.setAccountStatus("I");
1426: } else {
1427: u.setAccountStatus("A");
1428: }
1429:
1430: // If the user is a member of the "Not Regsitered Yet" group,
1431: // move user to group specified in domain
1432: GroupMembers gm = new GroupMembers();
1433: gm.setDataContext(request.getDataContext());
1434: gm.setField(GroupMembers.EXPUID, u.getUid());
1435: gm.setField(GroupMembers.GROUP_NAME, "NotReg");
1436:
1437: try {
1438: gm.retrieve();
1439:
1440: String groupName = rd
1441: .getField(GroupMembers.GROUP_NAME);
1442:
1443: if ((groupName == null)
1444: || (groupName.equals(""))) {
1445: groupName = UserGroup.ALL_USERS_GROUP;
1446: }
1447:
1448: gm.delete();
1449: gm.clear();
1450: gm.setField(GroupMembers.EXPUID, u.getUid());
1451: gm.setField(GroupMembers.GROUP_NAME, groupName);
1452: gm.add();
1453: } catch (DBException ex) {
1454: if (log.isDebugEnabled()) {
1455: log.debug("Didn't find group for uid: "
1456: + u.getUid());
1457: }
1458: }
1459:
1460: subject = response
1461: .getString("loginApprovedSubject");
1462:
1463: if (rd.getField("EmailValidate").equalsIgnoreCase(
1464: "Y")) {
1465: msg.append(response.getString(
1466: "loginAuthenticatedEM1", u
1467: .getLoginName(), Setup
1468: .getValue(request
1469: .getDataContext(),
1470: "CompanyName")));
1471: } else {
1472: msg.append(response.getString(
1473: "loginRegisteredEM1", u.getLoginName(),
1474: Setup.getValue(
1475: request.getDataContext(),
1476: "CompanyName")));
1477:
1478: if (rd.getField("UserPasswd").equalsIgnoreCase(
1479: "Y")) {
1480: msg
1481: .append(response
1482: .getString("loginAuthenticatedEM3"));
1483: } else {
1484: String password = u.randomPassword();
1485: u.setPassword(password);
1486: msg.append(response.getString(
1487: "loginAuthenticatedEM2", password));
1488: }
1489: }
1490:
1491: msg.append(response.getString(
1492: "loginAuthenticatedEM4", Setup.getValue(
1493: request.getDataContext(),
1494: "CompanyName"), Setup.getValue(
1495: request.getDataContext(),
1496: "HomePageURL")));
1497: infoMessage = new Output("infoMessage",
1498: "Registration was approved, user was notified by email");
1499: } else if (cmd.equals("postpone")) {
1500: ValidationEntry ve = (ValidationEntry) request
1501: .getSession().getPersistentAttribute(
1502: ValidationEntry.SESSION_KEY);
1503:
1504: if (ve != null) {
1505: ve.setStatus(ValidationEntry.WAITING);
1506: request.getSession().removePersistentAttribute(
1507: ValidationEntry.SESSION_KEY);
1508: }
1509:
1510: infoMessage = new Output("infoMessage",
1511: "Registration Decision Postponed");
1512: successMessage = new Output("successMessage",
1513: "Postponement");
1514: response.add(infoMessage);
1515: response.add(successMessage);
1516:
1517: return;
1518: } else if (cmd.equals("deny")) {
1519: u.setAccountStatus("X");
1520: subject = response.getString("loginDeniedSubject");
1521: msg.append(response.getString("loginDeniedMsg",
1522: Setup.getValue(request.getDataContext(),
1523: "CompanyName"), u.getLoginName(),
1524: Setup.getValue(request.getDataContext(),
1525: "HomePageURL"),
1526: "Didn't meet our criteria"));
1527: infoMessage = new Output("infoMessage",
1528: "Registration was denied, user was notified by email");
1529: } else {
1530: throw new ControllerException("Invalid Command");
1531: }
1532:
1533: u.update();
1534:
1535: // If email validation is required by the user's registration domain
1536: // then just send email for the email validation. Otherwise, notify
1537: // the user that approval has been granted/denied.
1538: if (rd.getField("EmailValidate").equalsIgnoreCase("Y")) {
1539: setupEmailValidation(request, response, u, rd,
1540: loginControllerName);
1541: } else {
1542: u.notify(subject, msg.toString());
1543: }
1544:
1545: response.add(successMessage);
1546: response.add(infoMessage);
1547: }
1548: } catch (AuthValidationException ex) {
1549: ValidationEntry ve = (ValidationEntry) request
1550: .getSession()
1551: .getPersistentAttribute(ValidationEntry.SESSION_KEY);
1552:
1553: try {
1554: if (ve != null) {
1555: ve.setStatus(ValidationEntry.WAITING);
1556: }
1557: } catch (AuthValidationException ex1) {
1558: log
1559: .error(
1560: "Error in prompting for authorization and unable to reset Validation Entry ",
1561: ex);
1562: }
1563: } catch (DBException dbe) {
1564: ValidationEntry ve = (ValidationEntry) request
1565: .getSession()
1566: .getPersistentAttribute(ValidationEntry.SESSION_KEY);
1567:
1568: try {
1569: if (ve != null) {
1570: ve.setStatus(ValidationEntry.WAITING);
1571: }
1572: } catch (AuthValidationException ex) {
1573: log
1574: .error(
1575: "Error in prompting for authorization and unable to reset Validation Entry ",
1576: ex);
1577: }
1578:
1579: throw new ControllerException(dbe);
1580: }
1581: }
1582:
1583: /**
1584: * Deletes a registration record.
1585: *
1586: * @param request The ControllerRequest object handed down by the framework
1587: * for this request
1588: * @param response The ControllerResponse object returned by this
1589: * controller
1590: * @throws ControllerException upon error of processing this state.
1591: * @throws NonHandleableException upon fatal error
1592: */
1593: protected void runProcessDeleteRecordState(
1594: ControllerRequest request, ControllerResponse response)
1595: throws ControllerException, NonHandleableException {
1596: User user = getRegUser(request);
1597: RegistrationDomain rd = getRegDomain(request, user);
1598: String dbname = getDB(request);
1599: String keys = request.getParameter("keys");
1600: SecuredDBObject db = loadDBObject(request, dbname);
1601:
1602: try {
1603: RegistrationObjectMap rom = new RegistrationObjectMap();
1604: rom.setDataContext(request.getDataContext());
1605: rom.setField("RegDomId", rd.getField("RegDomId"));
1606: rom.setField("RegObj", dbname);
1607:
1608: if (!rom.find()) {
1609: throw new ControllerException(
1610: "Cannot find registration object map entry");
1611: }
1612:
1613: db.setField(rom.getField("UidField"), user.getUid());
1614:
1615: StringTokenizer stk = new StringTokenizer(keys, "|");
1616:
1617: for (Iterator k = db.getKeyFieldListIterator(); k.hasNext();) {
1618: String fn = (String) k.next();
1619: db.setField(fn, stk.nextToken());
1620: }
1621:
1622: if (!db.find()) {
1623: throw new ControllerException("Record with keys="
1624: + keys + " not found");
1625: }
1626:
1627: db.delete();
1628: checkRegComplete(request, user.getUid());
1629: } catch (DBException dbe) {
1630: throw new ControllerException(dbe);
1631: }
1632:
1633: transition("showDBMenu", request, response);
1634: }
1635:
1636: /**
1637: * Lists the registration records.
1638: *
1639: * @param request The ControllerRequest object handed down by the framework
1640: * for this request
1641: * @param response The ControllerResponse object returned by this
1642: * controller
1643: * @throws ControllerException upon error of processing this state.
1644: */
1645: protected void runProcessListRecordsState(
1646: ControllerRequest request, ControllerResponse response)
1647: throws ControllerException {
1648: ErrorCollection errors = new ErrorCollection();
1649: User user = getRegUser(request);
1650: RegistrationDomain rd = getRegDomain(request, user);
1651: String dbname = getDB(request);
1652: SecuredDBObject db = loadDBObject(request, dbname);
1653: Block row = null;
1654: String loginControllerName = getLoginController(request);
1655:
1656: try {
1657: RegistrationObjectMap rom = new RegistrationObjectMap();
1658: rom.setDataContext(request.getDataContext());
1659: rom.setField("RegDomId", rd.getField("RegDomId"));
1660: rom.setField("RegObj", dbname);
1661:
1662: if (!rom.find()) {
1663: throw new ControllerException(
1664: "Cannot find registration object map entry");
1665: }
1666:
1667: db.setField(rom.getField("UidField"), user.getUid());
1668:
1669: SecuredDBObject oneRec = null;
1670: int recNum = 0;
1671:
1672: for (Iterator e = db.searchAndRetrieveList().iterator(); e
1673: .hasNext();) {
1674: recNum++;
1675: oneRec = (SecuredDBObject) e.next();
1676: oneRec.setDataContext(request.getDataContext());
1677: row = new Block("row" + recNum);
1678:
1679: Output col = new Output("");
1680: String fieldName = null;
1681:
1682: for (Iterator k = oneRec.getMetaData()
1683: .getFieldListArray().iterator(); k.hasNext();) {
1684: fieldName = (String) k.next();
1685:
1686: if (isShowable(rd, db, fieldName, true)) {
1687: col = new Output(fieldName, oneRec
1688: .getField(fieldName));
1689: row.add(col);
1690: }
1691: }
1692:
1693: FastStringBuffer s = new FastStringBuffer(24);
1694:
1695: for (Iterator k = oneRec.getKeyFieldListIterator(); k
1696: .hasNext();) {
1697: String fn = (String) k.next();
1698: s.append(oneRec.getField(fn));
1699: s.append("|");
1700: }
1701:
1702: String registrationControllerName = (this
1703: .getSchemaInstance())
1704: .getRegistrationController().getClass()
1705: .getName();
1706:
1707: if (rom.getField("AllowEdit").equals("Y")) {
1708: Transition edit = new Transition("Update",
1709: "Update", registrationControllerName);
1710: edit
1711: .addParam(STATE_PARAM_KEY,
1712: "promptUpdateRecord");
1713: edit.addParam("dbobj", dbname);
1714: edit.addParam("keys", s.toString());
1715: edit.addParam("loginController",
1716: loginControllerName);
1717: row.add(edit);
1718: }
1719:
1720: if (rom.getField("AllowDel").equals("Y")) {
1721: Transition delete = new Transition("Delete",
1722: "Delete", registrationControllerName);
1723: delete.addParam(STATE_PARAM_KEY,
1724: "promptDeleteRecord");
1725: delete.addParam("dbobj", dbname);
1726: delete.addParam("keys", s.toString());
1727: delete.addParam("loginController",
1728: loginControllerName);
1729: row.add(delete);
1730: }
1731:
1732: response.add(row);
1733: }
1734:
1735: if (errors.getErrorCount() != 0) {
1736: response = this .newState("showDBMenu", request);
1737: response.saveErrors(errors);
1738: }
1739: } catch (Exception e) {
1740: throw new ControllerException("Error processing list", e);
1741: }
1742: }
1743:
1744: /**
1745: * Processes the Self-Registering Users
1746: *
1747: * @param request The ControllerRequest object handed down by the framework
1748: * for this request
1749: * @param response The ControllerResponse object returned by this
1750: * controller
1751: * @throws ControllerException upon error of processing this state.
1752: * @throws NonHandleableException upon fatal error
1753: */
1754: protected void runProcessSelfRegisterState(
1755: ControllerRequest request, ControllerResponse response)
1756: throws ControllerException, NonHandleableException {
1757: response.setFormCache();
1758:
1759: String dbContext = StringUtil.notNull(request
1760: .getParameter("dbContext"));
1761:
1762: if (!dbContext.equals("")) {
1763: request.setDataContext(dbContext);
1764: }
1765:
1766: ErrorCollection ec = request.getErrorCollection();
1767:
1768: if (ec == null) {
1769: ec = new ErrorCollection();
1770: }
1771:
1772: try {
1773: RegistrationDomain rd = new RegistrationDomain();
1774: User user = processLoginInformation(ec, request, response,
1775: rd);
1776:
1777: if (ec.getErrorCount() > 0) {
1778: response.setFormCache();
1779: response.saveErrors(ec);
1780: transition("promptSelfRegister", request, response);
1781:
1782: return;
1783: }
1784:
1785: //
1786: //Ok, we have ourselves a user, let's attempt to deal with the
1787: //registration objects.
1788: //
1789: DBObject[] expectedRegistrationObjects = this
1790: .getRequiredDBObjects(request, rd, user);
1791:
1792: if (expectedRegistrationObjects.length > 0) {
1793: expectedRegistrationObjects = (DBObject[]) DefaultAutoElement
1794: .getAutoControllerElement().parseBlocks(
1795: request, expectedRegistrationObjects,
1796: ec);
1797: }
1798:
1799: if (ec.getErrorCount() > 0) {
1800: response.setFormCache();
1801: response.saveErrors(ec);
1802: user.delete(); //It sucks but this way we essentially rollback the
1803:
1804: //transaction
1805: transition("promptSelfRegister", request, response);
1806:
1807: return;
1808: }
1809:
1810: for (int i = 0; i < expectedRegistrationObjects.length; i++) {
1811: try {
1812: expectedRegistrationObjects[i].add();
1813: } catch (DBException dbe) {
1814: FastStringBuffer fsb = new FastStringBuffer(64);
1815: fsb.append("Error adding registration object: '");
1816: fsb.append(expectedRegistrationObjects[i]
1817: .getMetaData().getDescription(
1818: request.getLocale()));
1819: fsb.append("' Message: ");
1820: fsb.append(dbe.getMessage());
1821:
1822: String errorMessage = fsb.toString();
1823: ec.addError(errorMessage);
1824: log.error(errorMessage, dbe);
1825: }
1826: }
1827:
1828: if (ec.getErrorCount() > 0) {
1829: user.delete(); //It sucks but this way we essentially rollback the
1830:
1831: //transaction
1832: response.saveErrors(ec);
1833: response.setFormCache();
1834: transition("promptSelfRegister", request, response);
1835:
1836: return;
1837: }
1838:
1839: this .processPostRegistration(request, response, user, rd,
1840: this .getLoginController(request));
1841: } catch (DBException de) {
1842: log.error(
1843: "DBException while processing self-register state",
1844: de);
1845: throw new ControllerException(de);
1846: } catch (LogException le) {
1847: log
1848: .error(
1849: "LogException while processing self-register state",
1850: le);
1851: throw new ControllerException(le);
1852: }
1853: }
1854:
1855: /**
1856: * Updates the Registration Record
1857: *
1858: * @param request The ControllerRequest object handed down by the framework
1859: * for this request
1860: * @param response The ControllerResponse object returned by this
1861: * controller
1862: * @throws ControllerException upon error of processing this state.
1863: */
1864: protected void runProcessUpdateRecordState(
1865: ControllerRequest request, ControllerResponse response)
1866: throws ControllerException, NonHandleableException {
1867: User user = getRegUser(request);
1868: RegistrationDomain rd = getRegDomain(request, user);
1869: String dbname = getDB(request);
1870: DBObject db = loadDBObject(request, dbname);
1871: DataObjectMetaData metadata = db.getMetaData();
1872: String fieldName = null;
1873:
1874: try {
1875: ErrorCollection ec = new ErrorCollection();
1876:
1877: for (Iterator e = db.getKeyFieldListIterator(); e.hasNext();) {
1878: fieldName = (String) e.next();
1879: db.setField(fieldName, request.getParameter(dbname
1880: + "." + fieldName));
1881: }
1882:
1883: RegistrationObjectMap rom = new RegistrationObjectMap();
1884: rom.setDataContext(request.getDataContext());
1885: rom.setField("RegDomId", rd.getField("RegDomId"));
1886: rom.setField("RegObj", dbname);
1887:
1888: if (!rom.find()) {
1889: throw new ControllerException(
1890: "Cannot find registration object map entry");
1891: }
1892:
1893: db.setField(rom.getField("UidField"), user.getUid());
1894:
1895: if (!db.find()) {
1896: ec
1897: .addError("Key fields did not match any record in DB");
1898: }
1899:
1900: db = (DBObject) DefaultAutoElement
1901: .getAutoControllerElement().parseBlock(request, db,
1902: ec);
1903:
1904: response.setFormCache();
1905:
1906: // for (Iterator e = metadata.getFieldListArray().iterator();
1907: // e.hasNext();) {
1908: // fieldName = (String) e.next();
1909: //
1910: // if (isShowable(rd, db, fieldName, false)) {
1911: // db.setField(fieldName,
1912: // request.getParameter(dbname + "." + fieldName));
1913: // request.validateField(fieldName, dbname + "." + fieldName,
1914: // db, ec);
1915: // }
1916: // }
1917:
1918: if (ec.size() > 0) {
1919: response.saveErrors(ec);
1920: transition("promptUpdateRecord", request, response);
1921:
1922: return;
1923: }
1924:
1925: if (metadata.isField("IPAddress")) {
1926: ServletControllerRequest sparams = (ServletControllerRequest) request;
1927: HttpServletRequest hreq = (HttpServletRequest) sparams
1928: .getServletRequest();
1929: db.setField("IPAddress", hreq.getRemoteAddr());
1930:
1931: if (log.isDebugEnabled()) {
1932: log.debug("IP address recorded as '"
1933: + hreq.getRemoteAddr() + "'");
1934: }
1935: } else {
1936: if (log.isDebugEnabled()) {
1937: log.debug("Object '" + db.getClass().getName()
1938: + "' does not have an IPAddress field");
1939: }
1940: }
1941:
1942: db.update();
1943: checkRegComplete(request, user.getUid());
1944: } catch (DBException dbe) {
1945: throw new ControllerException(dbe);
1946: }
1947:
1948: transition("showDBMenu", request, response);
1949: }
1950:
1951: /**
1952: * Displays fill-in form for registration.
1953: *
1954: * @param request The ControllerRequest object handed down by the framework
1955: * for this request
1956: * @param response The ControllerResponse object returned by this
1957: * controller
1958: * @throws ControllerException upon error of processing this state.
1959: */
1960: protected void runPromptAddRecordState(ControllerRequest request,
1961: ControllerResponse response) throws ControllerException {
1962: String dbContext = StringUtil.notNull(request
1963: .getParameter("dbContext"));
1964: String loginControllerName = getLoginController(request);
1965:
1966: if (!dbContext.equals("")) {
1967: request.setDataContext(dbContext);
1968: }
1969:
1970: User user = null;
1971:
1972: try {
1973: user = new User();
1974: user.setDataContext(request.getDataContext());
1975: user.setUid(request.getUid());
1976: user.retrieve();
1977: } catch (DBException de) {
1978: throw new ControllerException(de);
1979: }
1980:
1981: RegistrationDomain rd = getRegDomain(request, user);
1982: String dbname = getDB(request);
1983: SecuredDBObject db = loadDBObject(request, dbname);
1984: Block formBlock = buildForm(rd, db, response);
1985: Transition add = new Transition("processAddRecord", this );
1986: add.addParam("dbobj", dbname);
1987: add.addParam("dbContext", request.getDataContext());
1988: add.addParam("loginController", loginControllerName);
1989:
1990: if (StringUtil.notNull(request.getParameter("backToMenu"))
1991: .equalsIgnoreCase("Y")) {
1992: add.addParam("backToMenu", "Y");
1993: }
1994:
1995: formBlock.add(add);
1996: response.addBlock(formBlock);
1997: }
1998:
1999: /**
2000: * Displays the 'prompt admin for approval' page. Modify this page if you
2001: * want custom displays for your administrators.
2002: *
2003: * @param request The ControllerRequest object for the system.
2004: * @param response The ControllerResponse object for the system
2005: * @throws ControllerException upon state completion error.
2006: */
2007: protected void runPromptApprovalState(ControllerRequest request,
2008: ControllerResponse response) throws ControllerException,
2009: NonHandleableException {
2010: ErrorCollection errors = new ErrorCollection();
2011: String loginName = request.getUser();
2012: String dbContext = request.getParameter("db");
2013: String loginToApprove = request.getParameter("UserName");
2014: String loginControllerName = getLoginController(request);
2015:
2016: try {
2017: User myUser = new User();
2018: myUser.setDataContext(request.getDataContext());
2019: myUser.setLoginName(loginName);
2020:
2021: if (loginName.equals("")
2022: || loginName.equals(User.UNKNOWN_USER)
2023: || !myUser.find()) {
2024: errors.addError("Must login before approving users");
2025: response.saveErrors(errors);
2026: throw new SecurityException(
2027: "Must login before approving users");
2028: }
2029:
2030: User u = new User();
2031:
2032: if (errors.isEmpty()) {
2033: u.setDataContext(dbContext);
2034: u.setLoginName(loginToApprove);
2035:
2036: if (!u.find()) {
2037: errors.addError("User \"" + loginToApprove
2038: + "\" not found");
2039: }
2040: }
2041:
2042: RegistrationDomain rd = new RegistrationDomain();
2043:
2044: if (errors.isEmpty()) {
2045: rd.setDataContext(dbContext);
2046: rd.setField("Name", u.getRegistrationDomain());
2047:
2048: if (!rd.find()) {
2049: errors.addError("Registration domain \""
2050: + u.getRegistrationDomain()
2051: + "\" not found");
2052: } else {
2053: String approvers = rd.getField("Approvers");
2054: StringTokenizer stk = new StringTokenizer(
2055: approvers, ",");
2056: boolean havePermission = false;
2057:
2058: if (loginName.equals(User.ADMIN_USER)) {
2059: havePermission = true;
2060: }
2061:
2062: while (stk.hasMoreTokens() && !havePermission) {
2063: if (stk.nextToken().equals(loginName)) {
2064: havePermission = true;
2065: }
2066: }
2067:
2068: if (!havePermission) {
2069: errors
2070: .addError("You ("
2071: + loginName
2072: + ") do not have permission to approve users in this domain");
2073: }
2074: }
2075: }
2076:
2077: if (errors.isEmpty()) {
2078: Transition approve = new Transition("processApproval",
2079: this );
2080: approve.setName("approve");
2081: approve.setLabel("Approve Registration");
2082: approve.addParam("command", "approve");
2083: approve.addParam("db", dbContext);
2084: approve.addParam("UserName", loginToApprove);
2085: approve
2086: .addParam("loginController",
2087: loginControllerName);
2088: response.add(approve);
2089:
2090: Transition deny = new Transition("processApproval",
2091: this );
2092: deny.setName("deny");
2093: deny.setLabel("Deny Registration");
2094: deny.addParam("command", "deny");
2095: deny.addParam("db", dbContext);
2096: deny.addParam("UserName", loginToApprove);
2097: deny.addParam("loginController", loginControllerName);
2098: response.add(deny);
2099:
2100: Transition postpone = new Transition("processApproval",
2101: this );
2102: postpone.setName("postpone");
2103: postpone.setLabel("Postpone Decision Until Later");
2104: postpone.addParam("command", "postpone");
2105: postpone.addParam("db", dbContext);
2106: postpone.addParam("UserName", loginToApprove);
2107: postpone.addParam("loginController",
2108: loginControllerName);
2109: response.add(postpone);
2110: response.add(new Output("LoginName", loginToApprove));
2111: response.add(new Output("Email", u.getEmail()));
2112: response.add(new Output("RegDomain", u
2113: .getRegistrationDomain()));
2114:
2115: if (rd.getField("RegRequired").equalsIgnoreCase("Y")) {
2116: RegistrationObjectMap rom = new RegistrationObjectMap();
2117: rom.setDataContext(dbContext);
2118: rom.setField("RegDomId", rd.getField("RegDomId"));
2119:
2120: SecuredDBObject db = null;
2121: RegistrationObjectMap oneRom = null;
2122: SecuredDBObject oneDB = null;
2123:
2124: for (Iterator dbIter = rom.searchAndRetrieveList(
2125: "RegOrder").iterator(); dbIter.hasNext();) {
2126: oneRom = (RegistrationObjectMap) dbIter.next();
2127:
2128: try {
2129: db = (SecuredDBObject) Class.forName(
2130: oneRom.getField("RegObj"))
2131: .newInstance();
2132: } catch (Exception ex) {
2133: throw new ControllerException(
2134: "Dynamic load failed for "
2135: + oneRom.getField("RegObj"),
2136: ex);
2137: }
2138:
2139: db.setDataContext(dbContext);
2140:
2141: Block regObj = new Block("RegObj");
2142: response.add(regObj);
2143: regObj.add(new Output("Desc", getString(db
2144: .getMetaData().getDescription())
2145: + ":"));
2146: db.setField(oneRom.getField("UidField"), u
2147: .getUid());
2148:
2149: for (Iterator recIter = db
2150: .searchAndRetrieveList().iterator(); recIter
2151: .hasNext();) {
2152: oneDB = (SecuredDBObject) recIter.next();
2153:
2154: Block regRec = new Block("RegRec");
2155: regObj.add(regRec);
2156:
2157: StringBuffer s = new StringBuffer("");
2158:
2159: for (Iterator k = oneDB
2160: .getKeyFieldListIterator(); k
2161: .hasNext();) {
2162: String fn = (String) k.next();
2163: s.append(oneDB.getField(fn) + "|");
2164: }
2165:
2166: Transition dbMaint = new Transition();
2167: dbMaint.setName("dbMaint");
2168: dbMaint
2169: .setLabel("View Registration Record");
2170: dbMaint
2171: .setControllerObject(com.jcorporate.expresso.services.controller.DBMaint.class);
2172: dbMaint.addParam(STATE_PARAM_KEY, "Update");
2173: dbMaint.addParam("key", s.toString());
2174: dbMaint.addParam("dbobj", oneDB.getClass()
2175: .getName());
2176: regRec.add(dbMaint);
2177:
2178: Block fldTbl = new Block("FldTbl");
2179: regRec.add(fldTbl);
2180:
2181: for (Iterator fldIter = oneDB.getMetaData()
2182: .getFieldListArray().iterator(); fldIter
2183: .hasNext();) {
2184: String fn = (String) fldIter.next();
2185: Block fldRec = new Block("FldRec");
2186: fldTbl.add(fldRec);
2187: fldRec.add(new Output("FldName",
2188: getString(oneDB.getMetaData()
2189: .getDescription(fn))));
2190:
2191: String value = "";
2192:
2193: if (oneDB.getMetaData().isMultiValued(
2194: fn)) {
2195: value = StringUtil.notNull(oneDB
2196: .getValidValueDescrip(fn));
2197: } else {
2198: value = StringUtil.notNull(oneDB
2199: .getField(fn));
2200: }
2201:
2202: if (value.equals("")) {
2203: value = " ";
2204: }
2205:
2206: fldRec.add(new Output("FldVal", value));
2207: }
2208: }
2209: }
2210: }
2211: } else {
2212: response.saveErrors(errors);
2213: response.setFormCache();
2214: }
2215: } catch (DBException dbe) {
2216: ValidationEntry ve = (ValidationEntry) request
2217: .getSession()
2218: .getPersistentAttribute(ValidationEntry.SESSION_KEY);
2219:
2220: try {
2221: if (ve != null) {
2222: ve.setStatus(ValidationEntry.WAITING);
2223: }
2224: } catch (AuthValidationException ex) {
2225: log
2226: .error(
2227: "Error in prompting for authorization and unable to reset Validation Entry ",
2228: ex);
2229: }
2230:
2231: throw new ControllerException(dbe);
2232: }
2233: }
2234:
2235: /**
2236: * Displays confirmation of deleting a registration record.
2237: *
2238: * @param request The ControllerRequest object handed down by the framework
2239: * for this request
2240: * @param response The ControllerResponse object returned by this
2241: * controller
2242: * @throws ControllerException upon error of processing this state.
2243: */
2244: protected void runPromptDeleteRecordState(
2245: ControllerRequest request, ControllerResponse response)
2246: throws ControllerException {
2247: String loginControllerName = getLoginController(request);
2248: String dbname = getDB(request);
2249: String keys = request.getParameter("keys");
2250: Block formBlock = new Block("DeleteForm");
2251: formBlock.setForm("true");
2252:
2253: Output msg = new Output("Confirm",
2254: "Are you sure you want to delete?");
2255: formBlock.add(msg);
2256:
2257: Transition cancel = new Transition("Cancel", "Cancel", this
2258: .getClass().getName());
2259: cancel.addParam(STATE_PARAM_KEY, "showDBMenu");
2260: cancel.addParam("dbobj", dbname);
2261: cancel.addParam("loginController", loginControllerName);
2262: formBlock.add(cancel);
2263:
2264: Transition delete = new Transition("processDeleteRecord", this );
2265: delete.addParam("dbobj", dbname);
2266: delete.addParam("keys", keys);
2267: delete.addParam("loginController", loginControllerName);
2268: formBlock.add(delete);
2269: response.addBlock(formBlock);
2270: }
2271:
2272: /**
2273: * Displays the fill-in form for self-registering users
2274: *
2275: * @param request The ControllerRequest object handed down by the framework
2276: * for this request
2277: * @param response The ControllerResponse object returned by this
2278: * controller
2279: * @throws ControllerException upon error of processing this state.
2280: */
2281: protected void runPromptSelfRegisterState(
2282: ControllerRequest request, ControllerResponse response)
2283: throws ControllerException {
2284: try {
2285: String loginControllerName = getLoginController(request);
2286:
2287: //What db context to use? Try to see if it was passed as a "dbContext=xxxx" argument in the request URL.
2288: //If that fails, use "default"
2289: String dbContext = StringUtil.notNull(request
2290: .getParameter("dbContext"));
2291:
2292: if (!dbContext.equals("")) {
2293: request.setDataContext(dbContext);
2294: }
2295:
2296: if (log.isDebugEnabled()) {
2297: log.debug("New registration in db '"
2298: + request.getDataContext() + "'");
2299: }
2300:
2301: // Which registration domain to use? Try to get it from the request URL.
2302: // If it fails, see if the site default specifies a default domain
2303: // Otherwise, set it to "default"
2304: String regDomain = StringUtil.notNull(request
2305: .getParameter("regDomain"));
2306:
2307: if (regDomain.equals("")) {
2308: if (regDomain.equals("")) {
2309: try {
2310: regDomain = StringUtil.notNull(Setup.getValue(
2311: request.getDataContext(),
2312: "defaultRegDomain"));
2313: } catch (DBException dbe) {
2314: // Ignore the exception
2315: }
2316:
2317: if (regDomain.equals("")) {
2318: regDomain = "default";
2319: }
2320: }
2321: }
2322:
2323: RegistrationDomain rd = new RegistrationDomain(
2324: SecuredDBObject.SYSTEM_ACCOUNT);
2325: rd.setDataContext(request.getDataContext());
2326: rd.setField("Name", regDomain);
2327:
2328: if (!rd.find()) {
2329: throw new ControllerException("Registration domain \""
2330: + regDomain + "\" not created yet");
2331: }
2332:
2333: Block b = this .buildLoginBlock(rd, request, response);
2334: response.add(b);
2335:
2336: //
2337: //Get all the required registration objects. Then iterate through
2338: //them and add the appaopriate blocks.
2339: //
2340: DBObject[] registrationObjects = this .getRequiredDBObjects(
2341: request, rd, null);
2342:
2343: if (log.isDebugEnabled()) {
2344: log.debug("Registration domain is '" + regDomain + "'");
2345:
2346: if (registrationObjects.length == 0) {
2347: log
2348: .debug("There are no required registration objects");
2349: } else {
2350: log.debug("New needs " + registrationObjects.length
2351: + " records...");
2352: }
2353: }
2354:
2355: for (int i = 0; i < registrationObjects.length; i++) {
2356: Block rb = this .buildForm(rd, registrationObjects[i],
2357: response);
2358: response.add(rb);
2359: }
2360:
2361: Transition register = new Transition("processSelfRegister",
2362: this .getSchemaInstance()
2363: .getRegistrationController());
2364: register.addParam("regDomain", regDomain);
2365: register.addParam("dbContext", request.getDataContext());
2366: register.addParam("loginController", loginControllerName);
2367: register.setLabel("Submit");
2368: response.add(register);
2369: } catch (DBException dbe) {
2370: log.error("Error in State: promptSelfRegister", dbe);
2371: throw new ControllerException(
2372: "Error in State: promptSelfRegister", dbe);
2373: }
2374: }
2375:
2376: /**
2377: * Displays the fill-in form for updating a record
2378: *
2379: * @param request The ControllerRequest object handed down by the framework
2380: * for this request
2381: * @param response The ControllerResponse object returned by this
2382: * controller
2383: * @throws ControllerException upon error of processing this state.
2384: * @throws NonHandleableException upon fatal error
2385: */
2386: protected void runPromptUpdateRecordState(
2387: ControllerRequest request, ControllerResponse response)
2388: throws ControllerException, NonHandleableException {
2389: User user = getRegUser(request);
2390: RegistrationDomain rd = getRegDomain(request, user);
2391: String dbname = getDB(request);
2392: String keys = request.getParameter("keys");
2393: SecuredDBObject db = loadDBObject(request, dbname);
2394: String uidFieldName = null;
2395: String loginControllerName = getLoginController(request);
2396:
2397: try {
2398: RegistrationObjectMap rom = new RegistrationObjectMap();
2399: rom.setDataContext(request.getDataContext());
2400: rom.setField("RegObj", dbname);
2401:
2402: if (!rom.find()) {
2403: throw new ControllerException(
2404: "Registration object for db \"" + dbname
2405: + "\" not found");
2406: }
2407:
2408: uidFieldName = rom.getField("UidField");
2409: db.setField(uidFieldName, user.getUid());
2410:
2411: StringTokenizer stk = new StringTokenizer(keys, "|");
2412:
2413: for (Iterator k = db.getKeyFieldListIterator(); k.hasNext();) {
2414: String fn = (String) k.next();
2415: db.setField(fn, stk.nextToken());
2416: }
2417:
2418: if (!db.find()) {
2419: Transition addInstead = new Transition(
2420: "promptAddRecord", this );
2421: addInstead.addParam("dbobj", request
2422: .getParameter("dbobj"));
2423: addInstead.addParam("loginController",
2424: loginControllerName);
2425: addInstead.transition(request, response);
2426: }
2427: } catch (DBException dbe) {
2428: throw new ControllerException(
2429: "Database exception reading RegistrationObjectMap",
2430: dbe);
2431: }
2432:
2433: Block formBlock = buildForm(rd, db, response);
2434: Transition cancel = new Transition("Cancel", "Cancel", this
2435: .getClass().getName());
2436: cancel.addParam(STATE_PARAM_KEY, "showDBMenu");
2437: cancel.addParam("dbobj", dbname);
2438: cancel.addParam("loginController", loginControllerName);
2439: formBlock.add(cancel);
2440:
2441: Transition update = new Transition("processUpdateRecord", this );
2442: update.addParam("keys", keys);
2443: update.addParam("dbobj", dbname);
2444: formBlock.add(update);
2445: response.addBlock(formBlock);
2446: }
2447:
2448: /**
2449: * Displays a menu of registrations to fill out.
2450: *
2451: * @param request The ControllerRequest object handed down by the framework
2452: * for this request
2453: * @param response The ControllerResponse object returned by this
2454: * controller
2455: * @throws ControllerException upon error of processing this state.
2456: * @throws NonHandleableException upon fatal error
2457: */
2458: protected void runShowDBMenuState(ControllerRequest request,
2459: ControllerResponse response) throws ControllerException,
2460: NonHandleableException {
2461: String loginControllerName = getLoginController(request);
2462:
2463: try {
2464: User user = new User();
2465: user.setDataContext(request.getDataContext());
2466: user.setUid(request.getUid());
2467: user.retrieve();
2468:
2469: RegistrationDomain rd = new RegistrationDomain();
2470: rd.setDataContext(request.getDataContext());
2471: rd.setField("Name", user.getRegistrationDomain());
2472:
2473: if (!rd.find()) {
2474: throw new ControllerException("Domain "
2475: + user.getRegistrationDomain()
2476: + " not created yet");
2477: }
2478:
2479: RegistrationObjectMap rom = new RegistrationObjectMap();
2480: rom.setDataContext(request.getDataContext());
2481: rom.setField("RegDomId", rd.getField("RegDomId"));
2482:
2483: RegistrationObjectMap oneRom = null;
2484: SecuredDBObject db = null;
2485: Block block = null;
2486: Output desc = null;
2487: Output recCount = null;
2488: Output recMin = null;
2489: Output recMax = null;
2490: Output must = null;
2491: Transition add = null;
2492: Transition update = null;
2493: Transition list = null;
2494: Transition delete = null;
2495: int min = 0;
2496: int max = 0;
2497:
2498: for (Iterator e = rom.searchAndRetrieveList("RegOrder")
2499: .iterator(); e.hasNext();) {
2500: oneRom = (RegistrationObjectMap) e.next();
2501: oneRom.setDataContext(request.getDataContext());
2502:
2503: try {
2504: min = Integer.parseInt(oneRom.getField("RecMin"));
2505: } catch (NumberFormatException ne) {
2506: throw new ControllerException("Value '"
2507: + oneRom.getField("RecMin")
2508: + "' for Field RecMin in the registration"
2509: + " domain is not a number");
2510: }
2511:
2512: try {
2513: max = Integer.parseInt(oneRom.getField("RecMax"));
2514: } catch (NumberFormatException ne) {
2515: throw new ControllerException("Value '"
2516: + oneRom.getField("RecMax")
2517: + "' for Field RecMax in the registration"
2518: + " domain is not a number");
2519: }
2520:
2521: try {
2522: db = (SecuredDBObject) Class.forName(
2523: oneRom.getField("RegObj")).newInstance();
2524: } catch (Exception ex) {
2525: throw new ControllerException(
2526: "Dynamic load failed for "
2527: + oneRom.getField("RegObj"), ex);
2528: }
2529:
2530: db.setDataContext(request.getDataContext());
2531:
2532: String fieldName = oneRom.getField("UidField");
2533: db.setField(fieldName, user.getUid());
2534:
2535: int records = db.count();
2536: block = new Block("RegistrationDB");
2537: desc = new Output("desc", getString(db.getMetaData()
2538: .getDescription()));
2539: recMin = new Output("recMin", Integer.toString(min));
2540: recMax = new Output("recMax", Integer.toString(max));
2541: recCount = new Output("recCount", Integer
2542: .toString(records));
2543:
2544: if ((min > 0) && (records < min)) {
2545: must = new Output("inputNeeded",
2546: "Need Additional Data");
2547: block.add(must);
2548: } else {
2549: must = new Output("inputNotNeeded",
2550: "Additional Data Not Needed");
2551: block.add(must);
2552: }
2553:
2554: if ((max == 0) || (records < max)) {
2555: add = new Transition("promptAddRecord", this );
2556: add.addParam("backToMenu", "Y");
2557: add.addParam("dbobj", oneRom.getField("RegObj"));
2558: add.addParam("uid", user.getUidString());
2559: add
2560: .addParam("loginController",
2561: loginControllerName);
2562: block.add(add);
2563: }
2564:
2565: if (records > 0) {
2566: if (records == 1) {
2567: db.find();
2568:
2569: FastStringBuffer s = new FastStringBuffer(24);
2570:
2571: for (Iterator k = db.getKeyFieldListIterator(); k
2572: .hasNext();) {
2573: String fieldName2 = (String) k.next();
2574: s.append(db.getField(fieldName2));
2575: s.append("|");
2576: }
2577:
2578: if (oneRom.getField("AllowEdit").equals("Y")) {
2579: update = new Transition(
2580: "promptUpdateRecord", this );
2581: update.addParam("dbobj", oneRom
2582: .getField("RegObj"));
2583: update.addParam("uid", user.getUidString());
2584: update.addParam("keys", s.toString());
2585: update.addParam("loginController",
2586: loginControllerName);
2587: block.add(update);
2588: }
2589:
2590: if (oneRom.getField("AllowDel").equals("Y")) {
2591: delete = new Transition(
2592: "promptDeleteRecord", this );
2593: delete.addParam("dbobj", oneRom
2594: .getField("RegObj"));
2595: delete.addParam("uid", user.getUidString());
2596: delete.addParam("keys", s.toString());
2597: delete.addParam("loginController",
2598: loginControllerName);
2599: block.add(delete);
2600: }
2601: } else {
2602: if (oneRom.getField("AllowEdit").equals("Y")) {
2603: list = new Transition("processListRecords",
2604: this );
2605: list.addParam("uid", user.getUidString());
2606: list.addParam("dbobj", oneRom
2607: .getField("RegObj"));
2608: list.addParam("loginController",
2609: loginControllerName);
2610: block.add(list);
2611: }
2612: }
2613: }
2614:
2615: block.add(desc);
2616: block.add(recCount);
2617: block.add(recMin);
2618: block.add(recMax);
2619: response.addBlock(block);
2620: }
2621:
2622: /* This isn't relevant any more I don't think... */
2623: /* Transition complete = new Transition("processComplete", this);
2624:
2625:
2626:
2627: response.add(complete); */
2628: } catch (DBException e) {
2629: throw new ControllerException(
2630: "Cannot process registration - database error", e);
2631: }
2632: }
2633:
2634: /**
2635: * Resend the validation email.
2636: *
2637: * @param request The ControllerRequest object handed down by the framework
2638: * for this request
2639: * @param response The ControllerResponse object returned by this
2640: * controller
2641: * @throws ControllerException upon error of processing this state.
2642: * @throws NonHandleableException upon fatal error
2643: */
2644: protected void runProcessRevalidateState(ControllerRequest request,
2645: ControllerResponse response) throws ControllerException,
2646: NonHandleableException {
2647: ErrorCollection ec = request.getErrorCollection();
2648: if (ec == null) {
2649: ec = new ErrorCollection();
2650: }
2651:
2652: try {
2653: User user = new User();
2654: user.setDBName(request.getDataContext());
2655: user.setEmail(request.getParameter("Email"));
2656: if (!user.find()) {
2657: log.error("Received request for UserName: "
2658: + request.getParameter("UserName")
2659: + "but user does not exist");
2660:
2661: ec.addError("You entered an invalid email address");
2662: }
2663:
2664: if (ec.getErrorCount() > 0) {
2665: response.setFormCache();
2666: response.saveErrors(ec);
2667: transition("promptRevalidate", Class.forName(this
2668: .getLoginController(request)), request,
2669: response);
2670: return;
2671: }
2672:
2673: RegistrationDomain rd = getRegDomain(request, user);
2674: processPostRegistration(request, response, user, rd, this
2675: .getLoginController(request));
2676:
2677: } catch (DBException dbe) {
2678: throw new ControllerException(
2679: "Database exception reading User", dbe);
2680: } catch (ClassNotFoundException ce) {
2681: throw new ControllerException(
2682: "Login Controller class not found", ce);
2683: }
2684: }
2685: }
|