auth_oidc: add passive authn deactivation flag (#73412)

This commit is contained in:
Paul Marillonnet 2023-01-17 09:02:25 +01:00
parent ffe6c35471
commit 74e6f1f248
4 changed files with 79 additions and 1 deletions

View File

@ -349,7 +349,11 @@ def passive_login(request, *, next_url, login_hint=None):
visible_authenticators = [
authenticator
for authenticator in authenticators
if (authenticator.shown(ctx=show_ctx) and getattr(authenticator, 'passive_login', None))
if (
authenticator.shown(ctx=show_ctx)
and getattr(authenticator, 'passive_authn_supported', True)
and getattr(authenticator, 'passive_login', None)
)
]
if not visible_authenticators:

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.26 on 2023-01-17 08:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentic2_auth_oidc', '0013_synchronization_fields'),
]
operations = [
migrations.AddField(
model_name='oidcprovider',
name='passive_authn_supported',
field=models.BooleanField(default=True, verbose_name='Supports passive authentication'),
),
]

View File

@ -140,6 +140,11 @@ class OIDCProvider(BaseAuthenticator):
created = models.DateTimeField(verbose_name=_('creation date'), auto_now_add=True)
modified = models.DateTimeField(verbose_name=_('last modification date'), auto_now=True)
# passive authn deactivation flag
passive_authn_supported = models.BooleanField(
verbose_name=_('Supports passive authentication'),
default=True,
)
objects = managers.OIDCProviderManager()
type = 'oidc'

View File

@ -43,6 +43,7 @@ from authentic2.apps.authenticators.models import LoginPasswordAuthenticator
from authentic2.custom_user.models import DeletedUser
from authentic2.models import Attribute, AttributeValue
from authentic2.utils.misc import last_authentication_event
from authentic2.views import passive_login
from authentic2_auth_oidc.backends import OIDCBackend
from authentic2_auth_oidc.models import OIDCAccount, OIDCClaimMapping, OIDCProvider
from authentic2_auth_oidc.utils import IDToken, IDTokenError, parse_id_token, register_issuer
@ -1470,3 +1471,53 @@ def test_passive_login(get_provider, rf):
_, query = url.split('?', 1)
qs = dict(urllib.parse.parse_qsl(query))
assert qs['prompt'] == 'none'
@mock.patch('authentic2_auth_oidc.views.get_provider')
def test_passive_login_main_view(get_provider, rf):
AUTHORIZE_URL = 'https://op.example.com/authorize'
SCOPES = {'profile'}
provider = OIDCProvider.objects.create(
pk=1,
client_id='1234',
authorization_endpoint=AUTHORIZE_URL,
scopes=' '.join(SCOPES),
passive_authn_supported=True,
enabled=True,
)
get_provider.return_value = provider
req = rf.get('/')
req.user = mock.Mock()
req.user.is_authenticated = False
req.session = {}
response = passive_login(req, next_url='/manage/')
assert response.status_code == 302
assert response.url.startswith('https://op.example.com/authorize?')
_, query = response.url.split('?', 1)
qs = dict(urllib.parse.parse_qsl(query))
assert qs['prompt'] == 'none'
@mock.patch('authentic2_auth_oidc.views.get_provider')
def test_passive_login_main_view_deactivated(get_provider, rf):
AUTHORIZE_URL = 'https://op.example.com/authorize'
SCOPES = {'profile'}
provider = OIDCProvider.objects.create(
pk=1,
client_id='1234',
authorization_endpoint=AUTHORIZE_URL,
scopes=' '.join(SCOPES),
passive_authn_supported=False,
enabled=True,
)
get_provider.return_value = provider
req = rf.get('/')
req.user = mock.Mock()
req.user.is_authenticated = False
req.session = {}
response = passive_login(req, next_url='/manage/')
assert response is None