[Yanel-commits] rev 43761 - in public/yanel/trunk: conf src/contributions/resources src/contributions/resources/forgotpw src/contributions/resources/forgotpw/htdocs src/contributions/resources/forgotpw/src src/contributions/resources/forgotpw/src/build src/contributions/resources/forgotpw/src/java src/contributions/resources/forgotpw/src/java/org src/contributions/resources/forgotpw/src/java/org/wyona src/contributions/resources/forgotpw/src/java/org/wyona/yanel src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw src/contributions/resources/forgotpw/yanel-htdocs src/contributions/resources/forgotpw/yanel-htdocs/doc src/contributions/resources/forgotpw/yanel-htdocs/icons src/contributions/resources/forgotpw/yanel-htdocs/icons/16x16 src/contributions/resources/forgotpw/yanel-htdocs/icons/22x22 src/contributio! ns/resources/forgotpw/yanel-htdocs/icons/32x32 src/contributions/resources/forgotpw/yanel-htdocs/icons/scalable

guillaume at wyona.com guillaume at wyona.com
Thu Jul 23 12:46:54 CEST 2009


Author: guillaume
Date: 2009-07-23 12:46:53 +0200 (Thu, 23 Jul 2009)
New Revision: 43761

Added:
   public/yanel/trunk/src/contributions/resources/forgotpw/
   public/yanel/trunk/src/contributions/resources/forgotpw/build.xml
   public/yanel/trunk/src/contributions/resources/forgotpw/htdocs/
   public/yanel/trunk/src/contributions/resources/forgotpw/htdocs/forgotpw.xsl
   public/yanel/trunk/src/contributions/resources/forgotpw/resource.xml
   public/yanel/trunk/src/contributions/resources/forgotpw/src/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/build/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/build/build.properties
   public/yanel/trunk/src/contributions/resources/forgotpw/src/build/dependencies.xml
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ForgotPassword.java
   public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ResetPWExpire.java
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/doc/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/doc/index.html
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/16x16/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/16x16/rt-icon.png
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/22x22/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/22x22/rt-icon.png
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/32x32/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/32x32/rt-icon.png
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/scalable/
   public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/scalable/rt-icon.svg
Modified:
   public/yanel/trunk/conf/resource-types.xml
Log:
New feature: forgotten password handling.

Initial code contributed by Prabodh Upreti, thanks! :)

Issue: 7164


Modified: public/yanel/trunk/conf/resource-types.xml
===================================================================
--- public/yanel/trunk/conf/resource-types.xml	2009-07-23 09:52:14 UTC (rev 43760)
+++ public/yanel/trunk/conf/resource-types.xml	2009-07-23 10:46:53 UTC (rev 43761)
@@ -10,9 +10,10 @@
 
 <!-- NOTE: Do not use relative paths to reference resource types, because the paths are not being resolved re the location of (local.)resource-types.xml -->
 
-<resource-types xmlns="http://www.wyona.org/yanel/1.0" version="2009051900">
+<resource-types xmlns="http://www.wyona.org/yanel/1.0" version="2009072300">
 
   <changes>
+    <change version="2009070800">forgotpw resource type added</change>
     <change version="2009051900">copy-dir-name attribute to all resources added</change>
     <change version="2009042700">welcome realm resources commented, because already contained by welcome realm itself</change>
     <change version="2009041500">lookup resource type added</change>
@@ -30,6 +31,7 @@
   </changes>
 
   <!-- HEADSUP: Make sure to add the trailing slash (/) in the @src attribute! -->
+  <resource-type src="@YANEL_SRC_DIR@/src/contributions/resources/forgotpw/" compile="true" copy-dir-name="yanel-forgotpw"/>
   <resource-type src="@YANEL_SRC_DIR@/src/contributions/resources/lookup/" compile="true" copy-dir-name="yanel-lookup"/>
   <resource-type src="@YANEL_SRC_DIR@/src/resources/tinymce/" compile="true" copy-dir-name="yanel-tinymce"/>
   <resource-type src="@YANEL_SRC_DIR@/src/contributions/resources/image/" compile="true" copy-dir-name="yanel-image"/>


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw
___________________________________________________________________
Name: svn:ignore
   + build


Added: public/yanel/trunk/src/contributions/resources/forgotpw/build.xml
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/build.xml	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/build.xml	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,3 @@
+<project name="yanel-forgotpw-RT">
+  <import file="${yanel.source.home}/src/build/resource-types/resource-type.build.xml"/>
+</project>

Added: public/yanel/trunk/src/contributions/resources/forgotpw/htdocs/forgotpw.xsl
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/htdocs/forgotpw.xsl	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/htdocs/forgotpw.xsl	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,95 @@
+<xsl:stylesheet version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xhtml="http://www.w3.org/1999/xhtml"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:yanel="http://www.wyona.org/yanel/1.0"
+    xmlns:xalan="http://xml.apache.org/xalan">
+
+  <xsl:output method="xhtml" encoding="UTF-8"/>
+
+  <xsl:param name="yanel.back2realm" select="'BACK2REALM_IS_NULL'"/>
+  <xsl:param name="yanel.reservedPrefix" select="'RESERVEDPREFIX_IS_NULL'"/>
+
+  <xsl:template match="/">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+          <head>
+            <title>I forgot my password!</title>
+            <link type="text/css" href="{$yanel.back2realm}{$yanel.reservedPrefix}/yanel-css/global.css" rel="stylesheet"></link>
+          </head>
+          <body>
+            <table id="bodytable" cellpadding="0" cellspacing="0"><tr><td id="title">
+              I forgot my password!
+            </td><td id="logo"><img src="{$yanel.back2realm}{$yanel.reservedPrefix}/yanel-img/yanel_header.png"/></td></tr><tr><td colspan="2" valign="top" width="100%"><div id="content">
+
+            <xsl:apply-templates select="/yanel:yanel-forgotpw/yanel:requestemail"/>
+            <xsl:apply-templates select="/yanel:yanel-forgotpw/yanel:requestnewpw"/>
+            <xsl:apply-templates select="/yanel:yanel-forgotpw/yanel:show-message"/>
+
+            </div></td></tr></table>
+          </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="yanel:requestemail" >
+    <h2>Get a new password by E-mail</h2>
+    <form name="forgotpw-form" method="post" action="#">
+      <p>
+        <table cellpadding="0" cellspacing="0" border="0">
+          <tr>
+            <td>Email address:</td>
+            <td>
+              <input type="text" name="email"/>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2">
+              <input type="submit" name="submitForgotPW" value="Send Email"/>
+            </td>
+          </tr>
+        </table>
+      </p>
+    </form>
+  </xsl:template>
+
+<xsl:template match="yanel:requestnewpw" >
+    <h2>Change Password</h2>
+    <form name="forgotpw-form" method="post" action="#">
+      <p>
+        <table cellpadding="0" cellspacing="0" border="0">
+          <tr>
+            <td>Enter new password:</td>
+            <td>
+              <input type="password" name="newPassword"/>
+            </td>
+          </tr>
+          <tr>
+            <td>Confirm new password:</td>
+            <td>
+              <input type="password" name="newPasswordConfirmation"/>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <input name="guid" type="hidden"> <xsl:attribute name="value">
+                <xsl:value-of select="yanel:guid" /></xsl:attribute>
+              </input>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2">
+              <input type="submit" name="submitNewPW" value="Change Password"/>
+            </td>
+          </tr>
+        </table>
+      </p>
+    </form>
+  </xsl:template>
+
+  <xsl:template match="yanel:show-message">
+        <h4>
+          <xsl:value-of select="." />
+        </h4>
+  </xsl:template>
+
+
+</xsl:stylesheet>

Added: public/yanel/trunk/src/contributions/resources/forgotpw/resource.xml
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/resource.xml	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/resource.xml	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<resource xmlns="http://www.wyona.org/yanel/1.0"
+  name="forgotpw"
+  namespace="http://www.wyona.org/yanel/resource/1.0"
+  class="org.wyona.yanel.impl.resources.forgotpw.ForgotPassword"
+  >
+<description>
+manage forgot pw resource
+</description>
+
+<rtd>
+<!--
+  <property name="foo" default-value="bar"/>
+-->
+</rtd>
+</resource>

Added: public/yanel/trunk/src/contributions/resources/forgotpw/src/build/build.properties
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/src/build/build.properties	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/src/build/build.properties	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,2 @@
+resource.name=forgotpw
+resource.version=0.0.1-dev-rXXX

Added: public/yanel/trunk/src/contributions/resources/forgotpw/src/build/dependencies.xml
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/src/build/dependencies.xml	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/src/build/dependencies.xml	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<project name="forgotpw-dependencies" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+
+  <target name="dependencies" description="Dependencies">
+    <artifact:remoteRepository id="wyona.remote.repository" url="${maven.url}"/>
+
+    <artifact:dependencies pathId="maven2.classpath" filesetId="maven2.fileset">
+      <remoteRepository refid="wyona.remote.repository"/>
+      <dependency groupId="wyona-org-yanel" artifactId="yanel-core" version="${yanel.source.version}"/>
+      <dependency groupId="wyona-org-yanel" artifactId="yanel-impl" version="${yanel.source.version}"/>
+      <dependency groupId="javax.servlet" artifactId="servlet-api" version="2.3"/>
+      <dependency groupId="xml-resolver" artifactId="xml-resolver" version="1.1"/>
+      <dependency groupId="xalan" artifactId="xalan" version="2.7.0"/>
+    </artifact:dependencies>
+
+    <artifact:dependencies pathId="maven2.resource.classpath" filesetId="maven2.resource.fileset">
+      <remoteRepository refid="wyona.remote.repository"/>
+      <dependency groupId="javax.activation" artifactId="activation" version="1.1"/>
+      <dependency groupId="javax.mail" artifactId="mail" version="1.4"/>
+      <dependency groupId="commons-validator" artifactId="commons-validator" version="1.3.1"/>
+      <dependency groupId="wyona-org-security" artifactId="wyona-org-security-util" version="0.2-dev-r42034"/>
+      <dependency groupId="wyona-org-yanel" artifactId="yanel-resource-contact-form" version="1.0-dev-r?????"/>
+      <!-- No resource specific libs yet -->
+    </artifact:dependencies>
+
+    <property name="maven2.cp" refid="maven2.classpath"/>
+    <!--<echo>Maven2 classpath: ${maven2.cp}</echo>-->
+     <property name="maven2.resource.cp" refid="maven2.resource.classpath"/>
+  </target>
+
+</project>

Added: public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ForgotPassword.java
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ForgotPassword.java	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ForgotPassword.java	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,347 @@
+                                                                                                                        /*
+ * Copyright 2009 Wyona
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.wyona.org/licenses/APACHE-LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.wyona.yanel.impl.resources.forgotpw;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.timer.Timer;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.validator.EmailValidator;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.wyona.commons.xml.XMLHelper;
+import org.wyona.security.core.api.User;
+import org.wyona.yanel.impl.resources.BasicXMLResource;
+import org.wyona.yanel.impl.resources.SendMail;
+import org.wyona.yarep.core.Node;
+import org.wyona.yarep.core.NodeType;
+
+
+/**
+ * This resource is responsible for managing the forgot password functionality.
+ * The following constant control the flow with the UI.
+ * {@value #SUBMITFORGOTPASSWORD}  is passed when the user clicks on the first screen to submit email.
+ *
+ * {@value #SUBMITNEWPW}  is passed when the user enter the new password and submits the form.
+ *
+ * If the query string has pwresetid then we know that the user clicked on the link send via email.
+ */
+public class ForgotPassword extends BasicXMLResource {
+
+    private static Logger log = Logger.getLogger(ForgotPassword.class);
+    private long totalValidHrs;
+
+    private static final String SUBMITFORGOTPASSWORD = "submitForgotPW";
+    private static final String SUBMITNEWPW = "submitNewPW";
+    private static final String NAMESPACE = "http://www.wyona.org/yanel/1.0";
+    private static final long  DEFAULT_TOTAL_VALID_HRS = 24L;
+
+    /**
+     * This is the main method that handles all view request. The first time the request
+     * is made to enter the data.
+     */
+    @Override
+    protected InputStream getContentXML(String viewId) throws Exception {
+        HttpServletRequest request = getEnvironment().getRequest();
+
+        try {
+            String hrsValid = getResourceConfigProperty("num-hrs-valid");
+            if(hrsValid != null && !hrsValid.equals("")) {
+                totalValidHrs = Long.parseLong(hrsValid);
+            } else {
+                totalValidHrs = DEFAULT_TOTAL_VALID_HRS ;
+            }
+        } catch(Exception ex) {
+            log.error("num-hrs-valid flag not properly set: " + ex, ex);
+            totalValidHrs = DEFAULT_TOTAL_VALID_HRS;
+        }
+        //Node xsltNode = getRealm().getRepository().getNode(getResourceConfigProperty("src"));
+        Document adoc = XMLHelper.createDocument(NAMESPACE, "yanel-forgotpw");
+        processUserAction(request, adoc);
+        DOMSource source = new DOMSource(adoc);
+        StringWriter xmlAsWriter = new StringWriter();
+        StreamResult result = new StreamResult(xmlAsWriter);
+        TransformerFactory.newInstance().newTransformer().transform(source, result);
+        // write changes
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(xmlAsWriter.toString().getBytes("UTF-8"));
+        return inputStream;
+    }
+
+    private void processUserAction(HttpServletRequest request, Document adoc) throws Exception {
+        String action = determineAction(request);
+        log.debug("action performed: " + action);
+
+        Element rootElement = adoc.getDocumentElement();
+        if (action.equals(SUBMITFORGOTPASSWORD)) {
+            String strVal = processForgotPW(request);
+            Element statusElement = (Element) rootElement.appendChild(adoc.createElementNS(NAMESPACE, "show-message"));
+            if(!strVal.equals("success")) {
+                statusElement.setTextContent(strVal);
+            } else {
+                statusElement.setTextContent("Password change was successful. Please check your email.");
+            }
+        } else if (request.getParameter("pwresetid") != null && !request.getParameter("pwresetid").equals("") && !action.equals(SUBMITNEWPW)){
+            User usr = findRepoUser(request.getParameter("pwresetid"), totalValidHrs);
+            if(usr == null) {
+                Element statusElement = (Element) rootElement.appendChild(adoc.createElementNS(NAMESPACE, "show-message"));
+                statusElement.setTextContent("Unable to find forgot password request. Please try again.");
+            } else {
+                Element requestpwElement = (Element) rootElement.appendChild(adoc.createElementNS(NAMESPACE, "requestnewpw"));
+                Element guidElement = (Element) requestpwElement.appendChild(adoc.createElementNS(NAMESPACE, "guid"));
+                guidElement.setTextContent(request.getParameter("pwresetid"));
+            }
+        } else if(action.equals(SUBMITNEWPW)) {
+            String retStr = updatePassword(request);
+            Element statusElement = (Element) rootElement.appendChild(adoc.createElementNS(NAMESPACE, "show-message"));
+            if(!retStr.equals("success")) {
+                statusElement.setTextContent(retStr);
+            } else {
+                statusElement.setTextContent("Password has been successfully reset. Please login with your new password.");
+            }
+        } else {
+            log.debug("default handler");
+            Element requestElement = (Element) rootElement.appendChild(adoc.createElementNS(NAMESPACE, "requestemail"));
+        }
+    }
+
+    private User findRepoUser(String usrGuid, long duration_hour) throws Exception {
+        User upUser = null;
+        Map<String, ResetPWExpire> pwHM = getOblivionMap(getEnvironment().getRequest());
+
+        ResetPWExpire resetObj = pwHM.get(usrGuid);
+        if (resetObj == null) {
+            Node [] children = null;
+            children = getRealm().getRepository().getNode("nodePath").getNodes();
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            DocumentBuilder db = null;
+            db = dbf.newDocumentBuilder();
+
+            for(int i=0; i< children.length; i++) {
+                Document doc = null;
+                doc = db.parse(children[i].getInputStream());
+                Element userElem = doc.getElementById("user");
+                String userid = userElem.getAttribute("id");
+                String guid = getTextValue(userElem, "guid");
+                long savedDateTime = getLongValue(userElem, "starttime");
+                String email = getTextValue(userElem, "email");
+
+                if(guid.equals(usrGuid) && validGuid(savedDateTime, duration_hour)) {
+                    upUser = realm.getIdentityManager().getUserManager().getUser(userid);
+                }
+            }
+        }   else {
+            boolean check = validGuid(resetObj.getDateTime(), duration_hour);
+            if(check) {
+                upUser = realm.getIdentityManager().getUserManager().getUser(resetObj.getUserId());
+            }
+        }
+        return upUser;
+    }
+
+    private boolean validGuid(long starDT, long duration_hour) throws Exception {
+        long currentDT = new Date().getTime();
+        long expireTime= starDT + duration_hour * Timer.ONE_HOUR;
+
+        return (expireTime>currentDT);
+    }
+
+    private String getTextValue(Element ele, String tagName) throws Exception {
+        String textVal = null;
+        NodeList nl = ele.getElementsByTagName(tagName);
+        if(nl != null && nl.getLength() > 0) {
+            Element el = (Element)nl.item(0);
+            textVal = el.getFirstChild().getNodeValue();
+        }
+
+        return textVal;
+    }
+
+
+    private long getLongValue(Element ele, String tagName) throws Exception {
+        return Long.parseLong(getTextValue(ele,tagName));
+    }
+
+    /* Determine the requested view: defaultView, submitProfile,
+    * submitPassword,submitGroup, submitDelete
+    *
+    * @param request
+    * @return name of the desired view
+    */
+   private String determineAction(HttpServletRequest request) throws Exception {
+       boolean submit = false;
+       String action = "defaultView";
+
+       Enumeration<?> enumeration = request.getParameterNames();
+       while (enumeration.hasMoreElements() && !submit) {
+           action = enumeration.nextElement().toString();
+           if (action.startsWith("submit")) {
+               submit = true;
+           }
+       }
+       return action;
+   }
+
+   private Map<String, ResetPWExpire> getOblivionMap(HttpServletRequest request) throws Exception {
+       javax.servlet.http.HttpSession session = request.getSession(true);
+       Map<String, ResetPWExpire> pwHM = (Map<String, ResetPWExpire>) session.getAttribute("pwreset");
+       if (pwHM == null) {
+           pwHM = new HashMap<String, ResetPWExpire>();
+           session.setAttribute("pwreset", pwHM);
+       }
+       return pwHM;
+   }
+
+    /**
+     * Updates the user profile
+     *
+     * @param request
+     *            The request containing the data to update
+     * @param transformer
+     */
+    private String processForgotPW(HttpServletRequest request) throws Exception {
+        String email = request.getParameter("email");
+        String retStr = "";
+        if (email == null || ("").equals(email)) {
+            retStr = "E-mail address is empty.";
+        } else if (! EmailValidator.getInstance().isValid(email)) {
+            retStr = email + " is not a valid E-mail address.";
+        } else {
+            User[] userList = realm.getIdentityManager().getUserManager().getUsers(true);
+            boolean userFnd = false;
+            for(int i=0; i< userList.length; i++) {
+                if (userList[i].getEmail().equals(email)) {
+                    userFnd = true;
+                    UUID ranUUid = UUID.randomUUID();
+                    String guid = ranUUid.toString();
+
+                    ResetPWExpire pwexp = new ResetPWExpire(userList[i].getID(), new Date().getTime(), guid, userList[i].getEmail());
+                    Map<String, ResetPWExpire> pwHM = getOblivionMap(getEnvironment().getRequest());
+                    pwHM.put(pwexp.getGuid(), pwexp);
+                    String emailStr = "Please go to the following URL to reset password: <" + request.getRequestURL().toString() + "?pwresetid=" + guid + ">.";
+                    log.debug(emailStr);
+                    String emailServer = getResourceConfigProperty("smtpHost");
+                    int port = Integer.parseInt(getResourceConfigProperty("smtpPort"));
+                    String from = getResourceConfigProperty("smtpFrom");
+                    String to =  userList[i].getEmail();
+                    SendMail.send(emailServer, port, from, to, "password reset reset needs your confirmation", emailStr);
+                    String xmlStrVal = generateXML(pwexp);
+
+
+                    String fileName = pwexp.getUserId() + ".xml";
+                    String filePath = "";
+                    filePath = File.separator + getResourceConfigProperty("change-password-requests-path") + File.separator + fileName;
+                    writeXMLOutput(filePath, xmlStrVal);
+                    retStr = "success";
+                    break;
+                }
+            }
+            if(!userFnd) {
+                retStr = "Unable to find user based on the "+email+" E-mail address.";
+            }
+        }
+        return retStr;
+    }
+
+    private String generateXML(ResetPWExpire resetObj) throws Exception {
+        org.w3c.dom.Document adoc = org.wyona.commons.xml.XMLHelper.createDocument(NAMESPACE, "user");
+        Element userElement = adoc.getDocumentElement();
+
+        Element emailElement = (Element) userElement.appendChild(adoc.createElement("email"));
+        emailElement.setTextContent(resetObj.getEmail());
+        Element startTimeElement = (Element) userElement.appendChild(adoc.createElement("starttime"));
+        startTimeElement.setTextContent(Long.toString(resetObj.getDateTime()));
+
+        Element guidElement = (Element) userElement.appendChild(adoc.createElement("guid"));
+        guidElement.setTextContent(resetObj.getGuid());
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        TransformerFactory factory = TransformerFactory.newInstance();
+        Transformer t = factory.newTransformer(); // identity transform
+        DOMSource source = new DOMSource(adoc);
+        StreamResult result = new StreamResult(baos);
+        t.transform(source, result);
+
+        return baos.toString();
+    }
+
+    private void writeXMLOutput(String path, String outputVal) throws Exception {
+        Node fileToStore = null;
+        if (getRealm().getRepository().existsNode(path)) {
+            fileToStore = getRealm().getRepository().getNode(path);
+        } else {
+            fileToStore = getRealm().getRepository().getRootNode().addNode(path, NodeType.RESOURCE);
+        }
+        InputStream in = new ByteArrayInputStream(outputVal.getBytes());
+        OutputStream out = fileToStore.getOutputStream();
+        byte buffer[] = new byte[8192];
+        int bytesRead;
+        while ((bytesRead = in.read(buffer)) != -1) {
+            out.write(buffer, 0, bytesRead);
+        }
+        out.close();
+        in.close();
+    }
+
+    /**
+     * Change user password.
+     */
+    private String updatePassword(HttpServletRequest request) throws Exception {
+        String retStr = "";
+        String plainPassword = request.getParameter("newPassword");
+        boolean confirmation = plainPassword.equals(request.getParameter("newPasswordConfirmation"));
+        if (confirmation && !plainPassword.equals("")) {
+            User user = findRepoUser(request.getParameter("guid"), totalValidHrs);
+            if(user !=null) {
+                user.setPassword(plainPassword);
+                user.save();
+                retStr = "success";
+            } else {
+                retStr = "Unable to find user for password reset.";
+            }
+        } else {
+            retStr = "Either no new password was supplied or the password supplied and its confirmation password do not match.";
+        }
+        return retStr;
+    }
+
+    @Override
+    public boolean exists() throws Exception {
+        log.warn("Not implemented yet!");
+        return true;
+    }
+}


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ForgotPassword.java
___________________________________________________________________
Name: svn:mime-type
   + text/x-java

Added: public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ResetPWExpire.java
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ResetPWExpire.java	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ResetPWExpire.java	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009 Wyona
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.wyona.org/licenses/APACHE-LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.wyona.yanel.impl.resources.forgotpw;
+
+    public class ResetPWExpire {
+        private String;
+        private long dateTime;
+        private String guid;
+        private String email;
+
+        public ResetPWExpire(String userid, long datetime, String guid, String email) {
+          this.userId = userid;
+          this.dateTime = datetime;
+          this.guid = guid;
+          this.email = email;
+        }
+        public String getUserId() {
+            return userId;
+        }
+        public long getDateTime() {
+            return dateTime;
+        }
+        public String getGuid() {
+            return guid;
+        }
+        public String getEmail() {
+            return email;
+        }
+    }


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw/src/java/org/wyona/yanel/impl/resources/forgotpw/ResetPWExpire.java
___________________________________________________________________
Name: svn:mime-type
   + text/x-java

Added: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/doc/index.html
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/doc/index.html	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/doc/index.html	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>forgotpw</title>
+
+<!-- TODO: Reference this style globally -->
+    <style>
+h2 {
+  font-size: 130%;
+  color:     #ffffff;
+  background-color: #525D76;
+}
+pre {
+  background-color: efefef;
+}
+td {
+  background-color: eeeeee;
+  color:            000000;
+}
+
+/* first row */
+table tr:first-child td {
+  background-color: cccccc;
+  color:            000000;
+}
+
+/* or th as first row */
+table th {
+  background-color: cccccc;
+  color:            000000;
+}
+    </style>
+  </head>
+  <body>
+    <h1>forgotpw</h1>
+
+    <h2>Overview</h2>
+    <dl>
+      <dt>Name:</dt>
+      <dd>forgotpw</dd>
+      <dt>Namespace:</dt>
+      <dd>http://yourname.org/yanel/resource/1.0</dd>
+      <dt>Universal Name:</dt>
+      <dd>&lt;{http://yourname.org/yanel/resource/1.0}forgotpw/&gt;</dd>
+      <dt>Description:</dt>
+      <dd>manage forgot pw resource</dd>
+      <dt>Java Class:</dt>
+      <dd>org.wyona.yanel.impl.resources.forgotpw.ForgotPassword</dd>
+    </dl>
+
+    <h2>Views</h2>
+    <p>TODO</p>
+
+    <h2>Examples</h2>
+    <p>TODO</p>
+  </body>
+</html>


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/doc/index.html
___________________________________________________________________
Name: svn:mime-type
   + text/html

Added: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/16x16/rt-icon.png
===================================================================
(Binary files differ)


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/16x16/rt-icon.png
___________________________________________________________________
Name: svn:mime-type
   + image/png

Added: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/22x22/rt-icon.png
===================================================================
(Binary files differ)


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/22x22/rt-icon.png
___________________________________________________________________
Name: svn:mime-type
   + image/png

Added: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/32x32/rt-icon.png
===================================================================
(Binary files differ)


Property changes on: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/32x32/rt-icon.png
___________________________________________________________________
Name: svn:mime-type
   + image/png

Added: public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/scalable/rt-icon.svg
===================================================================
--- public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/scalable/rt-icon.svg	                        (rev 0)
+++ public/yanel/trunk/src/contributions/resources/forgotpw/yanel-htdocs/icons/scalable/rt-icon.svg	2009-07-23 10:46:53 UTC (rev 43761)
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="48px"
+   height="48px"
+   id="svg4376"
+   sodipodi:version="0.32"
+   inkscape:version="0.42+devel"
+   sodipodi:docbase="/home/jimmac/gfx/ximian/tango-icon-theme/scalable/emotes"
+   sodipodi:docname="face-shocked.svg">
+  <defs
+     id="defs3">
+    <linearGradient
+       id="linearGradient3290">
+      <stop
+         id="stop3292"
+         offset="0.0000000"
+         style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+      <stop
+         style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+         offset="0.64485979"
+         id="stop3294" />
+      <stop
+         id="stop3296"
+         offset="1.0000000"
+         style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <radialGradient
+       r="8.9020796"
+       fy="15.755712"
+       fx="29.158466"
+       cy="15.720984"
+       cx="29.288071"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient2714"
+       xlink:href="#linearGradient3290"
+       inkscape:collect="always" />
+    <linearGradient
+       id="linearGradient2509">
+      <stop
+         id="stop2511"
+         offset="0.0000000"
+         style="stop-color:#fffbd5;stop-opacity:1.0000000;" />
+      <stop
+         id="stop2513"
+         offset="1.0000000"
+         style="stop-color:#edd400;stop-opacity:1.0000000;" />
+    </linearGradient>
+    <radialGradient
+       gradientUnits="userSpaceOnUse"
+       fy="39.5928"
+       fx="25.0527"
+       r="15.7572"
+       cy="39.5928"
+       cx="25.0527"
+       id="aigrd2"
+       gradientTransform="matrix(1.250000,0.000000,0.000000,1.250000,-6.214281,-8.428572)">
+      <stop
+         id="stop8602"
+         style="stop-color:#777777;stop-opacity:1.0000000;"
+         offset="0.0000000" />
+      <stop
+         id="stop8604"
+         style="stop-color:#000000"
+         offset="1" />
+    </radialGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4565">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4567" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop4569" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3824">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3826" />
+      <stop
+         style="stop-color:#c9c9c9;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop3828" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3800">
+      <stop
+         style="stop-color:#ffeed6;stop-opacity:1.0000000;"
+         offset="0.0000000"
+         id="stop3802" />
+      <stop
+         id="stop8664"
+         offset="0.50000000"
+         style="stop-color:#e49c2f;stop-opacity:1.0000000;" />
+      <stop
+         style="stop-color:#ffc66c;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop3804" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4565"
+       id="radialGradient4571"
+       cx="24.714285"
+       cy="38.571430"
+       fx="24.714285"
+       fy="38.571430"
+       r="19.714285"
+       gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     fill="#edd400"
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="0.19607843"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.313708"
+     inkscape:cx="25.411306"
+     inkscape:cy="24.058534"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:showpageshadow="false"
+     inkscape:window-width="770"
+     inkscape:window-height="739"
+     inkscape:window-x="223"
+     inkscape:window-y="184" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Face - Shocked</dc:title>
+        <dc:subject>
+          <rdf:Bag>
+            <rdf:li>emoticon</rdf:li>
+            <rdf:li>emote</rdf:li>
+            <rdf:li>smiley</rdf:li>
+            <rdf:li>stare</rdf:li>
+            <rdf:li>shocked</rdf:li>
+            <rdf:li>:O</rdf:li>
+          </rdf:Bag>
+        </dc:subject>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Jakub Steiner</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:source>http://jimmac.musichall.cz</dc:source>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Reproduction" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Distribution" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Notice" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Attribution" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer">
+    <path
+       sodipodi:type="arc"
+       style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+       id="path4563"
+       sodipodi:cx="24.714285"
+       sodipodi:cy="38.571430"
+       sodipodi:rx="19.714285"
+       sodipodi:ry="6.5714288"
+       d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1  5.0000000,38.571430 A 19.714285 6.5714288 0 1 1  44.428570 38.571430 z" />
+    <path
+       sodipodi:type="arc"
+       style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+       id="path4320"
+       sodipodi:cx="31.112698"
+       sodipodi:cy="19.008621"
+       sodipodi:rx="8.6620579"
+       sodipodi:ry="8.6620579"
+       d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1  22.450640,19.008621 A 8.6620579 8.6620579 0 1 1  39.774755 19.008621 z"
+       transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)" />
+    <path
+       d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1  22.450640,19.008621 A 8.6620579 8.6620579 0 1 1  39.774755 19.008621 z"
+       sodipodi:ry="8.6620579"
+       sodipodi:rx="8.6620579"
+       sodipodi:cy="19.008621"
+       sodipodi:cx="31.112698"
+       id="path4322"
+       style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc"
+       transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)" />
+    <path
+       id="path8599"
+       d="M 33.660715,32.696428 C 33.660715,36.196428 29.410715,38.946428 24.285715,38.946428 C 19.160715,38.946428 14.910715,36.196428 14.910715,32.696428 C 14.910715,29.196428 19.160715,26.446428 24.285715,26.446428 C 29.410715,26.446428 33.660715,29.196428 33.660715,32.696428 z "
+       style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+    <path
+       id="path8606"
+       d="M 33.660715,31.696428 C 33.660715,35.196428 29.410715,37.946428 24.285715,37.946428 C 19.160715,37.946428 14.910715,35.196428 14.910715,31.696428 C 14.910715,28.196428 19.160715,25.446428 24.285715,25.446428 C 29.410715,25.446428 33.660715,28.196428 33.660715,31.696428 z "
+       style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+    <g
+       id="g8666"
+       transform="translate(0.265165,0.000000)">
+      <path
+         id="path8610"
+         d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+         style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+      <path
+         id="path8612"
+         d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+         style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+      <path
+         id="path8614"
+         d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+         style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+      <path
+         id="path8616"
+         d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+         style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+    </g>
+  </g>
+</svg>



More information about the Yanel-commits mailing list