diff --git a/CHANGES.rst b/CHANGES.rst
index a99cfed..2d282d5 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,12 +4,15 @@ Change Log
 2.3 (unreleased)
 ----------------
 
+- Fix broken ICredentialsUpdatedEvent event handler call to updateCredentials.
+  (`#17 <https://github.com/zopefoundation/Products.PluggableAuthService/issues/59>`_)
+
 
 2.2 (2019-11-23)
 ----------------
 
 - Add new events to be able to notify when a principal is added to
-  or removed from a group. Notify these events when principals are 
+  or removed from a group. Notify these events when principals are
   added or removed to a group in ZODBGroupManager
   (`#17 <https://github.com/zopefoundation/Products.PluggableAuthService/issues/17>`_)
 
diff --git a/Products/PluggableAuthService/events.py b/Products/PluggableAuthService/events.py
index a0d52d9..1379c16 100644
--- a/Products/PluggableAuthService/events.py
+++ b/Products/PluggableAuthService/events.py
@@ -101,7 +101,6 @@ class PropertiesUpdated(PASEvent):
 def userCredentialsUpdatedHandler(principal, event):
     pas = aq_parent(principal)
     pas.updateCredentials(
-            pas,
             pas.REQUEST,
             pas.REQUEST.RESPONSE,
             principal.getId(),

ICredentialsUpdatedEvent event handler incorrectly calls updateCredentials
*Products.PluggableAuthService.events.userCredentialsUpdatedHandler* calls updateCredentials explicitly passing the principal object.

```
@adapter(IBasicUser, ICredentialsUpdatedEvent)
def userCredentialsUpdatedHandler(principal, event):
    pas = aq_parent(principal)
    pas.updateCredentials(
            pas,
            pas.REQUEST,
            pas.REQUEST.RESPONSE,
            principal.getId(),
            event.password)
```
As *pas* in here is an instance, updateCredentials already receives self implicitly -- no need to provide it.

diff --git a/Products/PluggableAuthService/tests/test_UserFolder.py b/Products/PluggableAuthService/tests/test_UserFolder.py
index 2662a23..0336631 100644
--- a/Products/PluggableAuthService/tests/test_UserFolder.py
+++ b/Products/PluggableAuthService/tests/test_UserFolder.py
@@ -325,6 +325,7 @@ class UserEvents(pastc.PASTestCase):
         self.assertEqual(event.principal.getId(), 'event1')
 
     def testCredentialsEvent(self):
+        import functools
         provideHandler(PASEventNotify)
         provideHandler(userCredentialsUpdatedHandler)
 
@@ -334,7 +335,7 @@ class UserEvents(pastc.PASTestCase):
 
         self.uf._data = []
         self.uf._original = self.uf.updateCredentials
-        self.uf.updateCredentials = wrap
+        self.uf.updateCredentials = functools.partial(wrap, self.uf)
         self.assertEqual(len(self.uf._data), 0)
         event.notify(CredentialsUpdated(self.uf.getUserById('user1'),
                                         'testpassword'))

pip install -e .[dev]
parse_log_pytest
pytest
pytest pytest-cov flake8
3.8
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
AccessControl==7.2
Acquisition==6.1
AuthEncoding==5.0
beautifulsoup4==4.13.3
BTrees==6.1
cffi==1.17.1
Chameleon==4.4.4
coverage==7.6.1
DateTime==5.5
DocumentTemplate==4.6
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
ExtensionClass==6.0
five.localsitemanager==4.0
flake8==7.1.2
importlib_metadata==8.5.0
importlib_resources==6.4.5
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
mccabe==0.7.0
Missing==5.0
MultiMapping==5.0
multipart==1.2.1
packaging @ file:///croot/packaging_1720101850331/work
PasteDeploy==3.1.0
Persistence==5.1
persistent==6.1.1
pluggy @ file:///tmp/build/80754af9/pluggy_1648042571233/work
Products.GenericSetup==4.0
-e git+https://github.com/zopefoundation/Products.PluggableAuthService.git@5acf9460b732ebffae4ef69a68b17b2df774c228#egg=Products.PluggableAuthService
Products.PluginRegistry==2.0
Products.PythonScripts==5.1
Products.Sessions==5.0
Products.StandardCacheManagers==5.0
Products.ZCatalog==7.1
pycodestyle==2.12.1
pycparser==2.22
pyflakes==3.2.0
pytest @ file:///croot/pytest_1717793244625/work
pytest-cov==5.0.0
python-gettext==5.0
pytz==2025.2
Record==4.1
RestrictedPython==7.4
roman==4.2
six==1.17.0
soupsieve==2.6
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
transaction==5.0
typing_extensions==4.13.0
waitress==3.0.0
WebOb==1.8.9
WebTest==3.0.1
WSGIProxy2==0.5.1
z3c.pt==4.4
zc.lockfile==3.0.post1
ZConfig==4.1
zExceptions==5.0
zipp==3.20.2
ZODB==6.0
zodbpickle==4.1.1
Zope==5.12
zope.annotation==5.0
zope.browser==3.0
zope.browsermenu==5.0
zope.browserpage==5.0
zope.browserresource==5.1
zope.cachedescriptors==5.0
zope.component==6.0
zope.configuration==6.0
zope.container==6.1
zope.contentprovider==6.0
zope.contenttype==5.1
zope.datetime==5.0.0
zope.deferredimport==5.0
zope.deprecation==5.0
zope.dottedname==6.0
zope.event==5.0
zope.exceptions==5.2
zope.filerepresentation==6.0
zope.globalrequest==2.0
zope.hookable==7.0
zope.i18n==5.2
zope.i18nmessageid==7.0
zope.interface==7.2
zope.lifecycleevent==5.0
zope.location==5.0
zope.pagetemplate==5.1
zope.processlifetime==3.0
zope.proxy==6.1
zope.ptresource==5.0
zope.publisher==7.1
zope.schema==7.0.1
zope.security==7.3
zope.sequencesort==5.0
zope.site==5.0
zope.size==5.0
zope.structuredtext==5.0
zope.tal==5.0.1
zope.tales==6.0
zope.testbrowser==7.0.1
zope.testing==5.0.1
zope.traversing==5.0
zope.viewlet==5.0

name: Products.PluggableAuthService
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py38h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.1=py38h06a4308_0
  - pip=24.2=py38h06a4308_0
  - pluggy=1.0.0=py38h06a4308_1
  - pytest=7.4.4=py38h06a4308_0
  - python=3.8.20=he870216_0
  - readline=8.2=h5eee18b_0
  - setuptools=75.1.0=py38h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py38h06a4308_0
  - wheel=0.44.0=py38h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - accesscontrol==7.2
      - acquisition==6.1
      - authencoding==5.0
      - beautifulsoup4==4.13.3
      - btrees==6.1
      - cffi==1.17.1
      - chameleon==4.4.4
      - coverage==7.6.1
      - datetime==5.5
      - documenttemplate==4.6
      - extensionclass==6.0
      - five-localsitemanager==4.0
      - flake8==7.1.2
      - importlib-metadata==8.5.0
      - importlib-resources==6.4.5
      - mccabe==0.7.0
      - missing==5.0
      - multimapping==5.0
      - multipart==1.2.1
      - pastedeploy==3.1.0
      - persistence==5.1
      - persistent==6.1.1
      - products-genericsetup==4.0
      - products-pluginregistry==2.0
      - products-pythonscripts==5.1
      - products-sessions==5.0
      - products-standardcachemanagers==5.0
      - products-zcatalog==7.1
      - pycodestyle==2.12.1
      - pycparser==2.22
      - pyflakes==3.2.0
      - pytest-cov==5.0.0
      - python-gettext==5.0
      - pytz==2025.2
      - record==4.1
      - restrictedpython==7.4
      - roman==4.2
      - six==1.17.0
      - soupsieve==2.6
      - transaction==5.0
      - typing-extensions==4.13.0
      - waitress==3.0.0
      - webob==1.8.9
      - webtest==3.0.1
      - wsgiproxy2==0.5.1
      - z3c-pt==4.4
      - zc-lockfile==3.0.post1
      - zconfig==4.1
      - zexceptions==5.0
      - zipp==3.20.2
      - zodb==6.0
      - zodbpickle==4.1.1
      - zope==5.12
      - zope-annotation==5.0
      - zope-browser==3.0
      - zope-browsermenu==5.0
      - zope-browserpage==5.0
      - zope-browserresource==5.1
      - zope-cachedescriptors==5.0
      - zope-component==6.0
      - zope-configuration==6.0
      - zope-container==6.1
      - zope-contentprovider==6.0
      - zope-contenttype==5.1
      - zope-datetime==5.0.0
      - zope-deferredimport==5.0
      - zope-deprecation==5.0
      - zope-dottedname==6.0
      - zope-event==5.0
      - zope-exceptions==5.2
      - zope-filerepresentation==6.0
      - zope-globalrequest==2.0
      - zope-hookable==7.0
      - zope-i18n==5.2
      - zope-i18nmessageid==7.0
      - zope-interface==7.2
      - zope-lifecycleevent==5.0
      - zope-location==5.0
      - zope-pagetemplate==5.1
      - zope-processlifetime==3.0
      - zope-proxy==6.1
      - zope-ptresource==5.0
      - zope-publisher==7.1
      - zope-schema==7.0.1
      - zope-security==7.3
      - zope-sequencesort==5.0
      - zope-site==5.0
      - zope-size==5.0
      - zope-structuredtext==5.0
      - zope-tal==5.0.1
      - zope-tales==6.0
      - zope-testbrowser==7.0.1
      - zope-testing==5.0.1
      - zope-traversing==5.0
      - zope-viewlet==5.0
prefix: /opt/conda/envs/Products.PluggableAuthService

Products/PluggableAuthService/tests/test_UserFolder.py::UserEvents::testCredentialsEvent
Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testAllowAccessToUser Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testDenyAccessToAnonymous Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testGetBadUser Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testGetBadUserById Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testGetRoles Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testGetRolesInContext Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testGetUser Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testGetUserById Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testHasLocalRole Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testHasLocalRolePermission Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testHasPermission Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testHasRole Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testMaxListUsers Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testNotValidateWithEmptyRoles Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testNotValidateWithWrongRoles Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testNotValidateWithoutAuth Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testValidate Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::testValidateWithoutRoles Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::test__doAddUser_with_not_yet_encrypted_passwords Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::test__doAddUser_with_preencrypted_passwords Products/PluggableAuthService/tests/test_UserFolder.py::UserFolderTests::test_manage_zmi_logout Products/PluggableAuthService/tests/test_UserFolder.py::UserTests::testBaseUserGetIdEqualGetName Products/PluggableAuthService/tests/test_UserFolder.py::UserTests::testGetDomains Products/PluggableAuthService/tests/test_UserFolder.py::UserTests::testGetRoles Products/PluggableAuthService/tests/test_UserFolder.py::UserTests::testGetUserId Products/PluggableAuthService/tests/test_UserFolder.py::UserTests::testGetUserName Products/PluggableAuthService/tests/test_UserFolder.py::UserEvents::testUserCreationEvent
CHANGES.rst Products/PluggableAuthService/events.py
CHANGES.rst Products/PluggableAuthService/events.py