cco.member: provide OIDC authentication via loops.server.auth

This commit is contained in:
Helmut Merz 2025-10-27 16:29:01 +01:00
parent 110fa036f4
commit f27b0f952f
4 changed files with 37 additions and 6 deletions

View file

@ -9,6 +9,11 @@
i18n:translate=""
tal:content="request/error_message" />
<h2 i18n:translate="title_login">Login</h2>
<p i18n:domain="loops"
tal:condition="view/oidc_allowed">
<a tal:attributes="href string:/@@auth_login?camefrom=$camefrom"
i18n:translate="login-with-oidc">Login with OpenID Connect (Zitadel)</a>
</p>
<div>
<p i18n:translate="description_login"
tal:condition="python: principal == 'zope.anybody'">

View file

@ -23,6 +23,7 @@ from zope.publisher.interfaces.http import IHTTPRequest
from zope.security.interfaces import Unauthorized as DefaultUnauth
from zope.sendmail.interfaces import IMailDelivery
from scopes.web.auth import oidc
from cco.member.auth import getCredentials, getPrincipalFromCredentials,\
getPrincipalForUsername, JWT_SECRET
from cco.member.interfaces import IPasswordChange, IPasswordReset
@ -36,11 +37,9 @@ from loops.common import adapted
from loops.organize.interfaces import IMemberRegistrationManager
from loops.organize.party import getPersonForUser
from loops.organize.util import getPrincipalForUserId, getPrincipalFolder
from loops.server.auth import getAuthMethodCookieValue, getConfigAuthMethod
try:
import config
except ImportError:
config = None
log = logging.getLogger('cco.member.browser')
@ -60,14 +59,36 @@ def validateToken(token, secret=None):
return True
class LoginConcept(ConceptView):
class LoginBase:
def __call__(self):
if self.authMethod == 'oidc':
return self.authOidc()
return super(LoginBase, self).__call__()
@Lazy
def authMethod(self):
if getConfigAuthMethod() == 'cookie':
return getAuthMethodCookieValue(self.request)
return 'legacy'
@Lazy
def oidc_Allowed(self):
return self.authMethod in ('select', 'oidc')
def authOidc(self):
oidc.Authenticator(self.request).login()
return ''
class LoginConcept(LoginBase, ConceptView):
@Lazy
def macro(self):
return template.macros['login_form']
class LoginForm(NodeView):
class LoginForm(LoginBase, NodeView):
@Lazy
def macro(self):

2
cco/member/config.py Normal file
View file

@ -0,0 +1,2 @@
# loops-ext: cco.member.config
# (for testing only)

View file

@ -3,6 +3,9 @@
""" Tests for the 'cco.member' package.
"""
import os, sys
sys.path = [os.path.dirname(__file__)] + sys.path # for import of config.py
import os
import unittest, doctest
from zope import component