authentication methods: allow selection on personal info page, set cookie, check on login page

This commit is contained in:
Helmut Merz 2025-10-25 17:31:25 +02:00
parent f9474e59db
commit d588469bb5
5 changed files with 60 additions and 5 deletions

View file

@ -39,6 +39,7 @@ from loops.organize.util import getPrincipalFolder
import loops.browser.util
from loops.util import _
import config
organize_macros = ViewPageTemplateFile('view_macros.pt')
@ -60,6 +61,13 @@ class PersonalInfo(ConceptView):
def view(self):
return self
@Lazy
def selectAuthMethod(self):
return getattr(config, 'authentication_method', 'legacy') == 'cookie'
def getAuthMethod(self):
return self.request.cookies.get('loops_auth_method') or 'legacy'
@Lazy
def extUserLink(self):
from scopes.web.auth.oidc import IExternalPrincipal

View file

@ -60,6 +60,20 @@
<li tal:condition="python:item.globalOptions('organize.useFilters')">
<a href="edit_filters.html"
i18n:translate="">Edit Filters</a></li>
<li tal:condition="item/selectAuthMethod">
<span>Authentication Method:</span>
<select name="auth_method"
onchange="document.cookie=`loops_auth_method=${this.value}; path=/`"
tal:define="meth item/getAuthMethod"
tal:attributes="value meth">
<option value="legacy"
tal:attributes="selected python:meth=='legacy'">Legacy</option>
<option value="oidc"
tal:attributes="selected python:meth=='oidc'">OpenID Connect</option>
<option value="select"
tal:attributes="selected python:meth=='select'">Selection</option>
</select>
</li>
</ul>
</metal:block>
</metal:block>

View file

@ -5,24 +5,56 @@
from scopes.web.auth import oidc
from zope.authentication.interfaces import IAuthentication
from zope.browserpage import ViewPageTemplateFile
from zope.component import provideAdapter, getUtility, provideUtility
from zope.interface import implementer, Interface
from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserPage
from zope.publisher.browser import BrowserPage
from zope.security.proxy import removeSecurityProxy
import config
def registerAuthUtility(config):
baseAuth = getUtility(IAuthentication)
print('*** registerAuthUtility, baseAuth:', baseAuth)
provideUtility(oidc.OidcAuthentication(baseAuth))
class LoginView:
class LoginPage:
index = ViewPageTemplateFile('loginform.pt')
def __init__(self, context, request):
self.context = context
self.request = request
self.authMethod = getattr(config, 'authentication_method', 'legacy')
if self.authMethod == 'cookie':
self.authMethod = getAuthMethodCookieValue(request)
self.oidc_allowed = self.authMethod in ('oidc', 'select')
def __call__(self):
print('***', self.request.principal.id)
print('***', self.authMethod)
if self.authMethod == 'oidc':
return self.authOidc()
return self.index()
def authOidc(self):
oidc.Authenticator(self.request).login()
return ''
def getAuthMethodCookieValue(request):
print('***', dict(request.cookies))
return request.cookies.get('loops_auth_method') or 'legacy'
# OIDC authentication
class LoginView(LoginPage):
def __call__(self):
return self.authOidc()
class CallbackView:

View file

@ -25,7 +25,8 @@
<p i18n:translate="" tal:condition="python: principal != 'zope.anybody'">
You are not authorized to perform this action. However, you may login as a
different user who is authorized.</p>
<p i18n:domain="loops">
<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>

View file

@ -2,9 +2,9 @@
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<browser:page
name="loginForm.html" for="*"
template="loginform.pt"
<browser:page for="*"
name="loginForm.html"
class="loops.server.auth.LoginPage"
permission="zope.Public"
layer="cybertools.browser.loops.Loops" />