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:
parent
c8b3e250d7
commit
bdaffda265
5 changed files with 142 additions and 30 deletions
|
@ -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
|
||||
=============
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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"
|
||||
/>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue