[Checkins] SVN: grokapps/PlainLoginDemo/src/plainlogindemo/ added customized widgets to the join form; removed redundant class to provide a vocabulary for the passwordManagerName field

Luciano Ramalho luciano at ramalho.org
Tue Jan 15 20:54:27 EST 2008


Log message for revision 82910:
  added customized widgets to the join form; removed redundant class to provide a vocabulary for the passwordManagerName field
  

Changed:
  U   grokapps/PlainLoginDemo/src/plainlogindemo/app.py
  U   grokapps/PlainLoginDemo/src/plainlogindemo/ftests/member.txt

-=-
Modified: grokapps/PlainLoginDemo/src/plainlogindemo/app.py
===================================================================
--- grokapps/PlainLoginDemo/src/plainlogindemo/app.py	2008-01-16 00:46:21 UTC (rev 82909)
+++ grokapps/PlainLoginDemo/src/plainlogindemo/app.py	2008-01-16 01:54:26 UTC (rev 82910)
@@ -10,8 +10,10 @@
 from zope.app.authentication.principalfolder import InternalPrincipal
 from zope.app.authentication.principalfolder import IInternalPrincipal
 from zope.app.authentication.session import SessionCredentialsPlugin
+from zope.app.container.interfaces import DuplicateIDError
 from zope.app.security.interfaces import IAuthentication
 from zope.app.security.interfaces import IUnauthenticatedPrincipal
+from zope.app.form.browser import RadioWidget, TextWidget
 from zope.security.management import checkPermission
 from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager
 from zope.schema import getFieldNamesInOrder, ValidationError
@@ -103,11 +105,39 @@
         # redirect to the main page
         self.redirect(self.application_url())
         
+class FullNameWidget(TextWidget):
+    """
+    Simple customization: change field label from 'Title' to 'Full Name',
+    which makes more sense for a user record.
+    """
+
+    label = _(u'Full Name')
+
+class PasswordManagerChoices(RadioWidget):
+    """
+    Widget to select the passwordManager in charge of hashing or encrypting
+    the user's password before storing it.
+    """
+
+    label = _(u'Password protection')
+
+    def __init__(self, field, request):
+        # the IInternalPrincipal.passwordManagerName field comes with a
+        # vocabulary which provides the available utilities providing
+        # IPasswordManager; here we just pass that vocabulary to the widget
+        super(PasswordManagerChoices, self).__init__(
+            field, field.vocabulary, request)
+        
 class Join(grok.AddForm, Master):
     """
     User registration form.
     """
-    form_fields = grok.AutoFields(IInternalPrincipal).omit('passwordManagerName')
+
+    form_fields = grok.AutoFields(IInternalPrincipal)
+    # use our customized widgets
+    form_fields['title'].custom_widget = FullNameWidget
+    form_fields['passwordManagerName'].custom_widget = PasswordManagerChoices
+
     label = _(u'User registration')
     template = grok.PageTemplateFile('form.pt')
     
@@ -121,20 +151,20 @@
         login = data['login']
         pau = getUtility(IAuthentication)
         principals = pau['principals']
-        # XXX: the login name must be unique; need better handling of this
-        if login in principals:
+        # create an instance of InternalPrincipal
+        principal = InternalPrincipal(**data)
+        try:
+            principals[login] = principal
+        except DuplicateIDError:
+            # create a validation exception and assign it to the login field
             msg = _(u'Login name taken. Please choose a different one.') 
             self.widgets['login']._error = ValidationError(msg)
-            self.form_reset = False
+            self.form_reset = False # preserve the values in the fields
         else:
-            # create an instance of InternalPrincipal
-            principal = InternalPrincipal(passwordManagerName='SHA1', **data)
-            principals[login] = principal
             # grant the user permission to view the member listing
             permission_mngr = IPrincipalPermissionManager(grok.getSite())
             permission_mngr.grantPermissionToPrincipal(
                'plainlogindemo.ViewMemberListing', principals.prefix + login)
-
             self.redirect(self.url('login')+'?'+urlencode({'login':login}))
                     
 class Account(grok.View):
@@ -171,19 +201,4 @@
         # XXX: this is not the right way to do it... it's just a test
         return self.request.principal.id.endswith('.manager')
 
-class PasswordManagerChoices(object):
-    implements(IIterableSource)
-    
-    def __init__(self):
-        self.choices = [name for name, util in
-                            sorted(getUtilitiesFor(IPasswordManager))]
-        
-    def __iter__(self):
-        return iter(self.choices)
-    
-    def __len__(self):
-        return len(self.choices)
-    
-    def __contains__(self, value):
-        return value in self.choices
     
\ No newline at end of file

Modified: grokapps/PlainLoginDemo/src/plainlogindemo/ftests/member.txt
===================================================================
--- grokapps/PlainLoginDemo/src/plainlogindemo/ftests/member.txt	2008-01-16 00:46:21 UTC (rev 82909)
+++ grokapps/PlainLoginDemo/src/plainlogindemo/ftests/member.txt	2008-01-16 01:54:26 UTC (rev 82910)
@@ -20,16 +20,3 @@
     passwordManagerName SHA1
     password 5869cb11a7cb62e0e49aa081ea73f2e39e3df168
     login ip-login
-    
-One day we may allow a user to choose his PasswordManager. We'll do that as soon
-as we discover the simplest way to display a Choices field in a form. Meanwhile,
-we know we'll need a list of available options, so here is how we generate one::
-
-    >>> from plainlogindemo.app import PasswordManagerChoices
-    >>> choices = PasswordManagerChoices()
-    >>> len(choices)
-    3
-    >>> for choice in choices: print choice
-    MD5
-    Plain Text
-    SHA1



More information about the Checkins mailing list