misc: add a page to configure FranceConnect (#29642)

This commit is contained in:
Frédéric Péters 2019-01-10 15:31:11 +01:00
parent 5b05a6ff99
commit f42fdf1b0d
11 changed files with 277 additions and 0 deletions

View File

@ -1,5 +1,6 @@
recursive-include hobo/static *.css *.png *.js
recursive-include hobo/templates *.html *.txt
recursive-include hobo/franceconnect/templates *.html *.txt
recursive-include hobo/profile/templates *.html *.txt
recursive-include hobo/theme/templates *.html *.txt
recursive-include hobo/environment/templates *.html *.txt

View File

View File

@ -0,0 +1,39 @@
# hobo - portal to configure and deploy applications
# Copyright (C) 2015-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django import forms
from django.utils.translation import ugettext_lazy as _
class SettingsForm(forms.Form):
platform = forms.ChoiceField(
label=_('Platform'),
choices=[
('prod', _('Production')),
('test', _('Integration')),
])
client_id = forms.CharField(
label=_('Client ID'),
help_text=_('See <a href="https://franceconnect.gouv.fr/fournisseur-service">'
'FranceConnect partners site</a> for getting client ID and secret.'),
widget=forms.TextInput(attrs={'size': 64}))
client_secret = forms.CharField(
label=_('Client Secret'),
widget=forms.TextInput(attrs={'size': 64}))
class EnableForm(forms.Form):
pass

View File

@ -0,0 +1,20 @@
{% extends "hobo/franceconnect_home.html" %}
{% load i18n %}
{% block appbar %}
<h2>FranceConnect</h2>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
<p>
{% trans "Are you sure you want to disable FranceConnect support?" %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans "Disable" %}</button>
<a class="cancel" href="{% url 'franceconnect-home' %}">{% trans "Cancel" %}</a>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "hobo/franceconnect_home.html" %}
{% load i18n %}
{% block appbar %}
<h2>FranceConnect</h2>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
<p>
{% trans "Are you sure you want to enable FranceConnect support?" %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans "Enable" %}</button>
<a class="cancel" href="{% url 'franceconnect-home' %}">{% trans "Cancel" %}</a>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,47 @@
{% extends "hobo/base.html" %}
{% load i18n %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'franceconnect-home' %}">FranceConnect</a>
{% endblock %}
{% block appbar %}
<h2>{% trans 'FranceConnect' %}</h2>
{% if enabled %}
<span class="actions">
<a rel="popup" href="{% url 'franceconnect-disable' %}">{% trans 'Disable' %}</a>
</span>
{% endif %}
{% endblock %}
{% block content %}
<div class="infonotice">
{% blocktrans %}
FranceConnect is the solution proposed by the French state to streamline
logging in online services.
{% endblocktrans %}
</div>
{% if not enabled %}
<p>
{% trans "Support is currently disabled." %}
</p>
<p>
<a class="button" rel="popup" href="{% url 'franceconnect-enable' %}">Enable</a>
</p>
{% else %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="buttons">
<button class="submit-button">{% trans "Save" %}</button>
</div>
</form>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,25 @@
# hobo - portal to configure and deploy applications
# Copyright (C) 2015-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='franceconnect-home'),
url(r'^enable$', views.enable, name='franceconnect-enable'),
url(r'^disable$', views.disable, name='franceconnect-disable'),
]

120
hobo/franceconnect/views.py Normal file
View File

@ -0,0 +1,120 @@
# hobo - portal to configure and deploy applications
# Copyright (C) 2015-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.core.urlresolvers import reverse_lazy
from django.views.generic import RedirectView, FormView
from hobo.environment.models import Variable, Authentic
from .forms import SettingsForm, EnableForm
def get_variable(name):
variable, created = Variable.objects.get_or_create(
name='SETTING_' + name,
defaults={
'auto': True,
'service': Authentic.objects.get(secondary=False),
})
return variable
class HomeView(FormView):
template_name = 'hobo/franceconnect_home.html'
form_class = SettingsForm
success_url = reverse_lazy('franceconnect-home')
def get_initial(self):
initial = super(HomeView, self).get_initial()
authorize_url = get_variable('A2_FC_AUTHORIZE_URL').value
if authorize_url == 'https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize':
initial['platform'] = 'test'
elif authorize_url == 'https://app.franceconnect.gouv.fr/api/v1/authorize':
initial['platform'] = 'prod'
initial['client_id'] = get_variable('A2_FC_CLIENT_ID').value
initial['client_secret'] = get_variable('A2_FC_CLIENT_SECRET').value
return initial
def form_valid(self, form):
platforms = {
'test': {
'A2_FC_AUTHORIZE_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize',
'A2_FC_TOKEN_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/token',
'A2_FC_USERINFO_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/userinfo',
'A2_FC_LOGOUT_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/logout',
},
'prod': {
'A2_FC_AUTHORIZE_URL': 'https://app.franceconnect.gouv.fr/api/v1/authorize',
'A2_FC_TOKEN_URL': 'https://app.franceconnect.gouv.fr/api/v1/token',
'A2_FC_USERINFO_URL': 'https://app.franceconnect.gouv.fr/api/v1/userinfo',
'A2_FC_LOGOUT_URL': 'https://app.franceconnect.gouv.fr/api/v1/logout',
}
}
for key, value in platforms[form.cleaned_data['platform']].items():
variable = get_variable(key)
variable.value = value
variable.save()
variable = get_variable('A2_FC_CLIENT_ID')
variable.value = form.cleaned_data['client_id']
variable.save()
variable = get_variable('A2_FC_CLIENT_SECRET')
variable.value = form.cleaned_data['client_secret']
variable.save()
variable = get_variable('A2_FC_VERIFY_CERTIFICATE')
variable.value = 'true'
variable.save()
return super(HomeView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(HomeView, self).get_context_data(**kwargs)
context['enabled'] = bool(get_variable('A2_FC_ENABLE').json)
return context
home = HomeView.as_view()
class EnableView(FormView):
form_class = EnableForm
template_name = 'hobo/franceconnect_enable.html'
success_url = reverse_lazy('franceconnect-home')
def form_valid(self, form):
variable = get_variable('A2_FC_ENABLE')
variable.value = 'true'
variable.save()
return super(EnableView, self).form_valid(form)
enable = EnableView.as_view()
class DisableView(FormView):
form_class = EnableForm
template_name = 'hobo/franceconnect_disable.html'
success_url = reverse_lazy('franceconnect-home')
def form_valid(self, form):
variable = get_variable('A2_FC_ENABLE')
variable.value = 'false'
variable.save()
return super(DisableView, self).form_valid(form)
disable = DisableView.as_view()

View File

@ -40,6 +40,7 @@ INSTALLED_APPS = (
'mellon',
'gadjo',
'hobo.environment',
'hobo.franceconnect',
'hobo.profile',
'hobo.theme',
'hobo.emails',

View File

@ -9,6 +9,7 @@
<li><a href="{% url 'profile-home' %}">{% trans 'User Profile' %}</a></li>
<li><a href="{% url 'theme-home' %}">{% trans 'Theme' %}</a></li>
<li><a href="{% url 'emails-home' %}">{% trans 'Emails' %}</a></li>
<li><a href="{% url 'franceconnect-home' %}">FranceConnect</a></li>
<li><a href="{% url 'environment-home' %}">{% trans 'Services' %}</a></li>
<li><a href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a></li>
</ul>

View File

@ -7,6 +7,7 @@ admin.autodiscover()
from .views import admin_required, login, login_local, logout, home, health_json, menu_json, hobo
from .urls_utils import decorated_includes
from .environment.urls import urlpatterns as environment_urls
from .franceconnect.urls import urlpatterns as franceconnect_urls
from .profile.urls import urlpatterns as profile_urls
from .theme.urls import urlpatterns as theme_urls
from .emails.urls import urlpatterns as emails_urls
@ -17,6 +18,8 @@ urlpatterns = [
include(environment_urls))),
url(r'^profile/', decorated_includes(admin_required,
include(profile_urls))),
url(r'^franceconnect/',
decorated_includes(admin_required, include(franceconnect_urls))),
url(r'^theme/', decorated_includes(admin_required,
include(theme_urls))),
url(r'^emails/', decorated_includes(admin_required, include(emails_urls))),