Projet

Général

Profil

0001-profile-add-csam-account-un-linking-capabilities-608.patch

Paul Marillonnet, 24 janvier 2022 16:56

Télécharger (6,78 ko)

Voir les différences:

Subject: [PATCH] profile: add csam account-(un)linking capabilities (#60837)

 src/authentic2_auth_fedict/authenticators.py  |  2 -
 src/authentic2_auth_fedict/backends.py        | 47 +++++++++++++++++++
 .../authentic2_auth_fedict/profile.html       | 18 +++++--
 src/authentic2_auth_fedict/urls.py            |  1 +
 src/authentic2_auth_fedict/views.py           | 15 +++++-
 5 files changed, 77 insertions(+), 6 deletions(-)
src/authentic2_auth_fedict/authenticators.py
49 49
    def profile(self, request, *args, **kwargs):
50 50
        context = kwargs.get('context', {}).copy()
51 51
        user_saml_identifiers = request.user.saml_identifiers.all()
52
        if not user_saml_identifiers:
53
            return ''
54 52
        for user_saml_identifier in user_saml_identifiers:
55 53
            user_saml_identifier.idp = get_idp(user_saml_identifier.issuer)
56 54
        context['user_saml_identifiers'] = user_saml_identifiers
src/authentic2_auth_fedict/backends.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 logging
18

  
17 19
import lasso
20
from django.contrib import messages
18 21
from mellon.backends import SAMLBackend
22
from mellon.utils import get_adapters, get_idp
23

  
24
logger = logging.getLogger(__name__)
19 25

  
20 26

  
21 27
class FedictBackend(SAMLBackend):
......
28 34
        # but we do not expose this detail to the service provider as all it
29 35
        # needs to know is "strong authentication".
30 36
        return lasso.SAML2_AUTHN_CONTEXT_SMARTCARD_PKI
37

  
38
    def authenticate(self, request=None, **credentials):
39
        saml_attributes = credentials.get('saml_attributes') or {}
40
        if 'issuer' not in saml_attributes:
41
            logger.debug('no idp in saml_attributes')
42
            return None
43
        idp = get_idp(saml_attributes['issuer'])
44
        if not idp:
45
            logger.debug('unknown idp %s', saml_attributes['issuer'])
46
            return None
47
        adapters = get_adapters(idp, request=request)
48
        for adapter in adapters:
49
            if not hasattr(adapter, 'authorize'):
50
                continue
51
            if not adapter.authorize(idp, saml_attributes):
52
                return
53
        for adapter in adapters:
54
            if hasattr(adapter, 'lookup_by_attributes'):
55
                user = adapter.lookup_by_attributes(idp, saml_attributes)
56
        for adapter in adapters:
57
            if not hasattr(adapter, 'lookup_user'):
58
                continue
59
            user = adapter.lookup_user(idp, saml_attributes)
60
            if user:
61
                request_user = getattr(request, 'user', None) if request else None
62
                if request_user != user and request_user.is_authenticated:
63
                    messages.warning(request, 'Le compte existe déjà, retour sur le compte actuel.')
64
                    saml_identifier = user.saml_identifier
65
                    saml_identifier.user = request_user
66
                    saml_identifier.save(update_fields=['user'])
67
                    user.mark_as_inactive(reason='fedict link to manually-created account')
68
                    user = request_user
69
                    user.saml_identifier = saml_identifier
70
                break
71
        else:  # no user found
72
            return
73
        for adapter in adapters:
74
            if not hasattr(adapter, 'provision'):
75
                continue
76
            adapter.provision(user, idp, saml_attributes)
77
        return user
src/authentic2_auth_fedict/templates/authentic2_auth_fedict/profile.html
1
<p>
2
Ce compte est relié à votre carte d'identité électronique.
3
</p>
1
{% load static %}
2
<div>
3
 <img src="{% static "authentic2_auth_fedict/img/beid_image_mini.png" %}" alt="">
4
{% if user_saml_identifiers %}
5
 <p>Ce compte est relié à votre carte d'identité électronique.</p>
6
 <a href="{% url "fedict-unlink" %}">Vous pouvez dé-lier votre compte de votre espace usager CSAM.</a>
7
{% else %}
8
 <p>
9
 Vous pouvez lier votre compte Publik à votre eID. Pour effectuer cette
10
 liaison, vous avez besoin de votre carte d'identité électronique (eID) et
11
 d'un lecteur de carte, ou de votre liste de codes personnels (token).
12
 </p>
13
 <a href="{% url "fedict-login" %}?next=/accounts/">Initier la liaison</a>
14
{% endif %}
15
</div>
src/authentic2_auth_fedict/urls.py
21 21
urlpatterns = [
22 22
    url(r'^accounts/saml/', include('mellon.urls')),
23 23
    url(r'^accounts/fedict/login/$', views.login, name='fedict-login'),
24
    url(r'^accounts/fedict/unlink/$', views.unlink, name='fedict-unlink'),
24 25
]
src/authentic2_auth_fedict/views.py
18 18
import urllib.parse
19 19

  
20 20
from django.conf import settings
21
from django.contrib import messages
21 22
from django.core import signing
22 23
from django.db import transaction
23 24
from django.http import HttpResponseRedirect
24
from django.shortcuts import resolve_url
25
from django.shortcuts import redirect, resolve_url
25 26
from django.urls import reverse
26 27
from django.views.decorators.csrf import csrf_exempt
27 28
from django.views.generic import View
......
69 70

  
70 71

  
71 72
login = transaction.non_atomic_requests(csrf_exempt(LoginView.as_view()))
73

  
74

  
75
def unlink(request):
76
    if not hasattr(request, 'user') or not hasattr(request.user, 'saml_identifiers'):
77
        return
78
    unlink_performed = False
79
    for saml_identifier in request.user.saml_identifiers.all():
80
        saml_identifier.delete()
81
        unlink_performed = True
82
    if unlink_performed:
83
        messages.success(request, message='Dé-liaison effectuée.')
84
    return redirect('account_management')
72
-