Bug fix for improperly configured SSO provider (#4822)

* Add sso template tags

* Check if SSO provider is valid on login page

* Add warning if SSO method is not correctly configured

* Template tweaks
This commit is contained in:
Oliver 2023-05-15 15:09:14 +10:00 committed by GitHub
parent 065f3e2404
commit 368f615d71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 160 additions and 66 deletions

View File

@ -0,0 +1,48 @@
"""This module provides template tags pertaining to SSO functionality"""
from django import template
from common.models import InvenTreeSetting
from InvenTree.helpers import str2bool
register = template.Library()
@register.simple_tag()
def sso_login_enabled():
"""Return True if single-sign-on is enabled"""
val = InvenTreeSetting.get_setting('LOGIN_ENABLE_SSO')
print("SSO Enabled:", val)
return str2bool(InvenTreeSetting.get_setting('LOGIN_ENABLE_SSO'))
@register.simple_tag()
def sso_reg_enabled():
"""Return True if single-sign-on is enabled for self-registration"""
return str2bool(InvenTreeSetting.get_setting('LOGIN_ENABLE_SSO_REG'))
@register.simple_tag()
def sso_auto_enabled():
"""Return True if single-sign-on is enabled for auto-registration"""
return str2bool(InvenTreeSetting.get_setting('LOGIN_SIGNUP_SSO_AUTO'))
@register.simple_tag()
def sso_check_provider(provider):
"""Return True if the given provider is correctly configured"""
from allauth.socialaccount.models import SocialApp
# First, check that the provider is enabled
if not SocialApp.objects.filter(provider__iexact=provider.name).exists():
return False
# Next, check that the provider is correctly configured
# At this point, we assume that the provider is correctly configured
return True

View File

@ -1,6 +1,7 @@
{% extends "panel.html" %}
{% load i18n %}
{% load sso %}
{% load inventree_extras %}
{% load socialaccount %}
{% load crispy_forms_tags %}
@ -112,62 +113,7 @@
{% endif %}
</div>
<div class="row">
<div class='panel-heading'>
<h4>{% trans "Social Accounts" %}</h4>
</div>
<div class="col-md-6">
{% if social_form.accounts %}
<p>{% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}</p>
<form method="post" action="{% url 'socialaccount_connections' %}">
{% csrf_token %}
<fieldset>
{% if social_form.non_field_errors %}
<div id="errorMsg">{{ social_form.non_field_errors }}</div>
{% endif %}
{% for base_account in social_form.accounts %}
{% with base_account.get_provider_account as account %}
<div>
<label for="id_account_{{ base_account.id }}">
<input id="id_account_{{ base_account.id }}" type="radio" name="account"
value="{{ base_account.id }}" />
<span class="socialaccount_provider {{ base_account.provider }} {{ account.get_brand.id }}">
<span class='brand-icon'
brand_name='{{ account.get_brand.id }}'></span>{{ account.get_brand.name }}</span>
{{ account }}
</label>
</div>
{% endwith %}
{% endfor %}
<div>
<button class="btn btn-primary" type="submit">{% trans 'Remove' %}</button>
</div>
</fieldset>
</form>
{% else %}
<div class='alert alert-block alert-warning'>
{% trans 'There are no social network accounts connected to this account.' %}
</div>
{% endif %}
</div>
<div class="col-md-6">
<h5>{% trans 'Add a 3rd Party Account' %}</h5>
<div>
{% include "socialaccount/snippets/provider_list.html" with process="connect" %}
</div>
{% include "socialaccount/snippets/login_extra.html" %}
</div>
</div>
{% include "InvenTree/settings/user_sso.html" %}
<div class="row">
<div class='panel-heading'>

View File

@ -0,0 +1,71 @@
{% load i18n %}
{% load inventree_extras %}
{% load sso %}
{% sso_login_enabled as sso %}
<div class="row">
<div class='panel-heading'>
<h4>{% trans "Single Sign On Accounts" %}</h4>
{% include "spacer.html" %}
</div>
{% if sso %}
<div class="col-md-6">
{% if social_form.accounts %}
<p>{% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}</p>
<form method="post" action="{% url 'socialaccount_connections' %}">
{% csrf_token %}
<fieldset>
{% if social_form.non_field_errors %}
<div id="errorMsg">{{ social_form.non_field_errors }}</div>
{% endif %}
{% for base_account in social_form.accounts %}
{% with base_account.get_provider_account as account %}
<div>
<label for="id_account_{{ base_account.id }}">
<input id="id_account_{{ base_account.id }}" type="radio" name="account"
value="{{ base_account.id }}" />
<span class="socialaccount_provider {{ base_account.provider }} {{ account.get_brand.id }}">
<span class='brand-icon'
brand_name='{{ account.get_brand.id }}'></span>{{ account.get_brand.name }}</span>
{{ account }}
</label>
</div>
{% endwith %}
{% endfor %}
<div>
<button class="btn btn-primary" type="submit">{% trans 'Remove' %}</button>
</div>
</fieldset>
</form>
{% else %}
<div class='alert alert-block alert-warning'>
{% trans 'There are no social network accounts connected to this account.' %}
</div>
{% endif %}
</div>
<div class="col-md-6">
<h5>{% trans 'Add SSO Account' %}</h5>
<div>
{% include "socialaccount/snippets/provider_list.html" with process="connect" %}
</div>
{% include "socialaccount/snippets/login_extra.html" %}
</div>
{% else %}
<div class='alert alert-block alert-warning'>
{% trans "Single Sign On is not enabled for this server" %}
</div>
{% endif %}
</div>

View File

@ -1,15 +1,20 @@
{% extends "socialaccount/base.html" %}
{% load i18n %}
{% load sso %}
{% block head_title %}{% trans "Sign In" %}{% endblock head_title %}
{% block content %}
{% sso_check_provider provider as provider_valid %}
{% if provider_valid %}
{% if process == "connect" %}
<h3>{% blocktrans with provider.name as provider %}Connect {{ provider }}{% endblocktrans %}</h3>
<h4>{% blocktrans with provider.name as provider %}Connect {{ provider }}{% endblocktrans %}</h4>
<p>{% blocktrans with provider.name as provider %}You are about to connect a new third party account from {{ provider }}.{% endblocktrans %}</p>
{% else %}
<h3>{% blocktrans with provider.name as provider %}Sign In Via {{ provider }}{% endblocktrans %}</h3>
<h4>{% blocktrans with provider.name as provider %}Sign In Via {{ provider }}{% endblocktrans %}</h4>
<p>{% blocktrans with provider.name as provider %}You are about to sign in using a third party account from {{ provider }}.{% endblocktrans %}</p>
{% endif %}
@ -19,10 +24,19 @@
<button class='btn btn-success sso-provider-link' type="submit"><span class='fas fa-sign-in-alt'></span>&nbsp;{% trans "Continue" %}</button>
</form>
{% else %}
<div class='alert alert-info alert-danger'>
<h4>{% trans "Invalid SSO Provider" %}</h4>
<p>
{% trans "The selected SSO provider is invalid, or has not been correctly configured" %}
</p>
</div>
{% endif %}
<hr>
<div>
<a href='{% url "account_login" %}'>
{% trans "Return to login page" %}
</a>
</div>
{% endblock content %}

View File

@ -1,22 +1,37 @@
{% load socialaccount %}
{% load i18n %}
{% load sso %}
{% get_providers as socialaccount_providers %}
{% if socialaccount_providers|length > 0 %}
<ul class='sso-provider-list'>
{% for provider in socialaccount_providers %}
{% sso_check_provider provider as provider_valid %}
<li class='sso-provider-link'>
{% if provider.id == "openid" %}
{% for brand in provider.get_brands %}
{% if provider.id == "openid" %}
{% for brand in provider.get_brands %}
<a title="{{ brand.name }}" brand_name='{{ provider.id }}'
class="btn btn-light socialaccount_provider {{ provider.id }} {{ brand.id }}"
href="{% provider_login_url provider.id openid=brand.openid_url process=process %}">
<span class='brand-icon' brand_name='{{ provider.id }}'></span> {{ brand.name }}</a>
{% endfor %}
{% endif %}
<span class='brand-icon' brand_name='{{ provider.id }}'></span> {{ brand.name }}
</a>
{% endfor %}
{% endif %}
<a title="{{ provider.name }}" brand_name='{{ provider.id }}'
class="btn btn-light socialaccount_provider {{ provider.id }}"
href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_params %}"
><span class='brand-icon' brand_name='{{ provider.id }}'></span> {{ provider.name }}</a>
class="btn btn-light socialaccount_provider {{ provider.id }}"
href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_params %}">
<span class='brand-icon' brand_name='{{ provider.id }}'></span> {{ provider.name }}
{% if not provider_valid %}
<span class='fas fa-exclamation-circle icon-red float-right' title='{% trans "Provider has not been configured" %}'></span>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
{% else %}
<div class='alert alert-block alert-warning'>
{% trans "No SSO providers have been configured" %}
</div>
{% endif %}