Commit 78cd2eeb authored by Fabien Morin's avatar Fabien Morin

- add checkUserCanChangePassword method. This method can be overloaded in class

that need other security and inheritate from this mixin.
- change __setPasswordByForce to _forceSetPassword. In this way, it's still not
  possible to call it nor from url nor throught edit method (as it don't begins
  with _set*) and make possible to call it from class that inheritate from
  the mixin


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@35706 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 67dd4a41
......@@ -213,11 +213,7 @@ class PasswordTool(BaseTool):
self._password_request_dict.pop(password_key)
persons = self.getPortalObject().acl_users.erp5_users.getUserByLogin(user_login)
person = persons[0]
# Calling private method starts with __ from outside is normally BAD,
# but if we leave the method as a normal method starts with _ and follow
# our naming convention, then the method can be callable through edit
# method without appropriate permission check and then security breaks.
person._Person__setPasswordByForce(password)
person._forceSetPassword(password)
person.reindexObject()
if REQUEST is not None:
msg = translateString("Password changed.")
......
......@@ -47,9 +47,24 @@ class IEncryptedPassword(Interface):
Set an already encoded password.
"""
def _forceSetPassword(value):
"""
Because both _setPassword and setPassword are considered as
public method(They are callable from user directly or through edit method)
_forceSetPassword is needed to reset password without security check by
Password Tool. This method is not callable through edit method as it not
begins with _set*
"""
def checkUserCanChangePassword(unauthorized_message):
"""
check user have permission to change his password. Raise in case he cannot.
"""
def setPassword(value) :
"""
Set the password, only if the password is not empty.
Set the password, only if the password is not empty and user has
SetOwnPassword permission
"""
def getPassword(*args, **kw):
......
......@@ -63,6 +63,10 @@ class EncryptedPasswordMixin:
return pw_validate(self.getPassword(), value)
return False
def checkUserCanChangePassword(self, unauthorized_message='setPassword'):
if not _checkPermission(Permissions.SetOwnPassword, self):
raise AccessControl_Unauthorized(unauthorized_message)
def _setEncodedPassword(self, value, format='default'):
password = getattr(aq_base(self), 'password', None)
if password is None:
......@@ -73,24 +77,17 @@ class EncryptedPasswordMixin:
def setEncodedPassword(self, value, format='default'):
"""
"""
if not _checkPermission(Permissions.SetOwnPassword, self):
raise AccessControl_Unauthorized('setEncodedPassword')
self.checkUserCanChangePassword('setEncodedPassword')
self._setEncodedPassword(value, format=format)
self.reindexObject()
# Because both _setPassword and setPassword are considered as
# public method(They are callable from user directly or through edit method)
# _setPasswordByForce is needed to reset password without security check
# by Password Tool.
def __setPasswordByForce(self, value):
def _forceSetPassword(self, value):
self.password = PersistentMapping()
self._setEncodedPassword(pw_encrypt(value))
def _setPassword(self, value):
if not _checkPermission(Permissions.SetOwnPassword, self):
raise AccessControl_Unauthorized('setPassword')
else:
self.__setPasswordByForce(value)
self.checkUserCanChangePassword('setPassword')
self._forceSetPassword(value)
security.declarePublic('setPassword')
def setPassword(self, value) :
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment