Skip to content

Commit

Permalink
fix(auth): Logout all sessions when any logout
Browse files Browse the repository at this point in the history
When logging out of Plone via the API endpoint or through the classic logout link, all
PAS plugins should reset all credentials.
  • Loading branch information
rpatterson committed Dec 27, 2021
1 parent eeb0b5b commit a8855a8
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/plone/restapi/pas/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def addJWTAuthenticationPlugin(self, id_, title=None, REQUEST=None):
IChallengePlugin,
IExtractionPlugin,
plugins_ifaces.ICredentialsUpdatePlugin,
plugins_ifaces.ICredentialsResetPlugin,
)
class JWTAuthenticationPlugin(BasePlugin):
"""Plone PAS plugin for authentication with JSON web tokens (JWT)."""
Expand Down Expand Up @@ -180,6 +181,16 @@ def updateCredentials(self, request, response, login, new_password):
**cookie_kwargs,
)

@security.private
def resetCredentials(self, request, response):
"""
Expire the token and remove the cookie.
"""
if self.cookie_name in request:
if self.store_tokens:
self.delete_token(request[self.cookie_name])
response.expireCookie(self.cookie_name, path="/")

@security.protected(ManagePortal)
@postonly
def manage_updateConfig(self, REQUEST):
Expand Down
1 change: 1 addition & 0 deletions src/plone/restapi/setuphandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def install_pas_plugin(context):
"IAuthenticationPlugin",
"IExtractionPlugin",
"ICredentialsUpdatePlugin",
"ICredentialsResetPlugin",
],
)
if uf_parent is uf_parent.getPhysicalRoot():
Expand Down
32 changes: 32 additions & 0 deletions src/plone/restapi/tests/test_functional_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,38 @@ def test_cookie_login_grants_api(self):
"Wrong Plone object URL from API response JSON",
)

def test_api_logout_expires_both_cookies(self):
"""
API log out deletes both the API token and Plone classic auth cookie.
"""
session = requests.Session()
self.addCleanup(session.close)
session.post(
self.portal_url + "/@login",
headers={"Accept": "application/json"},
json={"login": SITE_OWNER_NAME, "password": TEST_USER_PASSWORD},
)
transaction.commit()
logout_resp = session.post(
self.portal_url + "/@logout",
headers={"Accept": "application/json"},
)
self.assertEqual(
logout_resp.status_code,
204,
"Wrong API logout response status code",
)
self.assertNotIn(
"__ac",
session.cookies,
"Plone session cookie remains after API logout POST response",
)
self.assertNotIn(
"auth_token",
session.cookies,
"API token cookie remains after API logout POST response",
)

def test_accessing_private_document_with_valid_token_succeeds(self):
# login and generate a valid token
response = requests.post(
Expand Down

0 comments on commit a8855a8

Please sign in to comment.