Skip to content

Commit

Permalink
fix(auth): Zope root logout Basic auth assumptions
Browse files Browse the repository at this point in the history
  • Loading branch information
rpatterson committed Jan 4, 2022
1 parent f35fa85 commit 120738d
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 2 deletions.
2 changes: 2 additions & 0 deletions news/1304.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Logging in to or out of the Zope root ZMI or the API does the same in the other.
[rpatterson]
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def read(filename):
"plone.schema >= 1.2.1", # new/fixed json field
"PyJWT",
"pytz",
"collective.monkeypatcher",
],
extras_require={"test": TEST_REQUIRES},
entry_points="""
Expand Down
1 change: 1 addition & 0 deletions src/plone/restapi/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<include package=".deserializer" />
<include package=".types" />
<include package=".search" />
<include package=".pas" />

<include package=".upgrades" />

Expand Down
17 changes: 17 additions & 0 deletions src/plone/restapi/pas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
A JWT token authentication plugin for PluggableAuthService.
"""

from App import Management
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import interfaces as plone_ifaces
from Products import PluggableAuthService # noqa, Ensure PAS patch in place
Expand Down Expand Up @@ -30,3 +31,19 @@ def iter_ancestor_pas(context):
if uf_parent is uf_parent.getPhysicalRoot():
break
uf_parent = Acquisition.aq_parent(uf_parent)


_orig_manage_zmi_logout = Management.Navigation.manage_zmi_logout


# BBB: Maybe remove depending on the outcome of the PAS issue:
# https://github.com/zopefoundation/Products.PluggableAuthService/issues/107#issue-1090137890
def manage_zmi_logout(self, REQUEST, RESPONSE):
"""
Logout the current ZMI user without re-challenging for login credentials.
"""
_orig_manage_zmi_logout(self, REQUEST, RESPONSE)

# Undo the HTTP `Authorization: Basic ...` assumptions
del RESPONSE.headers["WWW-Authenticate"]
RESPONSE.setStatus(200)
17 changes: 17 additions & 0 deletions src/plone/restapi/pas/configure.zcml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:monkey="http://namespaces.plone.org/monkey"
xmlns:zcml="http://namespaces.zope.org/zcml"
i18n_domain="plone.volto"
>

<include package="collective.monkeypatcher" />

<monkey:patch
original="manage_zmi_logout"
replacement=".manage_zmi_logout"
class="App.Management.Navigation"
description="Patch ZMI logout to remove Basic auth assumptions"
/>

</configure>
17 changes: 15 additions & 2 deletions src/plone/restapi/tests/test_functional_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,23 @@ def test_root_zmi_logout_expires_api_token(self):
login_form.controls[-1].click()

# Click the ZMI logout link
browser.raiseHttpErrors = False
logout_link = browser.getLink(url="manage_zmi_logout")
logout_link.click()
browser.raiseHttpErrors = True
self.assertEqual(
browser.headers["Status"].lower(),
"200 ok",
"Wrong Zope root `/acl_users` logout response status",
)
self.assertEqual(
browser.url,
self.app.absolute_url() + "/manage_zmi_logout",
"Wrong Zope root `/acl_users` logout response URL",
)
self.assertIn(
"You have been logged out",
browser.contents,
"Zope root `/acl_users` logout response missing confirmation message",
)
self.assertNotIn(
"__ac",
browser.cookies,
Expand Down

0 comments on commit 120738d

Please sign in to comment.