provide change_password.html

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1816 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-07-06 11:53:34 +00:00
parent c8b3e250d7
commit bdaffda265
5 changed files with 142 additions and 30 deletions

View file

@ -224,6 +224,26 @@ Now we can also retrieve it from the authentication utility:
u'Tom Sawyer'
Change Password
---------------
>>> data = {'oldPassword': u'tiger',
... 'password': u'lion',
... 'passwordConfirm': u'lion'}
>>> request = TestRequest()
We need a principal for testing the login stuff:
>>> from zope.app.authentication.principalfolder import InternalPrincipal
>>> principal = InternalPrincipal('scott', 'tiger', 'Scotty')
>>> request.setPrincipal(principal)
>>> from loops.organize.browser import PasswordChange
>>> pwcView = PasswordChange(menu, request, testing=True)
>>> pwcView.changePassword(data)
Fin de partie
=============

View file

@ -25,6 +25,7 @@ $Id$
from zope import interface, component
from zope.app import zapi
from zope.app.authentication.principalfolder import InternalPrincipal
from zope.app.form.browser.textwidgets import PasswordWidget as BasePasswordWidget
from zope.app.form.interfaces import WidgetInputError
from zope.app.pagetemplate import ViewPageTemplateFile
@ -39,8 +40,9 @@ from loops.browser.concept import ConceptView
from loops.browser.node import NodeView
from loops.browser.concept import ConceptRelationView
from loops.organize.interfaces import ANNOTATION_KEY, IMemberRegistrationManager
from loops.organize.interfaces import IMemberRegistration
from loops.organize.interfaces import IMemberRegistration, IPasswordChange
from loops.organize.party import getPersonForUser
from loops.organize.util import getInternalPrincipal
import loops.browser.util
_ = MessageFactory('zope')
@ -73,9 +75,26 @@ class PasswordWidget(BasePasswordWidget):
return value
class OldPasswordWidget(BasePasswordWidget):
def getInputValue(self):
value = super(OldPasswordWidget, self).getInputValue()
if value:
principal = self.request.principal
if not isinstance(principal, InternalPrincipal):
principal = getInternalPrincipal(principal.id)
if not principal.checkPassword(value):
v = _(u'Your old password was not entered correctly.')
self._error = WidgetInputError(
self.context.__name__, self.label, v)
raise self._error
return value
class MemberRegistration(NodeView, Form):
form_fields = FormFields(IMemberRegistration).omit('age')
form_fields['password'].custom_widget = PasswordWidget
template = loops.browser.util.dataform
label = _(u'Member Registration')
@ -92,10 +111,11 @@ class MemberRegistration(NodeView, Form):
def item(self):
return self
def xupdate(self):
def update(self):
# see cybertools.browser.view.GenericView.update()
NodeView.update(self)
Form.update(self)
return True
@action(_(u'Register'))
def handle_register_action(self, action, data):
@ -117,3 +137,53 @@ class MemberRegistration(NodeView, Form):
% (self.url, login, message))
return person
class PasswordChange(NodeView, Form):
form_fields = FormFields(IPasswordChange).select(
'oldPassword', 'password', 'passwordConfirm')
form_fields['oldPassword'].custom_widget = OldPasswordWidget
form_fields['password'].custom_widget = PasswordWidget
template = loops.browser.util.dataform
label = _(u'Change Password')
def __init__(self, context, request, testing=False):
super(PasswordChange, self).__init__(context, request)
if not testing:
self.setUpWidgets()
@Lazy
def macro(self):
return self.template.macros['content']
@Lazy
def item(self):
return self
def update(self):
# see cybertools.browser.view.GenericView.update()
NodeView.update(self)
Form.update(self)
return True
@action(_(u'Change Password'))
def handle_change_password_action(self, action, data):
self.changePassword(data)
def changePassword(self, data=None):
form = data or self.request.form
oldPw = form.get('oldPassword')
pw = form.get('password')
if form.get('passwordConfirm') != pw:
raise ValueError(u'Password and password confirmation do not match.')
regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
principal = self.request.principal
result = regMan.changePassword(principal, oldPw, pw)
if not result:
raise ValueError(u'Your old password was not entered correctly.')
message = _(u'Your password has been changed')
self.request.response.redirect('%s?message=%s'
% (self.url, message))
#self.request.response.redirect('%s/logout.html?message=%s'
# % (self.url, message))

View file

@ -84,11 +84,10 @@
permission="zope.Public"
/>
<zope:view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="loops.organize.interfaces.Password"
provides="zope.app.form.interfaces.IInputWidget"
factory="loops.organize.browser.PasswordWidget"
<browser:page
for="loops.interfaces.INode"
name="change_password.html"
class="loops.organize.browser.PasswordChange"
permission="zope.Public"
/>

View file

@ -22,15 +22,15 @@ Member registration adapter(s).
$Id$
"""
from zope.app import zapi
from zope import interface, component, schema
from zope.app.component import queryNextUtility
from zope.component import adapts
from zope.interface import implements
from zope.app.authentication.interfaces import IPluggableAuthentication
from zope.app.authentication.interfaces import IAuthenticatorPlugin
from zope.app.authentication.principalfolder import InternalPrincipal
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
from zope.app.security.interfaces import IAuthentication
from zope.app.security.interfaces import IAuthentication, PrincipalLookupError
from zope.event import notify
from zope.i18nmessageid import MessageFactory
from zope.cachedescriptors.property import Lazy
@ -39,9 +39,8 @@ from cybertools.typology.interfaces import IType
from loops.interfaces import ILoops
from loops.concept import Concept
from loops.organize.interfaces import IMemberRegistrationManager
from loops.organize.util import getPrincipalFolder, authPluginId
_ = MessageFactory('zope')
from loops.organize.util import getPrincipalFolder, authPluginId, getInternalPrincipal
from loops.util import _
class MemberRegistrationManager(object):
@ -56,7 +55,6 @@ class MemberRegistrationManager(object):
# step 1: create an internal principal in the loops principal folder:
pFolder = getPrincipalFolder(self.context)
title = firstName and ' '.join((firstName, lastName)) or lastName
# TODO: care for password encryption:
principal = InternalPrincipal(userId, password, title)
pFolder[userId] = principal
# step 2: create a corresponding person concept:
@ -80,6 +78,11 @@ class MemberRegistrationManager(object):
notify(ObjectModifiedEvent(person))
return personAdapter
def changePassword(self, oldPw, newPw):
pass
def changePassword(self, principal, oldPw, newPw):
if not isinstance(principal, InternalPrincipal):
principal = getInternalPrincipal(principal.id)
if not principal.checkPassword(oldPw):
return False
principal.setPassword(newPw)
return True

View file

@ -22,7 +22,6 @@ Utilities for the loops.organize package.
$Id$
"""
from zope.app import zapi
from zope import interface, component, schema
from zope.app.authentication.interfaces import IPluggableAuthentication
from zope.app.authentication.interfaces import IAuthenticatorPlugin
@ -32,16 +31,37 @@ authPluginId = 'loops'
def getPrincipalFolder(context=None):
pau = zapi.getUtility(IAuthentication, context=context)
pau = component.getUtility(IAuthentication, context=context)
if not IPluggableAuthentication.providedBy(pau):
raise ValueError(u'There is no pluggable authentication '
'utility available.')
if not authPluginId in pau.authenticatorPlugins:
raise ValueError(u'There is no loops authenticator '
'plugin available.')
#return component.queryUtility(IAuthenticatorPlugin, authPluginId,
# context=pau)
for name, plugin in pau.getAuthenticatorPlugins():
if name == authPluginId:
return plugin
def getInternalPrincipal(id, context=None):
pau = component.getUtility(IAuthentication, context=context)
if not IPluggableAuthentication.providedBy(pau):
raise ValueError(u'There is no pluggable authentication '
'utility available.')
if not id.startswith(pau.prefix):
next = queryNextUtility(pau, IAuthentication)
if next is None:
raise PrincipalLookupError(id)
return next.getPrincipal(id)
id = id[len(pau.prefix):]
for name, authplugin in pau.getAuthenticatorPlugins():
if not id.startswith(authplugin.prefix):
continue
principal = authplugin.get(id[len(authplugin.prefix):])
if principal is None:
continue
return principal
next = queryNextUtility(pau, IAuthentication)
if next is not None:
return next.getPrincipal(pau.prefix + id)
raise PrincipalLookupError(id)