Skip to content

Commit

Permalink
use getProperty accessor (collective#7)
Browse files Browse the repository at this point in the history
* use getProperty accessor
  • Loading branch information
mamico committed Nov 6, 2022
1 parent 71bf476 commit c07daac
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 27 deletions.
9 changes: 8 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ Changelog
=========


1.0a3 (unreleased)
1.0a4 (unreleased)
------------------

- use getProperty accessor
[mamico]


1.0a3 (2022-10-30)
------------------

- Removed the hardcoded auth cookie name
Expand Down
14 changes: 14 additions & 0 deletions requirements-6.0.x.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Keep these the same as in base.cfg please.
pip==22.2.2
setuptools==65.3.0
zc.buildout>=3.0.0rc3
wheel==0.37.1

# Windows specific down here (has to be installed here, fails in buildout)
# Dependency of zope.sendmail:
pywin32 ; platform_system == 'Windows'
# SSL Certs on Windows, because Python is missing them otherwise:
certifi ; platform_system == 'Windows'
# Dependency of collective.recipe.omelette:
ntfsutils ; platform_system == 'Windows' and python_version < '3.0'

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

setup(
name="pas.plugins.oidc",
version="1.0a3",
version='1.0a4.dev0',
description="An add-on for Plone",
long_description=long_description,
# Get more from https://pypi.org/classifiers/
Expand Down
21 changes: 13 additions & 8 deletions src/pas/plugins/oidc/browser/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ def __repr__(self):
class LoginView(BrowserView):
def __call__(self):
session = Session(
self.request, use_session_data_manager=self.context.use_session_data_manager
self.request,
use_session_data_manager=self.context.getProperty("use_session_data_manager"),
)
# state is used to keep track of responses to outstanding requests (state).
# nonce is a string value used to associate a Client session with an ID Token, and to mitigate replay attacks.
Expand All @@ -74,15 +75,15 @@ def __call__(self):

# https://pyoidc.readthedocs.io/en/latest/examples/rp.html#authorization-code-flow
args = {
"client_id": self.context.client_id,
"client_id": self.context.getProperty("client_id"),
"response_type": "code",
"scope": self.context.get_scopes(),
"state": session.get("state"),
"nonce": session.get("nonce"),
"redirect_uri": self.context.get_redirect_uris(),
}

if self.context.use_pkce:
if self.context.getProperty("use_pkce"):
# Build a random string of 43 to 128 characters
# and send it in the request as a base64-encoded urlsafe string of the sha256 hash of that string
session.set("verifier", rndstr(128))
Expand All @@ -107,7 +108,10 @@ def get_code_challenge(self, value):
class LogoutView(BrowserView):
def __call__(self):
client = self.context.get_oauth2_client()
# session = Session(self.request, use_session_data_manager=self.context.use_session_data_manager)
# session = Session(
# self.request,
# use_session_data_manager=self.context.getProperty("use_session_data_manager")
# )
# state is used to keep track of responses to outstanding requests (state).
# https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/java/logout.adoc
# session.set('end_session_state', rndstr())
Expand Down Expand Up @@ -143,7 +147,8 @@ class CallbackView(BrowserView):
def __call__(self):
response = self.request.environ["QUERY_STRING"]
session = Session(
self.request, use_session_data_manager=self.context.use_session_data_manager
self.request,
use_session_data_manager=self.context.getProperty("use_session_data_manager"),
)
client = self.context.get_oauth2_client()
aresp = client.parse_response(
Expand All @@ -158,10 +163,10 @@ def __call__(self):
"redirect_uri": self.context.get_redirect_uris(),
}

if self.context.use_pkce:
if self.context.getProperty("use_pkce"):
args["code_verifier"] = session.get("verifier")

if self.context.use_modified_openid_schema:
if self.context.getProperty("use_modified_openid_schema"):
IdToken.c_param.update(
{
"email_verified": SINGLE_OPTIONAL_BOOLEAN_AS_STRING,
Expand All @@ -186,7 +191,7 @@ def __call__(self):
# XXX: Not completely sure if this is even needed
# We do not have a OpenID connect provider with userinfo endpoint
# enabled and with the weird treatment of boolean values, so we cannot test this
# if self.context.use_modified_openid_schema:
# if self.context.getProperty("use_modified_openid_schema"):
# userinfo = client.do_user_info_request(state=aresp["state"], user_info_schema=CustomOpenIDNonBooleanSchema)
# else:
# userinfo = client.do_user_info_request(state=aresp["state"])
Expand Down
20 changes: 10 additions & 10 deletions src/pas/plugins/oidc/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def rememberIdentity(self, userinfo):
if pas is None:
return
user = pas.getUserById(user_id)
if self.create_user:
if self.getProperty("create_user"):
# https://github.com/collective/Products.AutoUserMakerPASPlugin/blob/master/Products/AutoUserMakerPASPlugin/auth.py#L110
if user is None:
with safe_write(self.REQUEST):
Expand Down Expand Up @@ -152,9 +152,9 @@ def rememberIdentity(self, userinfo):
# if time.time() > user.getProperty(LAST_UPDATE_USER_PROPERTY_KEY) + config.get(autoUpdateUserPropertiesIntervalKey, 0):
with safe_write(self.REQUEST):
self._updateUserProperties(user, userinfo)
if user and self.create_ticket:
if user and self.getProperty("create_ticket"):
self._setupTicket(user_id)
if user and self.create_restapi_ticket:
if user and self.getProperty("create_restapi_ticket"):
self._setupJWTTicket(user_id, user)

def _updateUserProperties(self, user, userinfo):
Expand Down Expand Up @@ -231,26 +231,26 @@ def get_oauth2_client(self):
# 'error_description': "Policy 'Trusted Hosts' rejected request to client-registration service. Details: Host not trusted."}

# use WebFinger
provider_info = client.provider_config(self.issuer) # noqa
provider_info = client.provider_config(self.getProperty("issuer")) # noqa
info = {
"client_id": self.client_id,
"client_secret": self.client_secret,
"client_id": self.getProperty("client_id"),
"client_secret": self.getProperty("client_secret"),
}
client_reg = RegistrationResponse(**info)
client.store_registration_info(client_reg)
return client

def get_redirect_uris(self):
if self.redirect_uris:
return [safe_unicode(u) for u in self.redirect_uris]
if self.getProperty("redirect_uris"):
return [safe_unicode(u) for u in self.getProperty("redirect_uris")]
else:
return [
"{}/callback".format(self.absolute_url()),
]

def get_scopes(self):
if self.scope:
return [safe_unicode(u) for u in self.scope]
if self.getProperty("scope"):
return [safe_unicode(u) for u in self.getProperty("scope")]
else:
return []

Expand Down
4 changes: 2 additions & 2 deletions src/pas/plugins/oidc/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ def setUp(self):
def test_remember_identity(self):
userinfo = OpenIDSchema(sub="bob")
# auto create user by default
self.assertTrue(self.plugin.create_user)
self.assertTrue(self.plugin.getProperty("create_user"))
# set __ac ticket by default
self.assertTrue(self.plugin.create_ticket)
self.assertTrue(self.plugin.getProperty("create_ticket"))
self.assertIsNone(self.pas.getUserById("bob"))
self.plugin.rememberIdentity(userinfo)
self.assertIsNotNone(self.pas.getUserById("bob"))
Expand Down
6 changes: 3 additions & 3 deletions src/pas/plugins/oidc/tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def setUp(self):

def test_product_installed(self):
"""Test if pas.plugins.oidc is installed."""
self.assertTrue(self.installer.isProductInstalled("pas.plugins.oidc"))
self.assertTrue(self.installer.is_product_installed("pas.plugins.oidc"))

def test_browserlayer(self):
"""Test that IPasPluginsOidcLayer is registered."""
Expand All @@ -51,12 +51,12 @@ def setUp(self):
self.installer = api.portal.get_tool("portal_quickinstaller")
roles_before = api.user.get_roles(TEST_USER_ID)
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.installer.uninstallProducts(["pas.plugins.oidc"])
self.installer.uninstall_product("pas.plugins.oidc")
setRoles(self.portal, TEST_USER_ID, roles_before)

def test_product_uninstalled(self):
"""Test if pas.plugins.oidc is cleanly uninstalled."""
self.assertFalse(self.installer.isProductInstalled("pas.plugins.oidc"))
self.assertFalse(self.installer.is_product_installed("pas.plugins.oidc"))

def test_browserlayer_removed(self):
"""Test that IPasPluginsOidcLayer is removed."""
Expand Down
10 changes: 10 additions & 0 deletions test_plone60.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[buildout]

extends =
https://raw.githubusercontent.com/collective/buildout.plonetest/master/test-6.0.x.cfg
https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg
base.cfg

update-versions-file = test_plone60.cfg

[versions]
9 changes: 7 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,27 @@ envlist =
# plone51-py27
# plone52-py{27,37,38,39}
plone52-py{37,38,39}
plone60-py{37,38,39,310}

[testenv]
# We do not install with pip, but with buildout:
usedevelop = false
skip_install = true
deps =
-r requirements.txt
!plone60: -rrequirements.txt
plone60: -rrequirements-6.0.x.txt
commands_pre =
plone43: {envbindir}/buildout -Nc {toxinidir}/test_plone43.cfg buildout:directory={envdir} buildout:develop={toxinidir}
plone50: {envbindir}/buildout -Nc {toxinidir}/test_plone50.cfg buildout:directory={envdir} buildout:develop={toxinidir}
plone51: {envbindir}/buildout -Nc {toxinidir}/test_plone51.cfg buildout:directory={envdir} buildout:develop={toxinidir}
plone52: {envbindir}/buildout -Nc {toxinidir}/test_plone52.cfg buildout:directory={envdir} buildout:develop={toxinidir}
plone60: {envbindir}/buildout -Nc {toxinidir}/test_plone60.cfg buildout:directory={envdir} buildout:develop={toxinidir}
# changedir={envdir}
commands =
{envbindir}/coverage run {envbindir}/test
{envbindir}/coverage html
{envbindir}/coverage report -m --fail-under=85
# TODO: increase coverage
{envbindir}/coverage report -m --fail-under=50
# {envbindir}/coverage report -m --fail-under=85
{envbindir}/coverage json -i

0 comments on commit c07daac

Please sign in to comment.