diff --git a/inst/loops/application.zcml b/inst/loops/application.zcml
index 537344a..13636d5 100644
--- a/inst/loops/application.zcml
+++ b/inst/loops/application.zcml
@@ -24,6 +24,8 @@
-->
+
+
diff --git a/inst/loops/config.py b/inst/loops/config.py
index db7f054..d4a6866 100644
--- a/inst/loops/config.py
+++ b/inst/loops/config.py
@@ -9,6 +9,7 @@ server_id = getenv('SERVER_ID')
zope_conf = getenv('ZOPE_CONF', 'zope.conf')
server_port = getenv('SERVER_PORT',
server_id and getenv(f'SERVER_PORT_{server_id}')) or '8080'
+base_url = getenv('BASE_URL', 'https://test.example.com')
shell_pw = (getenv('SHELL_PW', 'dummy'))
loops_path = (getenv('LOOPS_PATH', 'loops/demo'))
@@ -20,3 +21,20 @@ dbname = getenv('DBNAME', 'demo')
dbuser = getenv('DBUSER', 'demo')
dbpassword = getenv('DBPASSWORD', 'secret')
dbschema = getenv('DBSCHEMA', 'demo')
+
+# OpenID Connect (OIDC, e.g. via zitadel) authentication settings
+oidc_provider = getenv('OIDC_PROVIDER', '') #'https://instance1-abcdef.zitadel.cloud')
+oidc_client_id = getenv('OIDC_CLIENT_ID', '12345')
+oidc_params = dict(
+ op_config_url=oidc_provider + '/.well-known/openid-configuration',
+ op_uris=None,
+ op_keys=None,
+ callback_url=getenv('OIDC_CALLBACK_URL', base_url + '/auth_callback'),
+ client_id=oidc_client_id,
+ principal_prefix=getenv('OIDC_PRINCIPAL_PREFIX', 'loops.'),
+ cookie_name=getenv('OIDC_COOKIE_NAME', 'oidc_' + oidc_client_id),
+ cookie_domain=getenv('OIDC_COOKIE_DOMAIN', None),
+ cookie_lifetime=getenv('OIDC_COOKIE_LIFETIME', '86400'),
+ cookie_crypt=getenv('OIDC_COOKIE_CRYPT', None)
+)
+
diff --git a/loops/organize/interfaces.py b/loops/organize/interfaces.py
index e51ccff..7a5cca7 100644
--- a/loops/organize/interfaces.py
+++ b/loops/organize/interfaces.py
@@ -18,7 +18,6 @@ from loops.interfaces import HtmlText
from loops.organize.util import getPrincipalFolder, getPrincipalForUserId
from loops import util
from loops.util import _
-from scopes.web.auth import oidc
ANNOTATION_KEY = 'loops.organize.person'
@@ -34,7 +33,7 @@ def raiseValidationError(info):
class UserId(schema.TextLine):
- """ Obsolete, as member registration does not use zope.formlib any more.
+ """ Note: member registration does not use zope.formlib any more.
TODO: transfer validation to loops.organize.browser.
"""
@@ -44,11 +43,6 @@ class UserId(schema.TextLine):
from loops.organize.party import getPersonForUser
context = removeSecurityProxy(self.context).context
principal = getPrincipalForUserId(userId, context)
- #auth = component.getUtility(IAuthentication, context=context)
- #try:
- #principal = auth.getPrincipal(userId)
- #except PrincipalLookupError:
- #principal = oidc.Principal(userId, dict(name=userId))
if principal is None:
raiseValidationError(_('User $userId does not exist',
mapping={'userId': userId}))
diff --git a/loops/organize/party.py b/loops/organize/party.py
index d73a2ab..e440e4c 100644
--- a/loops/organize/party.py
+++ b/loops/organize/party.py
@@ -33,7 +33,6 @@ from loops.security.common import getCurrentPrincipal
from loops.security.interfaces import ISecuritySetter
from loops.type import TypeInterfaceSourceList
from loops import util
-from scopes.web.auth import oidc
# register type interfaces - (TODO: use a function for this)
@@ -87,7 +86,6 @@ class Person(AdapterBase, BasePerson):
setter = ISecuritySetter(self)
if userId:
principal = self.getPrincipalForUserId(userId)
- print('***', userId, principal)
if principal is None:
return
person = getPersonForUser(self.context, principal=principal)
@@ -144,14 +142,6 @@ class Person(AdapterBase, BasePerson):
def getPrincipalForUserId(self, userId=None):
userId = userId or self.userId
return getPrincipalForUserId(userId, self.context, self.authentication)
- if not userId:
- return None
- auth = self.authentication
- try:
- return auth.getPrincipal(userId)
- except PrincipalLookupError:
- return oidc.Principal(userId, dict(name=userId))
- #return None
def getAuthenticationUtility(context):
diff --git a/loops/organize/util.py b/loops/organize/util.py
index df1d067..f728093 100644
--- a/loops/organize/util.py
+++ b/loops/organize/util.py
@@ -15,7 +15,6 @@ from zope.traversing.api import getParents
from loops.common import adapted
from loops.security.common import getCurrentPrincipal
from loops.type import getOptionsDict
-from scopes.web.auth import oidc
defaultAuthPluginId = 'loops'
@@ -93,6 +92,7 @@ def getPrincipalForUserId(id, context=None, auth=None):
try:
return auth.getPrincipal(id)
except PrincipalLookupError:
+ from scopes.web.auth import oidc
return oidc.Principal(id, dict(name=id))
#return None
diff --git a/loops/server/auth.zcml b/loops/server/auth.zcml
new file mode 100644
index 0000000..124c0e6
--- /dev/null
+++ b/loops/server/auth.zcml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/loops/server/main.py b/loops/server/main.py
index a1b0964..a638ceb 100644
--- a/loops/server/main.py
+++ b/loops/server/main.py
@@ -15,7 +15,8 @@ import waitress
from zope.app.wsgi import config, getWSGIApplication
def run(app, config):
- oidc.startup()
+ if config.oidc_provider:
+ oidc.startup()
port = int(config.server_port)
print(f'Serving on port {port}.')
waitress.serve(app, port=port)
diff --git a/loops/tests/config.py b/loops/tests/config.py
index b910662..b1005e5 100644
--- a/loops/tests/config.py
+++ b/loops/tests/config.py
@@ -1,8 +1,8 @@
-# py-scopes/demo/config.py
+# loops/tests/config.py
from dotenv import load_dotenv
from os import getenv
-from scopes.server.app import zope_app_factory
+from scopes.web.app import zope_app_factory
load_dotenv()
@@ -18,3 +18,21 @@ dbuser = getenv('DBUSER', 'demo')
dbpassword = getenv('DBPASSWORD', 'secret')
dbschema = getenv('DBSCHEMA', 'demo')
+base_url = 'test://'
+
+# authentication settings
+oidc_provider = ''
+oidc_client_id = getenv('OIDC_CLIENT_ID', '12345')
+oidc_params = dict(
+ op_config_url=oidc_provider + '/.well-known/openid-configuration',
+ op_uris=None,
+ op_keys=None,
+ callback_url=getenv('OIDC_CALLBACK_URL', base_url + '/auth/callback'),
+ client_id=oidc_client_id,
+ principal_prefix=getenv('OIDC_PRINCIPAL_PREFIX', 'loops.'),
+ cookie_name=getenv('OIDC_COOKIE_NAME', 'oidc_' + oidc_client_id),
+ cookie_domain=getenv('OIDC_COOKIE_DOMAIN', None),
+ cookie_lifetime=getenv('OIDC_COOKIE_LIFETIME', '86400'),
+ cookie_crypt=getenv('OIDC_COOKIE_CRYPT', None)
+)
+
diff --git a/loops/tests/test_loops.py b/loops/tests/test_loops.py
index 52049b6..a529aa0 100755
--- a/loops/tests/test_loops.py
+++ b/loops/tests/test_loops.py
@@ -1,5 +1,8 @@
# loops.tests.test_loops
+import os, sys
+sys.path = [os.path.dirname(__file__)] + sys.path
+
import unittest, doctest
import warnings
from zope.interface.verify import verifyClass