Index: WAeUP_SRP/trunk/CHANGES.txt
===================================================================
--- WAeUP_SRP/trunk/CHANGES.txt	(revision 3847)
+++ WAeUP_SRP/trunk/CHANGES.txt	(revision 3858)
@@ -134,2 +134,6 @@
 -----------------
 - implement configuration object (step 1)
+
+1.27 (2009-01-17)
+-----------------
+- implement password notification module
Index: WAeUP_SRP/trunk/WAeUPTool.py
===================================================================
--- WAeUP_SRP/trunk/WAeUPTool.py	(revision 3847)
+++ WAeUP_SRP/trunk/WAeUPTool.py	(revision 3858)
@@ -182,14 +182,12 @@
                                                         "Manager" in roles)
         info['is_clearanceofficer'] = not is_student and ("ClearanceOfficer" in roles)
-        is_allowed = info['is_allowed'] = not is_anonymous
+        #is_allowed = info['is_allowed'] = not is_anonymous
         requested_id = context.getStudentId()
         student_id  = None
-        if is_allowed:
-            if not is_student and requested_id:
-                student_id  = requested_id
-            elif not is_allowed and (not is_staff or  member_id != requested_id):
+        if not is_anonymous and requested_id:
+            if (is_student and member_id == requested_id) or is_staff:
+                student_id = requested_id
+            else:    
                 logger.info('%s tried to access %s of %s' % (member_id,context.portal_type,requested_id))
-            else:
-                student_id = member_id
         info['student_id'] = student_id
         return info
@@ -570,13 +568,14 @@
     ###)
 
-    security.declareProtected(View,'getCredential') ###(
+    security.declarePublic('getCredential') ###(
     def getCredential(self,student_id):
         student_entry = getattr(self.portal_directories.students,student_id,None)
-        if not self.isStaff():
-            mtool = self.portal_membership
-            member = mtool.getAuthenticatedMember()
-            logger = logging.getLogger('WAeUPTool.getCredential')
-            logger.info('%s tried to access password of %s' % (member,student_id))
-            return None
+        #import pdb;pdb.set_trace()
+        #if not self.isStaff():
+        #    mtool = self.portal_membership
+        #    member = mtool.getAuthenticatedMember()
+        #    logger = logging.getLogger('WAeUPTool.getCredential')
+        #    logger.info('%s tried to access password of %s' % (member,student_id))
+        #    return None
         if student_entry is None:
             return None
Index: WAeUP_SRP/trunk/Widgets.py
===================================================================
--- WAeUP_SRP/trunk/Widgets.py	(revision 3847)
+++ WAeUP_SRP/trunk/Widgets.py	(revision 3858)
@@ -2474,4 +2474,74 @@
 
 widgetRegistry.register(DiscFileWidget)
+
+
+class RegMatricNoWidget(CPSStringWidget): ###(
+    """ RegMatricNo Widget"""
+    meta_type = "RegMatricNo Widget"
+    def validate(self, datastructure, **kw):
+        """Validate datastructure and update datamodel."""
+        valid = CPSStringWidget.validate(self, datastructure, **kw)
+        widget_id = self.getWidgetId()
+        value = datastructure[widget_id].upper()
+        err = 0
+        #import pdb;pdb.set_trace()
+        if not valid:
+            err = 'Invalid number'
+        else:
+            student_record = self.students_catalog(jamb_reg_no = value)
+            if len(student_record) < 1:
+                student_record = self.students_catalog(matric_no = value)
+                if len(student_record) < 1:
+                    err = 'No student record with this registration or matric number'
+                else:
+                    datastructure['record'] = student_record[0]
+                    #import pdb;pdb.set_trace()
+            else:
+                datastructure['record'] = student_record[0]
+                #import pdb;pdb.set_trace()
+        if err:
+            datastructure.setError(widget_id, err)
+        else:
+            datamodel = datastructure.getDataModel()
+            datamodel[self.fields[0]] = value
+        
+        return not err
+
+InitializeClass(RegMatricNoWidget)
+
+widgetRegistry.register(RegMatricNoWidget)
+
+class CheckEmailWidget(CPSStringWidget): ###(
+    """ CheckEmail Widget"""
+    meta_type = "CheckEmail Widget"
+    def validate(self, datastructure, **kw):
+        """Validate datastructure and update datamodel."""
+        if datastructure.errors:
+            return
+        valid = CPSStringWidget.validate(self, datastructure, **kw)
+        widget_id = self.getWidgetId()
+        value = datastructure[widget_id].upper()
+        err = 0
+        #import pdb;pdb.set_trace()
+        if not valid:
+            err = 'Invalid string'
+        else:
+            email_cat = datastructure['record'].email.upper()
+            if email_cat != value:
+                err = 'Email address does not match'
+            else:
+                pass
+        if err:
+            datastructure.setError(widget_id, err)
+        else:
+            datamodel = datastructure.getDataModel()
+            datamodel[self.fields[0]] = value            
+        
+        return not err
+
+InitializeClass(CheckEmailWidget)
+
+widgetRegistry.register(CheckEmailWidget)
+
 ###)
 
Index: WAeUP_SRP/trunk/profiles/default/layouts.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts.xml	(revision 3847)
+++ WAeUP_SRP/trunk/profiles/default/layouts.xml	(revision 3858)
@@ -117,4 +117,5 @@
   <object name="student_gown" meta_type="CPS Layout"/>
   <object name="configuration" meta_type="CPS Layout"/>
+  <object name="retrieve_password" meta_type="CPS Layout"/>
  
 </object>
Index: WAeUP_SRP/trunk/profiles/default/layouts/retrieve_password.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts/retrieve_password.xml	(revision 3858)
+++ WAeUP_SRP/trunk/profiles/default/layouts/retrieve_password.xml	(revision 3858)
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="layout.xsl"?>
+<object name="retrieve_password" meta_type="CPS Layout">
+ <property name="layout_create_method">layout_enter_access_code</property>
+ <property name="layout_edit_method"></property>
+ <property name="layout_view_method"></property>
+ <property name="style_prefix"></property>
+ <property name="flexible_widgets"/>
+ <property name="validate_values_expr"></property>
+ <widget name="reg_no" meta_type="RegMatricNo Widget">
+  <property name="title">Registration or Matriculation Number</property>
+  <property name="fields">
+   <element value="reg_no"/>
+  </property>
+  <property name="is_required">True</property>
+  <property name="label">Registration or Matriculation Number</property>
+  <property name="label_edit">Registration or Matriculation Number</property>
+  <property name="readonly_layout_modes">
+  </property>
+  <property name="hidden_layout_modes"/>
+  <property name="hidden_readonly_layout_modes"/>
+  <property name="display_width">18</property>
+  <property name="size_max">18</property>
+ </widget>
+ <widget name="email" meta_type="CheckEmail Widget">
+  <property name="title">Registered Email Address</property>
+  <property name="fields">
+   <element value="email"/>
+  </property>
+  <property name="is_required">True</property>
+  <property name="label">Registered Email Address</property>
+  <property name="label_edit">Registered Email Address</property>
+  <property name="readonly_layout_modes">
+  </property>
+  <property name="hidden_layout_modes"/>
+  <property name="hidden_readonly_layout_modes"/>
+ </widget>
+ <table>
+  <row>
+   <cell name="reg_no" ncols="3"/>
+  </row>
+  <row>
+   <cell name="email" ncols="3"/>
+  </row>  
+ </table>
+</object>
Index: WAeUP_SRP/trunk/profiles/default/schemas.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/schemas.xml	(revision 3847)
+++ WAeUP_SRP/trunk/profiles/default/schemas.xml	(revision 3858)
@@ -89,4 +89,5 @@
  <object name="waeup_common" meta_type="CPS Schema"/>
  <object name="configuration" meta_type="CPS Schema"/>
+ <object name="retrieve_password" meta_type="CPS Schema"/>
  
  
Index: WAeUP_SRP/trunk/profiles/default/schemas/retrieve_password.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/schemas/retrieve_password.xml	(revision 3858)
+++ WAeUP_SRP/trunk/profiles/default/schemas/retrieve_password.xml	(revision 3858)
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="schema.xsl"?>
+<object name="retrieve_password" meta_type="CPS Schema">
+ <field name="reg_no" meta_type="CPS String Field"/>
+ <field name="email" meta_type="CPS String Field"/>
+</object>
Index: WAeUP_SRP/trunk/skins/waeup_student/getMemberInfo.py
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_student/getMemberInfo.py	(revision 3847)
+++ WAeUP_SRP/trunk/skins/waeup_student/getMemberInfo.py	(revision 3858)
@@ -37,5 +37,5 @@
 student_id = info['student_id']
 if student_id is None:
-    return None
+    return 'You are not allowed to access this information!'
 
 students_object = context.portal_url.getPortalObject().campus.students
Index: WAeUP_SRP/trunk/skins/waeup_student/login_student.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_student/login_student.pt	(revision 3847)
+++ WAeUP_SRP/trunk/skins/waeup_student/login_student.pt	(revision 3858)
@@ -58,6 +58,10 @@
 
   </form>
+  
+  <br />
+  
+  <a href=/retrieve_password>Forgot your Id or Password?</a>
 
-  <br />
+  <br /><br />
 
   <p i18n:translate="help_login_aware_logout">
Index: WAeUP_SRP/trunk/skins/waeup_student/retrieve_password.py
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_student/retrieve_password.py	(revision 3858)
+++ WAeUP_SRP/trunk/skins/waeup_student/retrieve_password.py	(revision 3858)
@@ -0,0 +1,103 @@
+##parameters=REQUEST
+# $Id: retrieve_password.py 3367 2008-03-21 13:29:31Z henrik $
+"""
+request Clearance
+"""
+import logging
+logger = logging.getLogger('Skins.retrieve_password')
+validate = REQUEST.has_key("cpsdocument_create_button")
+
+from urllib import urlencode
+
+mhost = context.MailHost
+prop = context.portal_properties
+REQUEST = context.REQUEST
+
+
+mtool = context.portal_membership
+is_anon = mtool.isAnonymousUser()
+member = mtool.getAuthenticatedMember()
+lt = context.portal_layouts
+#pr = context.portal_registration
+
+res,psm,ds = lt.renderLayout('retrieve_password',
+                             'retrieve_password',
+                             context,
+                             mapping=validate and REQUEST,
+                             layout_mode='create',
+                             ob={},
+                             commit=False,
+                             formaction = "retrieve_password",
+                             button = "Send Notification Email",
+                             )
+if psm == 'invalid':
+    return context.retrieve_password_form(rendered = res,
+                                 psm = "Please correct your input!",
+                                 #psm = "%s, %s" % (psm,ds),
+                                 firstlayout = True,
+                                 lastlayout = True,
+                                 ds = ds,
+                                 )
+elif psm == '':
+    return context.retrieve_password_form(rendered = res,
+                                 psm = None,
+                                 firstlayout = True,
+                                 lastlayout = True,
+                                 ds = ds,
+                                 )
+elif psm == 'valid':
+
+    reg_no = ds.get('reg_no')
+    record = ds.get('record')
+    s_id = record.id
+    pw = context.waeup_tool.getCredential(s_id)
+
+    if is_anon and not s_id:
+        return context.retrieve_password_form(rendered = res,
+                                 psm = "You are not allowed to call this form in this context. Please try to log in.",
+                                 #psm = "%s, %s" % (psm,ds),
+                                 firstlayout = True,
+                                 lastlayout = True,
+                                 ds = ds,
+                                 )
+    elif not is_anon:
+        return context.retrieve_password_form(rendered = res,
+                                 psm = "You are already logged in!",
+                                 #psm = "%s, %s" % (psm,ds),
+                                 firstlayout = True,
+                                 lastlayout = True,
+                                 ds = ds,
+                                 )
+    
+    logger.info('%s successfully retrieved id %s and password %s' % (reg_no,s_id,pw))
+    
+    email = record.email
+    co_name = prop.email_from_name
+    co_email = prop.email_from_address
+    probtype = 'Your Student Id and Password'
+
+    short_msg="""
+    From: %s <%s>
+    To: %s
+    Reply-To: %s
+    Subject: %s
+    Your SRP Member Details
+    -----------------------
+    
+    Fullname: %s
+    Student Id: %s
+    Password: %s
+    
+    """
+    message = short_msg %(co_name,co_email,email,co_email,probtype,record.name,s_id,pw)
+    #mhost.send(message % d)
+
+    return message
+    return context.retrieve_password_form(rendered = res,
+                             psm = "Notification has been sent!",
+                             firstlayout = True,
+                             lastlayout = True,
+                             ds = ds,
+                             )
+        
+
Index: WAeUP_SRP/trunk/skins/waeup_student/retrieve_password_form.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_student/retrieve_password_form.pt	(revision 3858)
+++ WAeUP_SRP/trunk/skins/waeup_student/retrieve_password_form.pt	(revision 3858)
@@ -0,0 +1,24 @@
+<tal:block define="rendered_main options/rendered;
+                   portal_status_message options/psm;
+                   data_storage options/ds;
+                   jamb options/jamb/getContent|nothing;
+                   edition python:1;"
+                   >
+<metal:block define-macro="edit_form">
+  <metal:block use-macro="here/main_template/macros/master">
+  <metal:block fill-slot="header"
+    tal:define="creation creation|nothing;
+                edition edition|nothing;
+                metadata metadata|nothing"
+                >
+    </metal:block>
+      <metal:block fill-slot="main">
+        <h3>Retrieve Your Student Id and Password! </h3>
+        <br />
+        <div tal:replace="structure rendered_main" />
+      </metal:block>
+      <metal:block fill-slot="sub">
+      </metal:block>
+    </metal:block>
+  </metal:block>
+</tal:block>
