authenticators: add helper functions for show condition (#67986)
gitea/authentic/pipeline/head This commit looks good Details

This commit is contained in:
Emmanuel Cazenave 2024-03-21 15:55:38 +01:00
parent 4dc8f6aab7
commit 36bc55d3ce
3 changed files with 100 additions and 1 deletions

View File

@ -19,6 +19,7 @@ import logging
import uuid import uuid
from django.apps import apps from django.apps import apps
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.db.models import Max from django.db.models import Max
@ -135,10 +136,28 @@ class BaseAuthenticator(models.Model):
value=value, value=value,
) )
def is_for_office(self, office_keyword, ctx):
try:
return evaluate_condition(
settings.AUTHENTICATOR_SHOW_CONDITIONS[office_keyword], ctx, on_raise=False
)
except Exception as e:
logger.error(e)
return False
def shown(self, ctx=()): def shown(self, ctx=()):
if not self.show_condition: if not self.show_condition:
return True return True
ctx = dict(ctx, id=self.slug)
def is_for_backoffice():
return self.is_for_office('is_for_backoffice', ctx)
def is_for_frontoffice():
return self.is_for_office('is_for_frontoffice', ctx)
ctx = dict(
ctx, id=self.slug, is_for_backoffice=is_for_backoffice, is_for_frontoffice=is_for_frontoffice
)
try: try:
return evaluate_condition(self.show_condition, ctx, on_raise=True) return evaluate_condition(self.show_condition, ctx, on_raise=True)
except Exception as e: except Exception as e:

View File

@ -405,6 +405,11 @@ PHONE_COUNTRY_CODES = {
DEFAULT_COUNTRY_CODE = '33' DEFAULT_COUNTRY_CODE = '33'
AUTHENTICATOR_SHOW_CONDITIONS = {
'is_for_backoffice': "'backoffice' in login_hint",
'is_for_frontoffice': "'backoffice' not in login_hint",
}
# #
# Load configuration file # Load configuration file
# #

View File

@ -334,6 +334,81 @@ def test_show_condition_with_headers(db, app, settings):
assert 'name="login-password-submit"' in response assert 'name="login-password-submit"' in response
def test_show_condition_is_for_backoffice(db, app, settings, caplog):
response = app.get('/login/')
assert 'name="login-password-submit"' in response
LoginPasswordAuthenticator.objects.update(show_condition='is_for_backoffice()')
response = app.get('/login/')
assert 'name="login-password-submit"' not in response
assert len(caplog.records) == 0
response = app.get('/manage/')
response = response.follow()
assert 'name="login-password-submit"' in response
assert len(caplog.records) == 0
app.reset()
# combine
LoginPasswordAuthenticator.objects.update(
show_condition="is_for_backoffice() and 'X-Entrouvert' in headers"
)
response = app.get('/manage/')
response = response.follow()
assert 'name="login-password-submit"' not in response
assert len(caplog.records) == 0
app.reset()
response = app.get('/manage/')
response = response.follow(headers={'x-entrouvert': '1'})
assert 'name="login-password-submit"' in response
assert len(caplog.records) == 0
app.reset()
# set a condition with error
settings.AUTHENTICATOR_SHOW_CONDITIONS['is_for_backoffice'] = "'backoffice' in unknown"
LoginPasswordAuthenticator.objects.update(show_condition='is_for_backoffice()')
response = app.get('/manage/')
response = response.follow()
assert 'name="login-password-submit"' not in response
assert len(caplog.records) == 1
def test_show_condition_is_for_frontoffice(db, app, settings, caplog):
response = app.get('/login/')
assert 'name="login-password-submit"' in response
LoginPasswordAuthenticator.objects.update(show_condition='is_for_frontoffice()')
response = app.get('/login/')
assert 'name="login-password-submit"' in response
assert len(caplog.records) == 0
response = app.get('/manage/')
response = response.follow()
assert 'name="login-password-submit"' not in response
assert len(caplog.records) == 0
app.reset()
# combine
LoginPasswordAuthenticator.objects.update(
show_condition="is_for_frontoffice() and 'X-Entrouvert' in headers"
)
response = app.get('/login/')
assert 'name="login-password-submit"' not in response
assert len(caplog.records) == 0
response = app.get('/login/', headers={'X-entrouvert': '1'})
assert 'name="login-password-submit"' in response
assert len(caplog.records) == 0
# set a condition with error
settings.AUTHENTICATOR_SHOW_CONDITIONS['is_for_frontoffice'] = "'backoffice' not in unknown"
LoginPasswordAuthenticator.objects.update(show_condition='is_for_frontoffice()')
response = app.get('/login/')
assert 'name="login-password-submit"' not in response
assert len(caplog.records) == 1
def test_registration_url_on_login_page(db, app): def test_registration_url_on_login_page(db, app):
response = app.get('/login/?next=/whatever') response = app.get('/login/?next=/whatever')
assert 'register/?next=/whatever"' in response assert 'register/?next=/whatever"' in response