local accounts authentication (#7066)

This commit is contained in:
Serghei Mihai 2015-04-30 18:15:50 +02:00
parent 41862ed39d
commit b3843f123f
5 changed files with 68 additions and 29 deletions

14
uauth/backends.py Normal file
View File

@ -0,0 +1,14 @@
from .organization.models import LocalAccount
from datetime import datetime
class LocalAccountPasswordBackend(object):
def authenticate(self, login, password, organization):
try:
account = LocalAccount.objects.get(username=login, active=True,
organization=organization)
if account.password == password:
if not account.expired:
return account
except LocalAccount.DoesNotExist:
return None

View File

@ -99,6 +99,7 @@ LDAP_CONF = {
AUTHENTICATION_BACKENDS = global_settings.AUTHENTICATION_BACKENDS + (
'mellon.backends.SAMLBackend',
'uauth.backends.LocalAccountPasswordBackend',
)
MELLON_ATTRIBUTE_MAPPING = {

View File

@ -35,6 +35,10 @@ ul.login li, #guest-login ul li, #voucher-login ul li, .loginbox li {
border-bottom: 1px solid #bbb;
}
#login label {
display: block;
}
.loginbox {
width: 300px;
margin: 0 auto;

View File

@ -1,6 +1,7 @@
import os
import logging
import json
from uuid import uuid4
try:
import ldap
@ -42,7 +43,9 @@ def get_ldap_connection(conf=settings.LDAP_CONF):
return
return conn
def create_radius_user(username, password, **kwargs):
def create_radius_user(**kwargs):
username = uuid4().get_hex()
password = uuid4().get_hex()
connection = get_ldap_connection()
if connection:
attrs = {'objectClass': ['radiusprofile', 'radiusObjectProfile'],
@ -54,6 +57,6 @@ def create_radius_user(username, password, **kwargs):
dn = 'uid=%s,%s' % (username, settings.LDAP_CONF['dn'])
logger.debug('creating new radius user: %s' % dn)
connection.add_s(dn, ldif)
return True
return username, password
else:
return False

View File

@ -1,17 +1,19 @@
import json
from uuid import uuid4
import requests
from xml.etree import ElementTree
from django.views.generic.base import TemplateView
from django.views.generic import FormView
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render_to_response
from django.core import signing
from django.http.request import QueryDict
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _
from mellon.views import LoginView as MellonLoginView
from .organization.models import Organization
from .organization.models import Organization, LocalAccount
from .forms import GuestLoginForm, VoucherLoginForm
from .utils import create_radius_user, is_organization_idp, \
get_idp_list
@ -22,8 +24,29 @@ class HomeView(TemplateView):
homepage = HomeView.as_view()
class LoginMixin(object):
def login(self, organization):
context = {'organization': organization}
result = create_radius_user()
if result:
username, password = result
params = QueryDict(self.request.session[organization.slug], mutable=True)
hotspot_url = organization.hotspot_url
class LoginView(MellonLoginView):
if 'login_url' in params:
hotspot_url = params.pop('login_url')[0]
context.update({'params': params.urlencode(),
'hotspot_url': hotspot_url,
'data': {'username': username,
'password': password}
})
return render_to_response('uauth/%s_login_successful.html' % organization.hotspot_type,
context)
return render_to_response('uauth/login_failed.html', context)
class LoginView(LoginMixin, MellonLoginView):
def authenticate(self, request, login, attributes):
relayState = signing.loads(login.msgRelayState)
@ -41,44 +64,38 @@ class LoginView(MellonLoginView):
eduPersonTargetedID_NameQualifier = attributes['issuer']
if is_organization_idp(eduPersonTargetedID_NameQualifier, organization):
username = uuid4().get_hex()
password = uuid4().get_hex()
context = {'organization': organization}
if create_radius_user(username, password):
params = QueryDict(self.request.session[organization.slug], mutable=True)
hotspot_url = organization.hotspot_url
if 'login_url' in params:
hotspot_url = params.pop('login_url')[0]
context.update({'params': params.urlencode(),
'hotspot_url': hotspot_url,
'data': {'username': username,
'password': password
}
})
return render_to_response('uauth/%s_login_successful.html' % organization.hotspot_type,
context)
return render_to_response('uauth/login_failed.html', context)
return self.login(organization)
login = csrf_exempt(LoginView.as_view())
class OrganizationPageView(TemplateView):
class OrganizationPageView(LoginMixin, FormView):
form_class = GuestLoginForm
template_name = 'uauth/organization.html'
def get_context_data(self, **kwargs):
context = super(OrganizationPageView, self).get_context_data(**kwargs)
idps = get_idp_list()
organization = Organization.objects.get(slug=kwargs['organization_slug'])
organization = Organization.objects.get(slug=self.kwargs['organization_slug'])
self.request.session[organization.slug] = self.request.GET.urlencode()
relay = signing.dumps({'organization': organization.slug})
context.update({'idps': idps,
'guest_login_form': GuestLoginForm(),
'voucher_login_form': VoucherLoginForm(),
'guest_login_form': kwargs['form'],
'relay': relay,
'organization': organization
'organization': organization,
'voucher_login_form': VoucherLoginForm()
})
return context
def form_valid(self, form):
data = form.cleaned_data
organization = Organization.objects.get(slug=self.kwargs['organization_slug'])
data.update({'organization': organization})
user = authenticate(**data)
if user:
return self.login(organization)
else:
form.add_error(None, _('Unknown or inactive user'))
return self.form_invalid(form)
organization = OrganizationPageView.as_view()