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.utils.translation import ugettext as _
class LoginForm(forms.Form):
username = forms.CharField(max_length=255)
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'^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.contrib.auth import login, logout, authenticate
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):
redirect_to = request.GET.get('next', '') or '/'
@ -43,3 +49,83 @@ def auth_logout(request):
response = HttpResponseRedirect(redirect_to)
response.delete_cookie('sessionkey')
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.admindocs',
'jsonrpc',
'crispy_forms',
'cbmi',
'account',
'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:
from local_settings import *

View file

@ -69,10 +69,14 @@
<li class="{% if request.path == landing_page_url %}active{% endif %}">
<a href="{{ landing_page_url }}">{% trans "Home" %}</a>
</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 %}">
<a href="{{ wlan_presence_url }}">{% trans "WLAN Presence" %}</a>
</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>
{% block container %}
<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'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
# -*- coding: utf-8 -*-
import ldap
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]
# Create your views here