forms work and are saved to ldap correctly, added RFID form

This commit is contained in:
Uwe Kamper 2013-10-24 21:27:15 +02:00
parent 0aade5be94
commit 8fdc6064fa
14 changed files with 317 additions and 240 deletions

109
account/cbase_members.py Normal file
View file

@ -0,0 +1,109 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ldap
import copy
from django.conf import settings
"""
Example configuration:
CBASE_LDAP_URL = 'ldap://lea.cbrp3.c-base.org:389/'
CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org'
"""
def retrieve_member(request):
# TODO: Put password in encrypted session storage
return MemberValues(request.user.username, request.session['ldap_password'])
class MemberValues(object):
"""
Dictionary-like abstraction of the c-base member attributes.
"""
def __init__(self, username, password):
self._username = username
self._password = password
self._old = self._get_user_values()
# Make a complete copy of the old values so we can later check
# which
self._new = copy.deepcopy(self._old)
def get(self, key, default=None):
value = self._new.get(key, default)[0]
if value == 'TRUE':
return True
elif value == 'FALSE':
return False
else:
return value
def set(self, key, value):
converted_value = value
if isinstance(value, bool):
if value == True:
converted_value = 'TRUE'
else:
converted_value = 'FALSE'
self._new[key] = [converted_value.encode('latin-1')]
def save(self):
"""
Save the values back to the LDAP server.
"""
dn = "uid=%s,ou=crew,dc=c-base,dc=org" % self._username
print 'setting dn=', dn
# TODO: Use settings for url
l = ldap.initialize("ldap://lea.cbrp3.c-base.org:389/")
l.simple_bind_s(dn, self._password)
mod_attrs = []
for new_key, new_value in self._new.items():
# Replace is the default.
action = ldap.MOD_REPLACE
if new_key not in self._old.keys():
action = ldap.MOD_ADD
mod_attrs.append((action, '%s' % new_key, new_value ))
continue
# Set the attribute and wait for the LDAP server to complete.
if self._old[new_key][0] != new_value[0]:
action = ldap.MOD_REPLACE
mod_attrs.append((action, '%s' % new_key, new_value ))
continue
print "modattrs: ",mod_attrs
result = l.modify_s(dn, mod_attrs)
print "result is: ", result
def _get_bind_dn(self):
"""
Adds the uid=userid, to the base dn and returns that.
"""
bind_dn = 'uid=%s,' % self._username
bind_dn += settings.CBASE_BASE_DN
return bind_dn
def _get_user_values(self):
"""
Get an attribute from the ldap storage.
"""
# Create a new LDAP bind (aka connection or session)
session = ldap.initialize(settings.CBASE_LDAP_URL)
session.simple_bind_s(self._get_bind_dn(), self._password)
# Set the attribute and wait for the LDAP server to complete.
searchScope = ldap.SCOPE_SUBTREE
# retrieve all attributes
retrieveAttributes = None
searchFilter = "uid=%s" % self._username
dn = settings.CBASE_BASE_DN
result = session.search_s(dn, searchScope, searchFilter, retrieveAttributes)
# TODO: latin1
print "result is: ", result
# TODO: if len(result)==0
return result[0][1]

View file

@ -1,7 +1,45 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
from django import forms from django import forms
from django.utils.translation import ugettext as _
class LoginForm(forms.Form): class LoginForm(forms.Form):
username = forms.CharField(max_length=255) username = forms.CharField(max_length=255)
password = forms.CharField(max_length=255, widget=forms.PasswordInput) password = forms.CharField(max_length=255, widget=forms.PasswordInput)
class GastroPinField(forms.CharField):
def validate(self, value):
"""
Check if the value is all numeric and 4 - 6 chars long.
"""
match = re.match(r'^\d{4,6}$', value)
if not match:
raise forms.ValidationError(_('PIN must be 4 to 6 digits.'))
class GastroPinForm(forms.Form):
gastropin = GastroPinField()
class WlanPresenceForm(forms.Form):
# Boolean fields must never be required.
presence = forms.BooleanField(required=False,
help_text=_('Enable WiFi presence?'))
class PaswordForm(forms.Form):
password1 = forms.CharField(max_length=255, widget=forms.PasswordInput,
help_text=_('New password'))
password2 = forms.CharField(max_length=255, widget=forms.PasswordInput,
help_text=_('Repeat password'))
class RFIDForm(forms.Form):
rfid = forms.CharField(max_length=255, help_text=_('Your RFID'))

View file

@ -0,0 +1,18 @@
{% extends "base.html" %}
{% load i18n %}
{% block container %}
<div class="row">
<div class="span12">
<h2>{% block form_title %}{% endblock %}</h2>
{% block form_description %}{% endblock %}
{% if message %}
<div class="alert alert-success">{{ message }}</div>
{% endif %}
{% block form_fields %}{% endblock form_fields %}
</div>
</div>
{% endblock container %}

View file

@ -0,0 +1,23 @@
{% extends "form_base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block form_title %}{% trans "RFID"%}{% endblock %}
{% block form_description %}
<p>{% blocktrans %}Blabla testblab bla bla blub{% endblocktrans %}</p>
{% endblock %}
{% block form_fields %}
{{ form.non_field_errors }}
<form action="{% url account.views.rfid %}" method="post" class="form-horizontal well">
{% csrf_token %}
{{ form|crispy }}
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
{% endblock form_fields %}

View file

@ -0,0 +1,25 @@
{% extends "form_base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block form_title %}{% trans "WiFi Presence"%}{% endblock %}
{% block form_description %}
<p>{% blocktrans %}The WiFi Presence automatically logs you in
to the c-base presence system when you connect a device to the Crew-Wifi
(SSID: c-base-crew) with your username and password.{% endblocktrans %}</p>
{% endblock %}
{% block form_fields %}
{{ form.non_field_errors }}
<form action="{% url account.views.wlan_presence %}" method="post" class="form-horizontal well">
{% csrf_token %}
{{ form|crispy }}
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
{% endblock form_fields %}

View file

@ -5,4 +5,8 @@ urlpatterns = patterns(
'', '',
url(r'^login/$', 'account.views.auth_login', name="auth_login"), url(r'^login/$', 'account.views.auth_login', name="auth_login"),
url(r'^logout/$', 'account.views.auth_logout', name="auth_logout"), url(r'^logout/$', 'account.views.auth_logout', name="auth_logout"),
url(r'^gastropin/$', 'account.views.gastropin', name='gastropin'),
url(r'^wlan_presence/$', 'account.views.wlan_presence', name='wlan_presence'),
url(r'^rfid/$', 'account.views.rfid', name='rfid'),
url(r'^groups/(?P<group_name>[^/]+)/', 'account.views.groups_list'),
) )

View file

@ -6,8 +6,14 @@ from django.shortcuts import render_to_response
from django.template.context import RequestContext from django.template.context import RequestContext
from django.contrib.auth import login, logout, authenticate from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.shortcuts import render
from django.utils.translation import ugettext as _
from account.forms import LoginForm from forms import GastroPinForm, WlanPresenceForm, LoginForm, PaswordForm, RFIDForm
from cbase_members import MemberValues, retrieve_member
def auth_login(request): def auth_login(request):
redirect_to = request.GET.get('next', '') or '/' redirect_to = request.GET.get('next', '') or '/'
@ -43,3 +49,83 @@ def auth_logout(request):
response = HttpResponseRedirect(redirect_to) response = HttpResponseRedirect(redirect_to)
response.delete_cookie('sessionkey') response.delete_cookie('sessionkey')
return response return response
def landingpage(request):
is_ceymaster = is_admin = False
if 'ceymaster' in [g.name for g in request.user.groups.all()]:
is_ceymaster = True
if 'ldap_admins' in [g.name for g in request.user.groups.all()]:
is_admin = True
groups = Group.objects.all()
admins = Group.objects.get(name="ldap_admins").user_set.all()
if request.user.is_authenticated():
# values = get_user_values(request.user.username, request.session['ldap_password'])
return render_to_response("dashboard.html", locals())
return render_to_response("base.html", locals())
@login_required(redirect_field_name="/" ,login_url="/account/login/")
def groups_list(request, group_name):
group = get_object_or_404(Group, name=group_name)
groups = Group.objects.all()
if 'ceymaster' in [g.name for g in request.user.groups.all()]:
is_ceymaster = True
if 'ldap_admins' in [g.name for g in request.user.groups.all()]:
is_admin = True
return render_to_response("group_list.html", locals())
@login_required
def gastropin(request):
if request.method == 'POST':
form = GastroPinForm(request.POST)
if form.is_valid():
user = request.user
user_profile = user.get_profile()
user_profile.gastropin = form.cleaned_data['gastropin']
user_profile.save()
return render(request, 'gastropin.html',
{'message': _('Your Gastro-PIN was changed. Thank you!'),
'form:': form})
else:
return render(request, 'gastropin.html', {'form:': form})
else:
form = GastroPinForm()
return render(request, 'gastropin.html', {'form': form})
def set_ldap_field(request, form_type, field_names, template_name):
member = retrieve_member(request)
initial = {}
if request.method == 'POST':
form = form_type(request.POST)
if form.is_valid():
for form_field, ldap_field in field_names:
member.set(ldap_field, form.cleaned_data[form_field])
initial[form_field] = member.get(ldap_field)
member.save()
new_form = form_type(initial=initial)
return render(request, template_name,
{'message': _('Your changes have been saved. Thank you!'),
'form': new_form})
else:
return render(request, template_name, {'form:': form})
else:
for form_field, ldap_field in field_names:
initial[form_field] = member.get(ldap_field)
form = form_type(initial=initial)
return render(request, template_name, {'form': form})
@login_required
def wlan_presence(request):
return set_ldap_field(request, WlanPresenceForm,
[('presence', 'wlanPresence')], 'wlan_presence.html')
@login_required
def rfid(request):
return set_ldap_field(request, RFIDForm, [('rfid', 'rfid')], 'rfid.html')

View file

@ -1,26 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
from django import forms
from django.utils.translation import ugettext as _
class GastroPinField(forms.CharField):
def validate(self, value):
"""
Check if the value is all numeric and 4 - 6 chars long.
"""
match = re.match(r'^\d{4,6}$', value)
if not match:
raise forms.ValidationError(_('PIN must be 4 to 6 digits.'))
class GastroPinForm(forms.Form):
gastropin = GastroPinField()
class WlanPresenceForm(forms.Form):
# Boolean fields must never be required.
presence = forms.BooleanField(required=False)

View file

@ -176,6 +176,7 @@ INSTALLED_APPS = (
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.admindocs', 'django.contrib.admindocs',
'jsonrpc', 'jsonrpc',
'crispy_forms',
'cbmi', 'cbmi',
'account', 'account',
'cbapi_ldap', 'cbapi_ldap',
@ -210,7 +211,11 @@ LOGGING = {
} }
} }
# LOGIN_URL = '/account/login' CRISPY_TEMPLATE_PACK = 'bootstrap'
# c-base specific settings
CBASE_LDAP_URL = 'ldap://lea.cbrp3.c-base.org:389/'
CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org'
try: try:
from local_settings import * from local_settings import *

View file

@ -69,10 +69,14 @@
<li class="{% if request.path == landing_page_url %}active{% endif %}"> <li class="{% if request.path == landing_page_url %}active{% endif %}">
<a href="{{ landing_page_url }}">{% trans "Home" %}</a> <a href="{{ landing_page_url }}">{% trans "Home" %}</a>
</li> </li>
{% url cbmi.views.wlan_presence as wlan_presence_url %} {% url account.views.wlan_presence as wlan_presence_url %}
<li class="{% if request.path == wlan_presence_url %}active{% endif %}"> <li class="{% if request.path == wlan_presence_url %}active{% endif %}">
<a href="{{ wlan_presence_url }}">{% trans "WLAN Presence" %}</a> <a href="{{ wlan_presence_url }}">{% trans "WLAN Presence" %}</a>
</li> </li>
{% url account.views.rfid as rfid_url %}
<li class="{% if request.path == rfid_url %}active{% endif %}">
<a href="{{ rfid_url }}">{% trans "RFID" %}</a>
</li>
</ul> </ul>
{% block container %} {% block container %}
<div class="row"> <div class="row">

View file

@ -1,43 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% block container %}
<div class="row">
<div class="span12">
<h2>{% trans "WiFi Presence"%}</h2>
<p>{% blocktrans %}The WiFi Presence automatically logs you in
to the c-base presence system when you connect a device to the Crew-Wifi
(SSID: c-base-crew) with your username and password.{% endblocktrans %}</p>
{% if message %}
<div class="alert alert-success">{{ message }}</div>
{% endif %}
{{ form.non_field_errors }}
<form action="{% url cbmi.views.wlan_presence %}" method="post" class="form-horizontal well">
{% csrf_token %}
<div class="control-group">
<label class="control-label" for="if_presence">{% trans "WLAN-Presence" %}</label>
<div>
{{ form.presence.errors }}
</div>
<div class="controls">
<label class="checkbox">
{{ form.presence }}
{# <input name="presence" value="1" id="id_presence" type="checkbox"#}
{# {% if form.presence.value %}checked="checked"{% endif %} /> {% trans "aktivieren?" %}#}
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</div>
</div>
{% endblock container %}

View file

@ -10,10 +10,7 @@ urlpatterns = patterns('',
url(r'^cbapi/', include("cbapi_ldap.urls")), url(r'^cbapi/', include("cbapi_ldap.urls")),
url(r'account/', include('account.urls')), url(r'account/', include('account.urls')),
url(r'^groups/(?P<group_name>[^/]+)/', 'cbmi.views.groups_list'),
url(r'^$', 'cbmi.views.landingpage'),
url(r'^gastropin/$', 'cbmi.views.gastropin', name='gastropin'),
url(r'^wlan_presence/$', 'cbmi.views.wlan_presence', name='wlan_presence'), url(r'^$', 'cbmi.views.landingpage'),
) )

View file

@ -1,167 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import ldap # Create your views here
import copy
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.shortcuts import render
from django.utils.translation import ugettext as _
from forms import GastroPinForm, WlanPresenceForm
def landingpage(request):
is_ceymaster = is_admin = False
if 'ceymaster' in [g.name for g in request.user.groups.all()]:
is_ceymaster = True
if 'ldap_admins' in [g.name for g in request.user.groups.all()]:
is_admin = True
groups = Group.objects.all()
admins = Group.objects.get(name="ldap_admins").user_set.all()
if request.user.is_authenticated():
# values = get_user_values(request.user.username, request.session['ldap_password'])
return render_to_response("dashboard.html", locals())
return render_to_response("base.html", locals())
@login_required(redirect_field_name="/" ,login_url="/account/login/")
def groups_list(request, group_name):
group = get_object_or_404(Group, name=group_name)
groups = Group.objects.all()
if 'ceymaster' in [g.name for g in request.user.groups.all()]:
is_ceymaster = True
if 'ldap_admins' in [g.name for g in request.user.groups.all()]:
is_admin = True
return render_to_response("group_list.html", locals())
@login_required
def gastropin(request):
if request.method == 'POST':
form = GastroPinForm(request.POST)
if form.is_valid():
user = request.user
user_profile = user.get_profile()
user_profile.gastropin = form.cleaned_data['gastropin']
user_profile.save()
return render(request, 'gastropin.html',
{'message': _('Your Gastro-PIN was changed. Thank you!'),
'form:': form})
else:
return render(request, 'gastropin.html', {'form:': form})
else:
form = GastroPinForm()
return render(request, 'gastropin.html', {'form': form})
@login_required
def wlan_presence(request):
uv = UserValues(request.user.username, request.session['ldap_password'])
print "presence ist: ", uv.get_bool("wlanPresence")
if request.method == 'POST':
form = WlanPresenceForm(request.POST)
if form.is_valid():
p = 'FALSE'
if form.cleaned_data['presence'] == True:
p = 'TRUE'
uv.set('wlanPresence', p)
uv.save()
new_form = WlanPresenceForm(initial={'presence': uv.get_bool("wlanPresence")})
return render(request, 'wlan_presence.html',
{'message': _('Your Wifi Presenc has been set. Thank you!'),
'form': new_form})
else:
return render(request, 'wlan_presence.html', {'form:': form})
else:
form = WlanPresenceForm(initial={'presence': uv.get_bool("wlanPresence")})
return render(request, 'wlan_presence.html', {'form': form})
#def set_wlan_presence(request, value):
# """
#
# """
# set_boolean_value('wlanPresence', value,
# request.user.username, request.session['ldap_password'])
class UserValues(object):
"""
"""
def __init__(self, username, password):
self._username = username
self._password = password
self._old = self.get_user_values()
self._new = copy.deepcopy(self._old)
def get(self, key, default=None):
return self._new.get(key, default)[0]
def set(self, key, value):
self._new[key] = [value]
def get_bool(self, key):
return self.get(key) == 'TRUE'
def save(self):
"""
"""
dn = "uid=%s,ou=crew,dc=c-base,dc=org" % self._username
print 'setting dn=', dn
# TODO: Use settings for url
l = ldap.initialize("ldap://lea.cbrp3.c-base.org:389/")
l.simple_bind_s(dn, self._password)
mod_attrs = []
for new_key, new_value in self._new.items():
# Replace is the default.
action = ldap.MOD_REPLACE
if new_key not in self._old.keys():
action = ldap.MOD_ADD
mod_attrs.append((action, '%s' % new_key, new_value ))
continue
# Set the attribute and wait for the LDAP server to complete.
if self._old[new_key][0] != new_value[0]:
action = ldap.MOD_REPLACE
mod_attrs.append((action, '%s' % new_key, new_value ))
continue
print "modattrs: ",mod_attrs
result = l.modify_s(dn, mod_attrs)
print "result is: ", result
def get_user_values(self):
"""
"""
dn = "ou=crew,dc=c-base,dc=org"
bind_dn = "uid=%s,ou=crew,dc=c-base,dc=org" % self._username
print('setting dn=', dn)
# TODO: Use settings for url
l = ldap.initialize("ldap://lea.cbrp3.c-base.org:389/")
l.simple_bind_s(bind_dn, self._password)
# Set the attribute and wait for the LDAP server to complete.
searchScope = ldap.SCOPE_SUBTREE
## retrieve all attributes - again adjust to your needs - see documentation for more options
retrieveAttributes = None
searchFilter = "uid=%s" % self._username
# get_attrs = [( ldap., 'wlanPresence', set_value )]
result = l.search_s(dn, searchScope, searchFilter, retrieveAttributes)
# TODO: latin1
print "result is: ", result
# TODO: if len(result)==0
return result[0][1]