From 1ed3f3f4b95b44f885d4316515eaae929c779334 Mon Sep 17 00:00:00 2001 From: Brian Wiborg Date: Sat, 26 Oct 2013 21:16:41 +0200 Subject: [PATCH 1/7] add crispy forms to requirements --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5a224e6..e5d0614 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ Django==1.4.2 MySQL-python==1.2.4 - django-auth-ldap==1.1.4 +django-auth-ldap==1.1.4 django-json-rpc==0.6.1 +django-crispy-forms==1.4.0 From d24e853fcd8fdc59824d76835c44dc33a8346c00 Mon Sep 17 00:00:00 2001 From: Brian Wiborg Date: Sat, 26 Oct 2013 21:35:25 +0200 Subject: [PATCH 2/7] show landingpage even if there are no groups, yet --- account/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/account/views.py b/account/views.py index f8b8f5e..8353253 100644 --- a/account/views.py +++ b/account/views.py @@ -31,7 +31,10 @@ def landingpage(request): 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() + try: + admins = Group.objects.get(name="ldap_admins").user_set.all() + except: + admins = [] # values = get_user_values(request.user.username, request.session['ldap_password']) #return render_to_response("dashboard.html", locals()) From 0bb8b03fcb79c95950646404bad425467351bb53 Mon Sep 17 00:00:00 2001 From: Brian Wiborg Date: Sat, 26 Oct 2013 22:25:26 +0200 Subject: [PATCH 3/7] add submodule support to dev_setup script --- dev_env_setup.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev_env_setup.sh b/dev_env_setup.sh index 5e5d5c1..ff0e29f 100644 --- a/dev_env_setup.sh +++ b/dev_env_setup.sh @@ -7,6 +7,8 @@ cd cbmi source bin/activate git clone git@github.com:c-base/cbmi.git src cd src +git submodule init +git submodule update pip install -r requirements.txt cat < Date: Sat, 26 Oct 2013 22:38:57 +0200 Subject: [PATCH 4/7] added admin pasword setting function --- account/forms.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/account/forms.py b/account/forms.py index 01b5f24..89701b7 100644 --- a/account/forms.py +++ b/account/forms.py @@ -121,4 +121,34 @@ class NRF24Form(forms.Form): class CLabPinForm(forms.Form): c_lab_pin1 = GastroPinField(label=_('New c-lab PIN')) c_lab_pin2 = GastroPinField(label=_('Repeat c-lab PIN'), - help_text=_('Numerical only, 4 to 6 digits')) \ No newline at end of file + help_text=_('Numerical only, 4 to 6 digits')) + + +class AdminForm(forms.Form): + password1 = forms.CharField(max_length=255, widget=forms.PasswordInput, + label=_('New password')) + password2 = forms.CharField(max_length=255, widget=forms.PasswordInput, + label=_('Repeat password')) + + + def __init__(self, *args, **kwargs): + self._request = kwargs.pop('request', None) + self._users = kwargs.pop('users', []) + choices = [(x, x) for x in self._users] + super(AdminForm, self).__init__(*args, **kwargs) + self.fields['username'] = forms.ChoiceField(choices=choices) + + def clean(self): + cleaned_data = super(AdminForm, self).clean() + + password1 = cleaned_data.get('password1') + password2 = cleaned_data.get('password2') + if password1 != password2: + raise forms.ValidationError( + _('The new passwords were not identical.'), + code='not_identical') + + return cleaned_data + + def get_member_choices(self): + return [(x, x) for x in self._users] \ No newline at end of file From 56c684d355fbb3a9f415c2d964b18c171a11d80f Mon Sep 17 00:00:00 2001 From: smile Date: Sat, 26 Oct 2013 22:40:47 +0200 Subject: [PATCH 5/7] added admin password setting function --- account/cbase_members.py | 43 ++++++++++++++++++++++++++-- account/templates/access_denied.html | 9 ++++++ account/templates/admin.html | 22 ++++++++++++++ account/templates/member_base.html | 8 ++++++ account/urls.py | 1 + account/views.py | 31 ++++++++++++++++++-- 6 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 account/templates/access_denied.html create mode 100644 account/templates/admin.html diff --git a/account/cbase_members.py b/account/cbase_members.py index 47dcbfa..b3fe08b 100644 --- a/account/cbase_members.py +++ b/account/cbase_members.py @@ -100,11 +100,14 @@ class MemberValues(object): result[key] = self.get(key) return result - def _get_bind_dn(self): + def _get_bind_dn(self, username=None): """ Adds the uid=userid, to the base dn and returns that. """ - bind_dn = 'uid=%s,' % self._username + if not username: + bind_dn = 'uid=%s,' % self._username + else: + bind_dn = 'uid=%s,' % username bind_dn += settings.CBASE_BASE_DN return bind_dn @@ -128,5 +131,39 @@ class MemberValues(object): # TODO: latin1 print "result is: ", result # TODO: if len(result)==0 - return result[0][1] session.unbind_s() + return result[0][1] + + def admin_change_password(self, username, new_password): + """ + Change the password of the member. + You do not need to call save() after calling change_password(). + """ + l = ldap.initialize(settings.CBASE_LDAP_URL) + user_dn = self._get_bind_dn() + l.simple_bind_s(user_dn, self._password) + l.passwd_s(self._get_bind_dn(username), None, new_password) + l.unbind_s() + + def list_users(self): + l = ldap.initialize(settings.CBASE_LDAP_URL) + user_dn = self._get_bind_dn() + l.simple_bind_s(user_dn, self._password) + try: + ldap_result_id = l.search(settings.CBASE_BASE_DN, ldap.SCOPE_SUBTREE, "memberOf=cn=crew,ou=groups,dc=c-base,dc=org", None) + result_set = [] + while 1: + result_type, result_data = l.result(ldap_result_id, 0) + if (result_data == []): + break + else: + ## here you don't have to append to a list + ## you could do whatever you want with the individual entry + ## The appending to list is just for illustration. + if result_type == ldap.RES_SEARCH_ENTRY: + result_set.append(result_data) + + userlist = [x[0][1]['uid'][0] for x in result_set] + return sorted(userlist) + except: + return [] \ No newline at end of file diff --git a/account/templates/access_denied.html b/account/templates/access_denied.html new file mode 100644 index 0000000..dfe4e30 --- /dev/null +++ b/account/templates/access_denied.html @@ -0,0 +1,9 @@ +{% extends "member_base.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block form_title %}{% trans "Password"%}{% endblock %} + +{% block container %} +
{% blocktrans %}ACCESS DENIED{% endblocktrans %}
+{% endblock %} \ No newline at end of file diff --git a/account/templates/admin.html b/account/templates/admin.html new file mode 100644 index 0000000..e230e92 --- /dev/null +++ b/account/templates/admin.html @@ -0,0 +1,22 @@ +{% extends "form_base.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block form_title %}{% trans "Admin Password"%}{% endblock %} + +{% block form_description %} +

{% blocktrans %}You can change other users passwords here.{% endblocktrans %}

+{% endblock %} + +{% block form_fields %} +
+ {% csrf_token %} + {{ form|crispy }} + +
+
+ +
+
+
+{% endblock form_fields %} \ No newline at end of file diff --git a/account/templates/member_base.html b/account/templates/member_base.html index 67bfd7d..795300b 100644 --- a/account/templates/member_base.html +++ b/account/templates/member_base.html @@ -36,6 +36,14 @@
  • {% trans "SIP-PIN" %}
  • + {% for group in request.user.groups.all %} + {% if group.name == 'ldap_admins' %} + {% url account.views.admin as admin_url %} +
  • + {% trans "Admin" %} +
  • + {% endif %} + {% endfor %} {% block container %}{% endblock container %} diff --git a/account/urls.py b/account/urls.py index cb721bd..d4ff5f6 100644 --- a/account/urls.py +++ b/account/urls.py @@ -12,6 +12,7 @@ urlpatterns = patterns( url(r'^password/$', 'account.views.password', name='password'), url(r'^sippin/$', 'account.views.sippin', name='sippin'), url(r'^clabpin/$', 'account.views.clabpin', name='clabpin'), + url(r'^admin/$', 'account.views.admin', name='admin'), url(r'^$', 'account.views.home', name="home"), url(r'^groups/(?P[^/]+)/', 'account.views.groups_list'), ) \ No newline at end of file diff --git a/account/views.py b/account/views.py index f8b8f5e..6f6f664 100644 --- a/account/views.py +++ b/account/views.py @@ -18,7 +18,7 @@ from django.shortcuts import render from django.utils.translation import ugettext as _ from forms import GastroPinForm, WlanPresenceForm, LoginForm, PasswordForm, \ - RFIDForm, NRF24Form, SIPPinForm, CLabPinForm + RFIDForm, NRF24Form, SIPPinForm, CLabPinForm, AdminForm from cbase_members import retrieve_member def landingpage(request): @@ -137,6 +137,9 @@ def gastropin(request): @login_required def clabpin(request): + if request.user.groups.filter(name='ldap_admins').count() == 0: + return render(request, 'access_denied.html') + def calculate_clab_hash(pin): salt = os.urandom(12) digest = hashlib.sha1(bytearray(pin, 'UTF-8')+salt).digest() @@ -215,6 +218,30 @@ def rfid(request): def nrf24(request): return set_ldap_field(request, NRF24Form, [('nrf24', 'nrf24')], 'nrf24.html') +@login_required +def admin(request): + member = retrieve_member(request) + if request.user.groups.filter(name='ldap_admins').count() == 0: + return render(request, 'access_denied.html') + users = member.list_users() + if request.method == 'POST': + form = AdminForm(request.POST, request=request, users=users) + if form.is_valid(): + new_password = form.cleaned_data['password1'] + member.admin_change_password(form.cleaned_data['username'], new_password) + new_form = AdminForm(request=request, users=users) + return render(request, 'admin.html', + {'message': _('The password for %s was changed. Thank you!' % form.cleaned_data['username']), + 'form': new_form}) + else: + return render(request, 'admin.html', + {'form': form}) + else: + form = AdminForm(request=request, users=users) + return render(request, 'admin.html', + {'form': form}) - + #username = cleaned_data.get('username') + #admin_username = self._request.user.username + #admin_password = self._request.session['ldap_password'] From 1f75194fadc6357b116edf2c7d21f32c052e8046 Mon Sep 17 00:00:00 2001 From: Uwe Kamper Date: Sat, 26 Oct 2013 22:45:02 +0200 Subject: [PATCH 6/7] c-lab view now requires c-lab-cey group --- account/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account/views.py b/account/views.py index 48105ce..e5b68b6 100644 --- a/account/views.py +++ b/account/views.py @@ -140,7 +140,7 @@ def gastropin(request): @login_required def clabpin(request): - if request.user.groups.filter(name='ldap_admins').count() == 0: + if request.user.groups.filter(name='cey-c-lab').count() == 0: return render(request, 'access_denied.html') def calculate_clab_hash(pin): From 6bc87b605c82f5fc3e1e102adc8c21a6f549a75a Mon Sep 17 00:00:00 2001 From: Uwe Kamper Date: Sat, 26 Oct 2013 22:56:47 +0200 Subject: [PATCH 7/7] added star to admin tab, changed form order in admin tab --- account/forms.py | 4 +++- account/templates/member_base.html | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/account/forms.py b/account/forms.py index 89701b7..84f4fc1 100644 --- a/account/forms.py +++ b/account/forms.py @@ -135,8 +135,10 @@ class AdminForm(forms.Form): self._request = kwargs.pop('request', None) self._users = kwargs.pop('users', []) choices = [(x, x) for x in self._users] + choices.insert(0, ('', 'Select username ...')) super(AdminForm, self).__init__(*args, **kwargs) - self.fields['username'] = forms.ChoiceField(choices=choices) + self.fields.insert(0, 'username', forms.ChoiceField(choices=choices, + help_text=_('Select the username for whom you want to reset the password.'))) def clean(self): cleaned_data = super(AdminForm, self).clean() diff --git a/account/templates/member_base.html b/account/templates/member_base.html index 795300b..6b850e9 100644 --- a/account/templates/member_base.html +++ b/account/templates/member_base.html @@ -40,7 +40,8 @@ {% if group.name == 'ldap_admins' %} {% url account.views.admin as admin_url %}
  • - {% trans "Admin" %} + + {% trans "Admin" %}
  • {% endif %} {% endfor %}