Projet

Général

Profil

0001-franceconnect-remove-app-65845.patch

Valentin Deniaud, 14 juin 2022 11:38

Télécharger (14,6 ko)

Voir les différences:

Subject: [PATCH] franceconnect: remove app (#65845)

 hobo/franceconnect/forms.py                   |  61 --------
 .../templates/hobo/franceconnect_disable.html |  20 ---
 .../templates/hobo/franceconnect_enable.html  |  20 ---
 .../templates/hobo/franceconnect_home.html    |  32 +----
 hobo/franceconnect/urls.py                    |   2 -
 hobo/franceconnect/views.py                   | 132 +-----------------
 tests/test_franceconnect.py                   |  67 ---------
 7 files changed, 4 insertions(+), 330 deletions(-)
 delete mode 100644 hobo/franceconnect/forms.py
 delete mode 100644 hobo/franceconnect/templates/hobo/franceconnect_disable.html
 delete mode 100644 hobo/franceconnect/templates/hobo/franceconnect_enable.html
 delete mode 100644 tests/test_franceconnect.py
hobo/franceconnect/forms.py
1
# hobo - portal to configure and deploy applications
2
# Copyright (C) 2015-2019  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from django import forms
18
from django.utils.translation import ugettext_lazy as _
19

  
20

  
21
class SettingsForm(forms.Form):
22
    platform = forms.ChoiceField(
23
        label=_('Platform'),
24
        choices=[
25
            ('prod', _('Production')),
26
            ('test', _('Integration')),
27
        ],
28
    )
29
    client_id = forms.CharField(
30
        label=_('Client ID'),
31
        help_text=_(
32
            'See <a href="https://partenaires.franceconnect.gouv.fr/fcp/fournisseur-service">'
33
            'FranceConnect partners site</a> for getting client ID and secret.'
34
        ),
35
        widget=forms.TextInput(attrs={'size': 64}),
36
    )
37
    client_secret = forms.CharField(label=_('Client Secret'), widget=forms.TextInput(attrs={'size': 64}))
38
    scopes = forms.MultipleChoiceField(
39
        label=_('Scopes'),
40
        choices=[
41
            ('given_name', _('given name (given_name)')),
42
            ('gender', _('gender (gender)')),
43
            ('birthdate', _('birthdate (birthdate)')),
44
            ('birthcountry', _('birthcountry (birthcountry)')),
45
            ('birthplace', _('birthplace (birthplace)')),
46
            ('family_name', _('family name (family_name)')),
47
            ('email', _('email (email)')),
48
            ('preferred_username', _('usual family name (preferred_username)')),
49
            ('address', _('address (address)')),
50
            ('phone', _('phone (phone)')),
51
            ('identite_pivot', _('identite_pivot (identite_pivot)')),
52
            ('profile', _('profile (profile)')),
53
            ('birth', _('birth profile (birth)')),
54
        ],
55
        widget=forms.CheckboxSelectMultiple,
56
        help_text=_('These scopes will be requested in addition to openid'),
57
    )
58

  
59

  
60
class EnableForm(forms.Form):
61
    pass
hobo/franceconnect/templates/hobo/franceconnect_disable.html
1
{% extends "hobo/franceconnect_home.html" %}
2
{% load i18n %}
3

  
4
{% block appbar %}
5
  <h2>FranceConnect</h2>
6
{% endblock %}
7

  
8
{% block content %}
9
<form method="post">
10
{% csrf_token %}
11
<p>
12
{% trans "Are you sure you want to disable FranceConnect support?" %}
13
{{ form.as_p }}
14
<div class="buttons">
15
<button class="submit-button">{% trans "Disable" %}</button>
16
<a class="cancel" href="{% url 'franceconnect-home' %}">{% trans "Cancel" %}</a>
17
</div>
18
</form>
19

  
20
{% endblock %}
hobo/franceconnect/templates/hobo/franceconnect_enable.html
1
{% extends "hobo/franceconnect_home.html" %}
2
{% load i18n %}
3

  
4
{% block appbar %}
5
  <h2>FranceConnect</h2>
6
{% endblock %}
7

  
8
{% block content %}
9
<form method="post">
10
{% csrf_token %}
11
<p>
12
{% trans "Are you sure you want to enable FranceConnect support?" %}
13
{{ form.as_p }}
14
<div class="buttons">
15
<button class="submit-button">{% trans "Enable" %}</button>
16
<a class="cancel" href="{% url 'franceconnect-home' %}">{% trans "Cancel" %}</a>
17
</div>
18
</form>
19

  
20
{% endblock %}
hobo/franceconnect/templates/hobo/franceconnect_home.html
8 8

  
9 9
{% block appbar %}
10 10
  <h2>{% trans 'FranceConnect' %}</h2>
11
  {% if enabled %}
12
  <span class="actions">
13
  <a rel="popup" href="{% url 'franceconnect-disable' %}">{% trans 'Disable' %}</a>
14
  </span>
15
  {% endif %}
16 11
{% endblock %}
17 12

  
18 13
{% block content %}
19 14

  
20
<div class="infonotice">
21
  {% blocktrans %}
22
  FranceConnect is the solution proposed by the French state to streamline
23
  logging in online services.
24
 {% endblocktrans %}
15
<div class="warningnotice">
16
  {% trans "FranceConnect configuration should be handled there:" %} <a href="{{ idp_url }}manage/authenticators/">{{ idp_url }}manage/authenticators/</a>
25 17
</div>
26 18

  
27
{% if not enabled %}
28
<p>
29
 {% trans "Support is currently disabled." %}
30
</p>
31
<p>
32
 <a class="button" rel="popup" href="{% url 'franceconnect-enable' %}">{% trans 'Enable' %}</a>
33
</p>
34
{% else %}
35

  
36
<form method="post">
37
{% csrf_token %}
38
{{ form.as_p }}
39

  
40
<div class="buttons">
41
<button class="submit-button">{% trans "Save" %}</button>
42
</div>
43
</form>
44

  
45
{% endif %}
46

  
47 19
{% endblock %}
hobo/franceconnect/urls.py
20 20

  
21 21
urlpatterns = [
22 22
    url(r'^$', views.home, name='franceconnect-home'),
23
    url(r'^enable$', views.enable, name='franceconnect-enable'),
24
    url(r'^disable$', views.disable, name='franceconnect-disable'),
25 23
]
hobo/franceconnect/views.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import json
17
from django.views.generic import TemplateView
18 18

  
19
from django.urls import reverse_lazy
20
from django.views.generic import FormView
21 19

  
22
from hobo.environment.models import Authentic
23
from hobo.environment.utils import get_setting_variable
24

  
25
from .forms import EnableForm, SettingsForm
26

  
27

  
28
def get_variable(setting_name):
29
    return get_setting_variable(setting_name, service=Authentic.objects.get(secondary=False))
30

  
31

  
32
PLATFORMS = {
33
    'test': {
34
        'A2_FC_AUTHORIZE_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize',
35
        'A2_FC_TOKEN_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/token',
36
        'A2_FC_USERINFO_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/userinfo',
37
        'A2_FC_LOGOUT_URL': 'https://fcp.integ01.dev-franceconnect.fr/api/v1/logout',
38
    },
39
    'prod': {
40
        'A2_FC_AUTHORIZE_URL': 'https://app.franceconnect.gouv.fr/api/v1/authorize',
41
        'A2_FC_TOKEN_URL': 'https://app.franceconnect.gouv.fr/api/v1/token',
42
        'A2_FC_USERINFO_URL': 'https://app.franceconnect.gouv.fr/api/v1/userinfo',
43
        'A2_FC_LOGOUT_URL': 'https://app.franceconnect.gouv.fr/api/v1/logout',
44
    },
45
}
46

  
47

  
48
class HomeView(FormView):
20
class HomeView(TemplateView):
49 21
    template_name = 'hobo/franceconnect_home.html'
50
    form_class = SettingsForm
51
    success_url = reverse_lazy('franceconnect-home')
52

  
53
    def get_initial(self):
54
        initial = super(HomeView, self).get_initial()
55
        authorize_url = get_variable('A2_FC_AUTHORIZE_URL').value
56
        if authorize_url == 'https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize':
57
            initial['platform'] = 'test'
58
        elif authorize_url == 'https://app.franceconnect.gouv.fr/api/v1/authorize':
59
            initial['platform'] = 'prod'
60

  
61
        initial['client_id'] = get_variable('A2_FC_CLIENT_ID').value
62
        initial['client_secret'] = get_variable('A2_FC_CLIENT_SECRET').value
63
        initial['scopes'] = get_variable('A2_FC_SCOPES').json or ['profile', 'email']
64

  
65
        return initial
66

  
67
    def form_valid(self, form):
68
        for key, value in PLATFORMS[form.cleaned_data['platform']].items():
69
            variable = get_variable(key)
70
            variable.value = value
71
            variable.save()
72

  
73
        variable = get_variable('A2_FC_CLIENT_ID')
74
        variable.value = form.cleaned_data['client_id']
75
        variable.save()
76

  
77
        variable = get_variable('A2_FC_CLIENT_SECRET')
78
        variable.value = form.cleaned_data['client_secret']
79
        variable.save()
80

  
81
        variable = get_variable('A2_FC_VERIFY_CERTIFICATE')
82
        variable.value = 'true'
83
        variable.save()
84

  
85
        variable = get_variable('A2_FC_USER_INFO_MAPPINGS')
86
        variable.value = json.dumps(
87
            {
88
                'last_name': {
89
                    'ref': 'family_name',
90
                    'verified': True,
91
                },
92
                'first_name': {
93
                    'ref': 'given_name',
94
                    'verified': True,
95
                },
96
                'title': {
97
                    'ref': 'gender',
98
                    'translation': 'simple',
99
                    'translation_simple': {
100
                        'male': 'Monsieur',
101
                        'female': 'Madame',
102
                    },
103
                    'verified': True,
104
                },
105
                'email': 'email',
106
            }
107
        )
108
        variable.save()
109

  
110
        variable = get_variable('A2_FC_SCOPES')
111
        variable.json = form.cleaned_data['scopes']
112
        variable.save()
113

  
114
        return super(HomeView, self).form_valid(form)
115

  
116
    def get_context_data(self, **kwargs):
117
        context = super(HomeView, self).get_context_data(**kwargs)
118
        context['enabled'] = bool(get_variable('A2_FC_ENABLE').json)
119
        return context
120 22

  
121 23

  
122 24
home = HomeView.as_view()
123

  
124

  
125
class EnableView(FormView):
126
    form_class = EnableForm
127
    template_name = 'hobo/franceconnect_enable.html'
128
    success_url = reverse_lazy('franceconnect-home')
129

  
130
    def form_valid(self, form):
131
        variable = get_variable('A2_FC_ENABLE')
132
        variable.value = 'true'
133
        variable.save()
134
        return super(EnableView, self).form_valid(form)
135

  
136

  
137
enable = EnableView.as_view()
138

  
139

  
140
class DisableView(FormView):
141
    form_class = EnableForm
142
    template_name = 'hobo/franceconnect_disable.html'
143
    success_url = reverse_lazy('franceconnect-home')
144

  
145
    def form_valid(self, form):
146
        variable = get_variable('A2_FC_ENABLE')
147
        variable.value = 'false'
148
        variable.save()
149
        return super(DisableView, self).form_valid(form)
150

  
151

  
152
disable = DisableView.as_view()
tests/test_franceconnect.py
1
# hobo - portal to configure and deploy applications
2
# Copyright (C) 2015-2019  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
from test_manager import login
18

  
19
from hobo.environment.models import Authentic, Variable
20
from hobo.franceconnect.views import PLATFORMS
21

  
22

  
23
def test_franceconnect(app, admin_user):
24
    Authentic.objects.create(title='bar', slug='bar', base_url='http://bar.example.net')
25
    login(app)
26

  
27
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC').count() == 0
28

  
29
    response = app.get('/franceconnect/')
30

  
31
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC').count() == 0
32
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC_ENABLE', value='true').count() == 0
33

  
34
    response = response.click('Enable')
35

  
36
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC').count() == 0
37
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC_ENABLE', value='true').count() == 0
38

  
39
    response = response.form.submit().follow()
40

  
41
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC').count() == 1
42
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC_ENABLE', value='true').count() == 1
43

  
44
    response.form.set('platform', 'prod')
45
    response.form.set('client_id', 'xyz')
46
    response.form.set('client_secret', '1234')
47
    response = response.form.submit().follow()
48

  
49
    assert Variable.objects.filter(name__startswith='SETTING_A2_FC').count() == 10
50

  
51
    for key, value in PLATFORMS['prod'].items():
52
        assert Variable.objects.filter(name='SETTING_' + key, value=value).count() == 1
53

  
54
    assert Variable.objects.get(name='SETTING_A2_FC_USER_INFO_MAPPINGS').json == {
55
        "last_name": {"ref": "family_name", "verified": True},
56
        "first_name": {
57
            "ref": "given_name",
58
            "verified": True,
59
        },
60
        "title": {
61
            "ref": "gender",
62
            "translation": "simple",
63
            "translation_simple": {"male": "Monsieur", "female": "Madame"},
64
            "verified": True,
65
        },
66
        "email": "email",
67
    }
68
-