Projet

Général

Profil

« Précédent | Suivant » 

Révision b3843f12

Ajouté par Serghei Mihai il y a presque 9 ans

local accounts authentication (#7066)

Voir les différences:

uauth/backends.py
1
from .organization.models import LocalAccount
2
from datetime import datetime
3

  
4
class LocalAccountPasswordBackend(object):
5

  
6
    def authenticate(self, login, password, organization):
7
        try:
8
            account = LocalAccount.objects.get(username=login, active=True,
9
                                               organization=organization)
10
            if account.password == password:
11
                if not account.expired:
12
                    return account
13
        except LocalAccount.DoesNotExist:
14
            return None
uauth/settings.py
99 99

  
100 100
AUTHENTICATION_BACKENDS = global_settings.AUTHENTICATION_BACKENDS + (
101 101
    'mellon.backends.SAMLBackend',
102
    'uauth.backends.LocalAccountPasswordBackend',
102 103
)
103 104

  
104 105
MELLON_ATTRIBUTE_MAPPING = {
uauth/static/css/style.css
35 35
    border-bottom: 1px solid #bbb;
36 36
}
37 37

  
38
#login label {
39
    display: block;
40
}
41

  
38 42
.loginbox {
39 43
    width: 300px;
40 44
    margin: 0 auto;
uauth/utils.py
1 1
import os
2 2
import logging
3 3
import json
4
from uuid import uuid4
4 5

  
5 6
try:
6 7
    import ldap
......
42 43
        return
43 44
    return conn
44 45

  
45
def create_radius_user(username, password, **kwargs):
46
def create_radius_user(**kwargs):
47
    username = uuid4().get_hex()
48
    password = uuid4().get_hex()
46 49
    connection = get_ldap_connection()
47 50
    if connection:
48 51
        attrs = {'objectClass': ['radiusprofile', 'radiusObjectProfile'],
......
54 57
        dn = 'uid=%s,%s' % (username, settings.LDAP_CONF['dn'])
55 58
        logger.debug('creating new radius user: %s' % dn)
56 59
        connection.add_s(dn, ldif)
57
        return True
60
        return username, password
58 61
    else:
59 62
        return False
uauth/views.py
1 1
import json
2
from uuid import uuid4
3 2
import requests
4 3
from xml.etree import ElementTree
5 4

  
6 5
from django.views.generic.base import TemplateView
6
from django.views.generic import FormView
7 7
from django.views.decorators.csrf import csrf_exempt
8 8
from django.shortcuts import render_to_response
9 9
from django.core import signing
10 10
from django.http.request import QueryDict
11
from django.contrib.auth import authenticate
12
from django.utils.translation import ugettext_lazy as _
11 13

  
12 14
from mellon.views import LoginView as MellonLoginView
13 15

  
14
from .organization.models import Organization
16
from .organization.models import Organization, LocalAccount
15 17
from .forms import GuestLoginForm, VoucherLoginForm
16 18
from .utils import create_radius_user, is_organization_idp, \
17 19
    get_idp_list
......
22 24

  
23 25
homepage = HomeView.as_view()
24 26

  
27
class LoginMixin(object):
28
    def login(self, organization):
29
        context = {'organization': organization}
30
        result = create_radius_user()
31
        if result:
32
            username, password = result
33
            params = QueryDict(self.request.session[organization.slug], mutable=True)
34
            hotspot_url = organization.hotspot_url
35

  
36
            if 'login_url' in params:
37
                hotspot_url = params.pop('login_url')[0]
38

  
39
            context.update({'params':  params.urlencode(),
40
                            'hotspot_url': hotspot_url,
41
                            'data': {'username': username,
42
                                     'password': password}
43
                        })
44
            return render_to_response('uauth/%s_login_successful.html' % organization.hotspot_type,
45
                                          context)
46
        return render_to_response('uauth/login_failed.html', context)
47

  
25 48

  
26
class LoginView(MellonLoginView):
49
class LoginView(LoginMixin, MellonLoginView):
27 50

  
28 51
    def authenticate(self, request, login, attributes):
29 52
        relayState = signing.loads(login.msgRelayState)
......
41 64
            eduPersonTargetedID_NameQualifier = attributes['issuer']
42 65

  
43 66
        if is_organization_idp(eduPersonTargetedID_NameQualifier, organization):
44
            username = uuid4().get_hex()
45
            password = uuid4().get_hex()
46
            context = {'organization': organization}
47
            if create_radius_user(username, password):
48
                params = QueryDict(self.request.session[organization.slug], mutable=True)
49
                hotspot_url = organization.hotspot_url
50

  
51
                if 'login_url' in params:
52
                    hotspot_url = params.pop('login_url')[0]
53

  
54
                context.update({'params':  params.urlencode(),
55
                                'hotspot_url': hotspot_url,
56
                                'data': {'username': username,
57
                                         'password': password
58
                                     }
59
                            })
60
                return render_to_response('uauth/%s_login_successful.html' % organization.hotspot_type,
61
                                          context)
62
        return render_to_response('uauth/login_failed.html', context)
67
            return self.login(organization)
63 68

  
64 69
login = csrf_exempt(LoginView.as_view())
65 70

  
66 71

  
67
class OrganizationPageView(TemplateView):
72
class OrganizationPageView(LoginMixin, FormView):
73
    form_class = GuestLoginForm
68 74
    template_name = 'uauth/organization.html'
69 75

  
70 76
    def get_context_data(self, **kwargs):
71 77
        context = super(OrganizationPageView, self).get_context_data(**kwargs)
72 78
        idps = get_idp_list()
73
        organization = Organization.objects.get(slug=kwargs['organization_slug'])
79
        organization = Organization.objects.get(slug=self.kwargs['organization_slug'])
74 80
        self.request.session[organization.slug] = self.request.GET.urlencode()
75 81
        relay = signing.dumps({'organization': organization.slug})
76 82
        context.update({'idps': idps,
77
                        'guest_login_form': GuestLoginForm(),
78
                        'voucher_login_form': VoucherLoginForm(),
83
                        'guest_login_form': kwargs['form'],
79 84
                        'relay': relay,
80
                        'organization': organization
85
                        'organization': organization,
86
                        'voucher_login_form': VoucherLoginForm()
81 87
                        })
82 88
        return context
83 89

  
90
    def form_valid(self, form):
91
        data = form.cleaned_data
92
        organization = Organization.objects.get(slug=self.kwargs['organization_slug'])
93
        data.update({'organization': organization})
94
        user = authenticate(**data)
95
        if user:
96
            return self.login(organization)
97
        else:
98
            form.add_error(None, _('Unknown or inactive user'))
99
            return self.form_invalid(form)
100

  
84 101
organization = OrganizationPageView.as_view()

Formats disponibles : Unified diff