0001-auth-separate-OIDC-providers-in-blocks-on-login-page.patch
src/authentic2/views.py | ||
---|---|---|
323 | 323 |
block['form'] = form_class() |
324 | 324 |
blocks.append(block) |
325 | 325 |
else: # New frontends API |
326 |
auth_blocks = [] |
|
326 | 327 |
parameters = {'request': request, |
327 | 328 |
'context': context} |
328 |
block = utils.get_authenticator_method(authenticator, 'login', parameters) |
|
329 |
# check if the authenticator has multiple instances |
|
330 |
if hasattr(authenticator, 'instances'): |
|
331 |
for instance_id, instance in authenticator.instances(**parameters): |
|
332 |
parameters['instance'] = instance |
|
333 |
block = utils.get_authenticator_method(authenticator, 'login', parameters) |
|
334 |
# update block id in order to separate instances |
|
335 |
block['id'] = instance_id |
|
336 |
auth_blocks.append(block) |
|
337 |
else: |
|
338 |
auth_blocks.append(utils.get_authenticator_method(authenticator, 'login', parameters)) |
|
329 | 339 |
# If a login frontend method returns an HttpResponse with a status code != 200 |
330 | 340 |
# this response is returned. |
331 |
if block: |
|
332 |
if block['status_code'] != 200: |
|
333 |
return block['response'] |
|
334 |
blocks.append(block) |
|
335 |
if hasattr(authenticator, 'is_hidden'): |
|
336 |
blocks[-1]['is_hidden'] = authenticator.is_hidden(request) |
|
337 |
else: |
|
338 |
blocks[-1]['is_hidden'] = False |
|
341 |
for block in auth_blocks: |
|
342 |
if block: |
|
343 |
if block['status_code'] != 200: |
|
344 |
return block['response'] |
|
345 |
blocks.append(block) |
|
346 |
if hasattr(authenticator, 'is_hidden'): |
|
347 |
blocks[-1]['is_hidden'] = authenticator.is_hidden(request) |
|
348 |
else: |
|
349 |
blocks[-1]['is_hidden'] = False |
|
339 | 350 | |
340 | 351 | |
341 | 352 |
# Old frontends API |
src/authentic2_auth_oidc/authenticators.py | ||
---|---|---|
14 | 14 |
def id(self): |
15 | 15 |
return 'oidc' |
16 | 16 | |
17 |
def instances(self, request, *args, **kwargs): |
|
18 |
return [('%s-%s' % (self.id, p.slug), p) for p in utils.get_providers(shown=True)] |
|
19 | ||
20 | ||
17 | 21 |
def login(self, request, *args, **kwargs): |
18 | 22 |
context = kwargs.get('context', {}) |
19 |
context['providers'] = utils.get_providers(shown=True) |
|
20 |
return render(request, 'authentic2_auth_oidc/login.html', context) |
|
23 |
if kwargs.get('instance'): |
|
24 |
context['provider'] = kwargs['instance'] |
|
25 |
return render(request, 'authentic2_auth_oidc/login.html', context) |
src/authentic2_auth_oidc/templates/authentic2_auth_oidc/login.html | ||
---|---|---|
1 |
{% for provider in providers %} |
|
2 |
<p id="oidc-p-{% firstof provider.slug provider.name|slugify %}"> |
|
3 |
<a id="oidc-a-{% firstof provider.slug provider.name|slugify %}" |
|
4 |
href="{% url "oidc-login" pk=provider.pk %}?{{ request.GET.urlencode }}">{{ provider.name }}</a> |
|
5 |
</p> |
|
6 |
{% endfor %} |
|
1 |
<p id="oidc-p-{% firstof provider.slug provider.name|slugify %}"> |
|
2 |
<a id="oidc-a-{% firstof provider.slug provider.name|slugify %}" |
|
3 |
href="{% url "oidc-login" pk=provider.pk %}?{{ request.GET.urlencode }}">{{ provider.name }}</a> |
|
4 |
</p> |
|
5 |
tests/test_auth_oidc.py | ||
---|---|---|
260 | 260 |
return qs |
261 | 261 | |
262 | 262 | |
263 |
def test_providers_on_login_page(oidc_provider, app): |
|
264 |
response = app.get('/login/') |
|
265 |
# two frontends should be presnt on login page |
|
266 |
assert "css-tab2" in response |
|
267 |
assert "OIDIDP" in response |
|
268 |
OIDCProvider.objects.create( |
|
269 |
id=2, |
|
270 |
ou=get_default_ou(), |
|
271 |
name='OIDIDP 2', |
|
272 |
slug='oididp-2', |
|
273 |
issuer='https://idp2.example.com/', |
|
274 |
authorization_endpoint='https://idp2.example.com/authorize', |
|
275 |
token_endpoint='https://idp2.example.com/token', |
|
276 |
end_session_endpoint='https://idp2.example.com/logout', |
|
277 |
userinfo_endpoint='https://idp*é.example.com/user_info', |
|
278 |
token_revocation_endpoint='https://idp2.example.com/revoke', |
|
279 |
max_auth_age=10, |
|
280 |
strategy=OIDCProvider.STRATEGY_CREATE, |
|
281 |
jwkset_json=None, |
|
282 |
idtoken_algo=OIDCProvider.ALGO_RSA, |
|
283 |
claims_parameter_supported=False |
|
284 |
) |
|
285 |
response = app.get('/login/') |
|
286 |
assert "css-tab3" in response |
|
287 |
assert 'OIDIDP 2' in response |
|
288 | ||
289 | ||
263 | 290 |
def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url, login_callback_url, hooks): |
264 | 291 |
OU = get_ou_model() |
265 | 292 |
cassis = OU.objects.create(name='Cassis', slug='cassis') |
266 |
- |