Package org.openeai.portlets

Source Code of org.openeai.portlets.SelfServicePasswordChange

/*******************************************************************************
$Source: /cvs/repositories/openii3/project/java/examples/org/openeai/portlets/SelfServicePasswordChange.java,v $
$Revision: 1.3 $
*******************************************************************************/

/**********************************************************************
This file is part of the OpenEAI sample, reference implementation,
and deployment management suite created by Tod Jackson
(tod@openeai.org) and Steve Wheat (steve@openeai.org) at
the University of Illinois Urbana-Champaign.

Copyright (C) 2002-2006 The OpenEAI Software Foundation

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

For specific licensing details and examples of how this software
can be used to implement integrations for your enterprise, visit
http://www.OpenEai.org/licensing.
*/

package org.openeai.portlets;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.util.Map;
import java.util.Properties;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.any_openeai_enterprise.moa.jmsobjects.coreapplication.v1_0.EnterpriseUser;
import org.any_openeai_enterprise.moa.jmsobjects.coreapplication.v1_0.EnterpriseUserPassword;
import org.any_openeai_enterprise.moa.jmsobjects.coreapplication.v1_0.NetId;
import org.any_openeai_enterprise.moa.objects.resources.v1_0.LightweightPerson;
import org.any_openeai_enterprise.moa.objects.resources.v1_0.Password;
import org.apache.log4j.Category;
import org.apache.log4j.PropertyConfigurator;
import org.jdom.Document;
import org.jdom.Element;
import org.openeai.config.AppConfig;
import org.openeai.config.EnterpriseConfigurationObjectException;
import org.openeai.config.EnterpriseFieldException;
import org.openeai.config.LoggerConfig;
import org.openeai.jms.producer.PointToPointProducer;
import org.openeai.moa.EnterpriseObjectCreateException;
import org.openeai.moa.EnterpriseObjectQueryException;
import org.openeai.moa.EnterpriseObjectUpdateException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* <p>
* SelfServicePasswordChange is a portlet that is used to change the portal user's EnterpriseUserPasssword
* in the sample enterprise.
* </p>
* <p>
* It is designed to JSR-168 portlet spec to be independent of portlet containers <em> with one exception</em>,
* passwordMatchesUPortalPassword(). This method works only with uPortal.
* </p>
* <p>
* SelfServicePasswordChange uses the OpenEAI framework and needs to be supplied with a deployment document. A
* properties file must also be supplied that contains the location of the deployment document. The name location
* of the properties file is specified in the portlet deployment doc, portlet.xml.
* </p>
* @author tcerven *
*/
public class SelfServicePasswordChange extends GenericPortlet {

  private Category logger;
  private AppConfig appConfig;
  private PointToPointProducer p2p;
  private String viewXSL;
  private String portletName;

  static final String ENTERPRISE_USER = "EnterpriseUser.v1_0";
  static final String LIGHTWEIGHT_PERSON = "LightweightPerson.v1_0";
  static final String NET_ID = "NetId";
  static final String SELF_SERVICE_PRODUCER = "SelfServicePortletProducer";
  private boolean createBasicPersonIfNotFound=false;
  static final String ENTERPRISE_USER_PASSWORD="EnterpriseUserPassword.v1_0";

  /**
   * Initializes various objects needed by the portlet.
   * <p>
   * <ol>
   * <li>
   * Reads the location of the stylesheet used to translate the XML output from the portlet
   * into an HTML fragment for the portal. This parameter is stored in the portlet's descriptor, portlet.xml,
   * as an init-param.
   * </li>
   * <li>
   * Reads the location of the properties file used by the OpenEAI framework to initalize an AppConfig. This
   * parameter is al stored in the portlet's descriptor, portlet.xml,
   * as an init-param.
   * </li>
   * </p>
   * @param config PortletConfig object
   * @see javax.portlet.Portlet#init(javax.portlet.PortletConfig)
   */
  public void init(PortletConfig config) throws PortletException {
    super.init(config);

    portletName = config.getPortletName();

    /* get location of stylesheet */
    viewXSL = config.getInitParameter("viewXSL");
    if (!(viewXSL.indexOf(File.pathSeparator)==1 || viewXSL.indexOf(":")==2)) {
      viewXSL = config.getPortletContext().getRealPath("/")+config.getInitParameter("viewXSL")
    }
     
      // Get the path to the properties file.
    String propertyFilePath=config.getInitParameter("propertyFilePath");
    if (!(propertyFilePath.indexOf(File.pathSeparator)==1 || propertyFilePath.indexOf(":")==2)) {
      propertyFilePath=config.getPortletContext().getRealPath("/")+config.getInitParameter("propertyFilePath")
    }
   
      // Load the initial properties from the properties file.
      Properties initProps = new Properties();
      try {
        InputStream in = new FileInputStream(propertyFilePath);
        initProps.load(in);
        in.close();
      }
      catch (FileNotFoundException fnfe) {
        String errMsg = "["+portletName+"] Initial properties file not " +
          "found. The exception is: " + fnfe.getMessage();
        throw new PortletException(errMsg);
      }
      catch (IOException ioe) {
        String errMsg = "["+portletName+"] Error loading initial " +
          "properties from the properties file. The exception is: " +
          ioe.getMessage();
        throw new PortletException(errMsg);
      }

      // Initialize an AppConfig using the initial properties.
      appConfig = null;
      try {
        appConfig = new AppConfig(initProps);
      }
      catch (EnterpriseConfigurationObjectException ecoe) {
        String errMsg = "["+portletName+"] Error initializing AppConfig. " +
          "The exception is: " + ecoe.getMessage();
        throw new PortletException(errMsg);
      }
     
      // Get the logger from AppConfig.
      try {
        LoggerConfig lConfig = new LoggerConfig();
        lConfig = (LoggerConfig)appConfig.getObjectByType(lConfig.getClass()
          .getName());
        logger = Category.getInstance("org.openeai.SelfService.SelfServiceProducer");
        PropertyConfigurator.configure(lConfig.getProperties());
      }
      catch (Exception e) {
        logger = org.openeai.OpenEaiObject.logger;
      }   
      // Get the producer from AppConfig.
    try {
      p2p = (PointToPointProducer) appConfig.getObject(SELF_SERVICE_PRODUCER);
      logger.info("p2p is "+p2p.getClass());
    } catch (EnterpriseConfigurationObjectException e) {
          String errMsg = "["+portletName+"] Error configuring "+SELF_SERVICE_PRODUCER+": " +
            "The exception is: " + e.getMessage();
          logger.error(errMsg);
          throw new PortletException(errMsg);
    }
    // Get the value of createBasicPersonIfNotFound
    createBasicPersonIfNotFound = Boolean.valueOf(
        config.getInitParameter("createBasicPersonIfNotFound"))
          .booleanValue();
   
    logger.info("["+portletName+"] createBasicPersonIfNotFound="+createBasicPersonIfNotFound);   
    logger.info("["+portletName+"] ViewXSL="+viewXSL);
  }
 
  /**
   * Processes requests to update or create the EnterpriseUserPassword for the portal user.
   * <p>
   * If the following conditions are met, the portlet will either create or update the EnterpriseUserPassword
   * for the portal user.
   * <ol>
   * <li>
   * The new password can't be empty or null
   * </li>
   * <li>
   * The new password must match the confirmation password
   * </li>
   * <li>
   * The old password must match the uPortal password.
   * </li>
   * </ol>
   * </p>
   * SelfServicePasswordChange uses the following request parameters:
   * </p>
   * <h2>Request Parameters</h2>
   * <table>
   * <thead>
   * <tr>
   * <th align="left">Name</th>
   * <th align="left">Type</th>
   * <th align="left">Value</th>
   * </tr>
   * </thead>
   * <tbody>
   * <tr>
   * <td>oldPassword</td>
   * <td>String</td>
   * <td>The current uPortal password</td>
   * </tr>
   * <tr>
   * <td>newPassword</td>
   * <td>String</td>
   * <td>The new value for the password</td>
   * </tr>
   * <tr>
   * <td>oldPassword</td>
   * <td>String</td>
   * <td>The current uPortal password</td>
   * </tr>
   * <tr>
   * <td>confirmNewPassword</td>
   * <td>String</td>
   * <td>Must match newPassword</td>
   * </tr>
   * <tr>
   * <td>UpdateEUP</td>
   * <td>String</td>
   * <td>This has to exist (its value doesn't matter) or processAction() will ignore the request.</td>
   * </tr>
   * </tbody>
   * </table>
   * <p>
   * The uPortal password is not stored, rather, a hash of the password is stored by uPortal. This portlet
   * must hash the oldPassword using the same algorithm as uPortal in order to check to see if they are
   * equal. SelfServicePassword assumes that the portal container will pass this value in the
   * PortletRequest.USER_INFO map in a key named "encryptedPassword".
   * </p><p>
   * The InstitutionalId is also needed to create or update the EnterpriseUserPassword object for the portal
   * user. SelfServicePasswordChange assumes that the portal container will pass this value in the
   * PortletRequest.USER_INFO map in a key named "user.id".
   * </p><p>
   * The EnterpriseUserPassword also required an EnterpriseUser. Rather than query for this object,
   * SelfServicePasswordChange builds it from information gleaned from the portal container via the PortletRequest.
   * EnterpriseUser requires a NetId and InstitutionalId. SelfServicePasswordChange assumes that the portal
   * container will pass the InstitutionalId value in the PortletRequest.USER_INFO map in a key named "user.id".
   * </p><p>
   * The NetId requires a Principal and Domain. Principal is obtained from the portlet contaner via the
   * PortletRequest.getUserPrincipal() method. Domain is hard coded "any-openeai-enterprise.org".
   * TODO: Parameterize domain.
   * </p>
   *
   * @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
   */
  public void processAction(ActionRequest request, ActionResponse response) throws PortletException {
    logger.info("["+portletName+"] \n\nProcess Action Started.\n\n");
    logger.info(request.getParameterMap());
    String oldPassword=request.getParameter("oldPassword");
    String newPassword=request.getParameter("newPassword");
    String confirmNewPassword=request.getParameter("confirmNewPassword");
    String updateSubmitEUP = request.getParameter("UpdateEUP");

    if (updateSubmitEUP!=null) {
      Map userInfo = (Map) request.getAttribute(PortletRequest.USER_INFO);
      Principal p = request.getUserPrincipal();       
      String encryptedPassword=(String)userInfo.get("encryptedPassword");
      String instID=(String)userInfo.get("user.id");
       
      try {
        if (passwordMatchesUPortalPassword(oldPassword,encryptedPassword)) {
          // Old password EQUALS uPortal password
          if (newPassword==null || newPassword.equals("")) {
            response.setRenderParameter("actionMessage","New password not specified");                       
          } else {
            if (confirmNewPassword==null || !confirmNewPassword.equals(newPassword)) {
              response.setRenderParameter("actionMessage","New password and confirm password don't match");                                       
            } else {
              // update the password
              // query for an EnterpriseUserPassword
              String principal=null;
              principal=p.getName();
              String domain=null;
              domain="any-openeai-enterprise.org";
              logger.info("["+portletName+"] "+"principal="+principal);                 
              logger.info("["+portletName+"] "+"domain="+domain);                 
              EnterpriseUserPassword eup=updateEnterpriseUserPassword(instID, principal, domain, newPassword);
              logger.info("["+portletName+"] "+"EnterpriseUserPassword="+eup);                 
              response.setRenderParameter("actionMessage","Password changed. Logout of uPortal.");                                       
            }
          }
        } else {
          response.setRenderParameter("actionMessage","Old password DOES NOT EQUAL uPortal password");         
        }
      } catch (EnterpriseConfigurationObjectException e1) {
        e1.printStackTrace();
      } catch (EnterpriseFieldException e) {
        e.printStackTrace();
      } catch (EnterpriseObjectQueryException e) {
        e.printStackTrace();
      } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        throw new PortletException("NoSuchAlgorithmException");
      } catch (EnterpriseObjectCreateException e) {
        e.printStackTrace();
      } catch (EnterpriseObjectUpdateException e) {
        e.printStackTrace();
      }
     
    }
  }

 

  /**
   * This just creates a presentation for transformation into a form that targets processAction() with
   * the correct parameters. It also displays messages generated by processAction().
   * @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
   */
  protected void doView (RenderRequest request, RenderResponse response)throws PortletException, IOException{
   
    logger.info("["+portletName+"] doView");
    Map userInfo = (Map) request.getAttribute(PortletRequest.USER_INFO);
    Principal p = request.getUserPrincipal();
    PortletURL portletUrl = response.createActionURL();

    logger.info("["+portletName+"] "+userInfo);

    response.setContentType("text/html");
    Writer out = response.getWriter();
   
    // create a document to hold the response
    Document data;
    Element dataRoot;
    String nameSpace = "http://openeai.org/examples/SelfServicePortlet";
    dataRoot = new Element("SelfServicePasswordChangeResponse", "", nameSpace);
    dataRoot.setAttribute("portletUrl",portletUrl.toString());
    String actionString = request.getParameter("actionMessage");
    if (actionString!=null) {
      Element actionMessage = new Element("ActionMessage","",nameSpace);
      actionMessage.addContent(actionString);
      dataRoot.addContent(actionMessage);
    }
    data = new Document(dataRoot);
       
    String outMsg=outXML(data);
    logger.info("["+portletName+"] "+"data:\n"+outMsg);
   
    //org.jdom.Document xmlResp = makeDoc(outMsg);
    org.jdom.Document xmlResp = data;
   
    if (xmlResp!=null){
      //transform the sucker
      try {
      logger.info("["+portletName+"] "+"Attempting to transform...");
      String s = outTransform(xmlResp, viewXSL);
      out.write(s); // send output along to client
      logger.info("["+portletName+"] "+"Transformation complete.");
      } catch (TransformerConfigurationException e) {
        logger.error("Transformer Configuration Error: "+e.toString());
        response.setContentType("text/plain");
        out.write("The transformation file, '"+viewXSL+"', can not be found.");
      } catch (Exception e) {
        logger.error("Error: "+e.toString());
      } finally {
        out.close();       
      }
    } else {
      //return output from servlet
      logger.fatal("["+portletName+"] Can't create XML from model.");
      out.write("<p>Can't create XML from model.</p>"); // send output along to client
      out.write("<p>"+outMsg+"</p>"); // send output along to client
      out.close();   
    }

   
//    response.setContentType(request.getResponseContentType());
   
   
  }
 
  /**
   * Updates or creates an EnterpriseUserPassword object for the portal user.
   *
   * @param instID required by EnterpriseUser
   * @param principal required by NetId
   * @param domain required by NetId
   * @param newPassword the new value of the password, in the case of an update, or the inital value in
   * the case of a create
   * @return
   * @throws EnterpriseConfigurationObjectException
   * @throws EnterpriseFieldException
   * @throws EnterpriseObjectCreateException
   * @throws EnterpriseObjectQueryException
   * @throws EnterpriseObjectQueryException
   * @throws EnterpriseObjectUpdateException
   */
  private EnterpriseUserPassword updateEnterpriseUserPassword(String instID, String principal, String domain, String newPassword)
    throws EnterpriseConfigurationObjectException, EnterpriseFieldException,
         EnterpriseObjectCreateException, EnterpriseObjectQueryException, EnterpriseObjectUpdateException {
      EnterpriseUser eu = (EnterpriseUser)appConfig.getObject(ENTERPRISE_USER);
      logger.info("["+portletName+"] Got " + ENTERPRISE_USER + " from AppConfig, performing Query...");

      LightweightPerson lPerson = eu.newLightweightPerson();
    logger.info("["+portletName+"] Got LightweightPerson...");
    lPerson.setInstitutionalId(instID);
    logger.info("["+portletName+"] Set instid on lightweight person...");

    NetId netId = eu.newNetId();
    logger.info("["+portletName+"] Got NetId...");
    netId.setPrincipal(principal);
    netId.setDomain(domain);
     
      eu.setLightweightPerson(lPerson);
      eu.addNetId(netId);
     
      EnterpriseUserPassword eup=(EnterpriseUserPassword)appConfig.getObject(ENTERPRISE_USER_PASSWORD);
      eup.setEnterpriseUser(eu);
      Password p = eup.newPassword();
      p.setValue(newPassword);
      p.setType("secure credential");
      p.setEncryption("cleartext");
     
      java.util.List returnedEup = eup.query(eu, p2p);
      if (returnedEup.size() == 0) {
        //create the password
        eup.setPassword(p);
        eup.create(p2p);
        return eup;
      } else {
        //update the password
        EnterpriseUserPassword baselineEup = (EnterpriseUserPassword) returnedEup.get(0);
      logger.info("["+portletName+"] baseline="+baselineEup);       
        eup.setBaseline(baselineEup);
        eup.setPassword(p);
        eup.update(p2p);
        return eup;
      }
     
  }

 
  /**
   * Creates a Document from a string source.
   * @param sXml
   * @return document equvalent to string source.
   * @throws IOException
   */
  private org.jdom.Document makeDoc(String sXml) throws IOException {

    org.jdom.Document jdomDoc=null;

    try {
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      InputSource is = new InputSource(new StringReader(sXml));
      org.w3c.dom.Document doc = db.parse(is);
      //convert to jdom
      org.jdom.input.DOMBuilder jdomBuilder = new org.jdom.input.DOMBuilder();
      jdomDoc = jdomBuilder.build(doc);
      //convert to string
      org.jdom.DocType dt = null;
      jdomDoc.setDocType(dt);
      } catch (ParserConfigurationException pce) {
        logger.warn("[makeDoc] ParserConfigurationException: " + pce.getMessage());
      } catch (SAXException saxe) {
        logger.warn("[makeDoc] SAXException: " + saxe.getMessage());
      } catch (IOException ioe) {
        logger.warn("[makeDoc] IOException: " + ioe.getMessage());
      }
     
    return jdomDoc;
  }
 
  /**
  * <p>Performs a transformation on a document.
  * Uses xalan. Sends output to specified destination.<p>
  *
  * @param     doc  the jdom document to transform
  * @param     xslName  the FQN of the the file that contains the
  *                     transformation stylesheet.
  * @param     out  the destination for the results of the transformation.
  * @exception  Throws up all exceptions.
  */
private String outTransform(org.jdom.Document doc, String xslName) throws Exception {

   try {
   TransformerFactory tFactory = TransformerFactory.newInstance();
   logger.debug("[outTransform] xslName="+xslName);
   Templates templates = tFactory.newTemplates(new StreamSource(xslName));
   Transformer transformer = templates.newTransformer();
   String contentType = null;

   String docstring = outXML(doc);
   StringWriter out = new StringWriter();
  
   transformer.transform(new StreamSource(new StringReader(docstring)),
             new StreamResult(out));
   return out.toString();
  
   }
   catch (Exception e) {
   throw e;
   }
}

  /**
   * Creates a string from a Document
   * @param doc the source document
   * @return string equvalent to doucment source
   */
  private String outXML(org.jdom.Document doc) {
      StringWriter sw=new StringWriter();
      try {
      org.jdom.output.XMLOutputter outputter = new org.jdom.output.XMLOutputter();
      outputter.output(doc, sw);
      }
      catch (Exception e) {
      if (e!=null) e.printStackTrace();
      }
      return new String(sw.getBuffer());
    }

 
  /**
   * Hashes the supplied password using the same algoritm as uPortal (2.5.1) and compares with the hash
   * supplied in the other parameter.
   * @param oldPassword
   * @param md5_passwd
   * @return true if the password are equal, false otherwise.
   * @throws NoSuchAlgorithmException
   */
  private boolean passwordMatchesUPortalPassword(String oldPassword, String md5_passwd) throws NoSuchAlgorithmException{
      boolean same = true;
      String txthash = md5_passwd.substring(5);
        byte[] whole, salt = new byte[8], compare = new byte[16], dgx;
        whole = decode(txthash);
        System.arraycopy(whole, 0, salt, 0, 8);
        System.arraycopy(whole, 8, compare, 0, 16);
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(salt);
        dgx = md.digest(oldPassword.getBytes());
        int i;
        for (i = 0; i < dgx.length; i++) {
          if (dgx[i] != compare[i])
            same = false;
        }
        if (same) {
          logger.info("[PasswordCheck] credentials match");
        }
        else {
          logger.info("[PasswordCheck] Credentials DO NOT match");
        }
      return same;
    }
   
   /**
    * This was originally Jonathan B. Knudsen's Example from his book
    * Java Cryptography published by O'Reilly Associates (1st Edition 1998)
    *  
    * @param base64
    * @return
    */
  private static byte[] decode(String base64) {
      int pad = 0;
      for (int i = base64.length() - 1; base64.charAt(i) == '='; i--)
        pad++;
      int length = base64.length()*6/8 - pad;
      byte[] raw = new byte[length];
      int rawIndex = 0;
      for (int i = 0; i < base64.length(); i += 4) {
        int block = (getValue(base64.charAt(i)) << 18) + (getValue(base64.charAt(i + 1)) << 12) + (getValue(base64.charAt(
            i + 2)) << 6) + (getValue(base64.charAt(i + 3)));
        for (int j = 0; j < 3 && rawIndex + j < raw.length; j++)
          raw[rawIndex + j] = (byte)((block >> (8*(2 - j))) & 0xff);
        rawIndex += 3;
      }
      return  raw;
    }


  /**
   * This was originally Jonathan B. Knudsen's Example from his book
   * Java Cryptography published by O'Reilly Associates (1st Edition 1998)
   * @param c
   * @return
   */
  private static int getValue(char c) {
      if (c >= 'A' && c <= 'Z')
        return  c - 'A';
      if (c >= 'a' && c <= 'z')
        return  c - 'a' + 26;
      if (c >= '0' && c <= '9')
        return  c - '0' + 52;
      if (c == '+')
        return  62;
      if (c == '/')
        return  63;
      if (c == '=')
        return  0;
      return  -1;
    }

}
TOP

Related Classes of org.openeai.portlets.SelfServicePasswordChange

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.