diff --git a/account/cbase_members.py b/account/cbase_members.py index a9d0039..b81d187 100644 --- a/account/cbase_members.py +++ b/account/cbase_members.py @@ -1,12 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import ldap -import copy - -from django.conf import settings -from account.password_encryption import get_ldap_password - """ Example configuration: @@ -14,12 +8,30 @@ CBASE_LDAP_URL = 'ldap://lea.cbrp3.c-base.org:389/' CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org' """ +import copy +import logging + +from django.conf import settings + +import ldap + +from account.password_encryption import get_ldap_password + +LOGGER = logging.getLogger(__name__) + def retrieve_member(request): + """ + Gets a MemberValues object by its user name bound to a request object. + :param request: + :return: A MemberValues object + """ ldap_password = get_ldap_password(request) - session = dict(request.session) - print("session:", session) - print("cookies:", request.COOKIES) + request_session = dict(request.session) + + LOGGER.info("session: %s", request_session) + LOGGER.info("cookies: %s", request.COOKIES) + return MemberValues(request.user.username, ldap_password) @@ -29,6 +41,13 @@ class MemberValues(object): """ def __init__(self, username, password): + """ + Initializes a MemberValues object with all necessary parameters to + synchronize with an LDAP server. + + :param username: + :param password: + """ self._username = username self._password = password self._old = self._get_user_values() @@ -38,6 +57,12 @@ class MemberValues(object): self._new = copy.deepcopy(self._old) def get(self, key, default=None): + """ + Gets a member attribute value by key. + :param key: + :param default: + :return: + """ value_list = self._new.get(key, default) if value_list: value = value_list[0] @@ -56,13 +81,19 @@ class MemberValues(object): return value def set(self, key, value): - if value == None: + """ + Sets a member attribute value for a key replacing the old value + :param key: + :param value: + :return: + """ + if value is None: self._new[key] = [None] return converted_value = value if isinstance(value, bool): - if value == True: + if value: converted_value = 'TRUE' else: converted_value = 'FALSE' @@ -73,12 +104,13 @@ class MemberValues(object): """ Save the values back to the LDAP server. """ - dn = "uid=%s,ou=crew,dc=c-base,dc=org" % self._username + user_dn = "uid=%s,ou=crew,dc=c-base,dc=org" % self._username - l = ldap.initialize(settings.CBASE_LDAP_URL) - l.simple_bind_s(dn, self._password) + session = ldap.initialize(settings.CBASE_LDAP_URL) + session.simple_bind_s(user_dn, self._password) mod_attrs = [] + action = None for new_key, new_value in self._new.items(): # Replace is the default. action = ldap.MOD_REPLACE @@ -86,36 +118,41 @@ class MemberValues(object): action = ldap.MOD_ADD mod_attrs.append((action, '%s' % new_key, new_value)) continue - if self._old[new_key][0] != None and new_value == [None]: + if self._old.get(new_key, [None])[0] is not None \ + and new_value == [None]: action = ldap.MOD_DELETE mod_attrs.append((action, '%s' % new_key, [])) + # Set the attribute and wait for the LDAP server to complete. continue - # Set the attribute and wait for the LDAP server to complete. - if self._old[new_key][0] != new_value[0]: + if self._old.get(new_key, [None])[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) - l.unbind_s() + LOGGER.debug("action: %s modattrs: %s", action, mod_attrs) + result = session.modify_s(user_dn, mod_attrs) + LOGGER.debug("result is: %s", result) + session.unbind_s() + return result # does not harm any1 def change_password(self, 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) + session = ldap.initialize(settings.CBASE_LDAP_URL) user_dn = self._get_bind_dn() - l.simple_bind_s(user_dn, self._password) - l.passwd_s(user_dn, self._password, new_password) - l.unbind_s() + session.simple_bind_s(user_dn, self._password) + session.passwd_s(user_dn, self._password, new_password) + session.unbind_s() def to_dict(self): + """ + Converts a MembersValue object to a dict representation. + :return: + """ result = {} - for key, value in self._new.items(): + for key, _ in self._new.items(): result[key] = self.get(key) return result @@ -139,17 +176,22 @@ class MemberValues(object): 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 + search_scope = ldap.SCOPE_SUBTREE # retrieve all attributes - retrieveAttributes = None - searchFilter = "uid=%s" % self._username + retrieve_attributes = None + search_filter = "uid=%s" % self._username - dn = settings.CBASE_BASE_DN + base_dn = settings.CBASE_BASE_DN result = session.search_s( - dn, searchScope, searchFilter, retrieveAttributes) + base_dn, + search_scope, + search_filter, + retrieve_attributes + ) + # TODO: latin1 - print("result is: ", result) + LOGGER.info("result is: %s", result) # TODO: if len(result)==0 session.unbind_s() return result[0][1] @@ -159,11 +201,11 @@ class MemberValues(object): Change the password of the member. You do not need to call save() after calling change_password(). """ - l = ldap.initialize(settings.CBASE_LDAP_URL) + session = 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() + session.simple_bind_s(user_dn, self._password) + session.passwd_s(self._get_bind_dn(username), None, new_password) + session.unbind_s() def get_number_of_members(self): """ @@ -176,22 +218,26 @@ class MemberValues(object): Returns a list of strings with all usernames in the group 'crew'. The list is sorted alphabetically. """ - l = ldap.initialize(settings.CBASE_LDAP_URL) + session = ldap.initialize(settings.CBASE_LDAP_URL) user_dn = self._get_bind_dn() - l.simple_bind_s(user_dn, self._password) + session.simple_bind_s(user_dn, self._password) try: - result_id = l.search(settings.CBASE_BASE_DN, ldap.SCOPE_SUBTREE, - "memberOf=cn=crew,ou=groups,dc=c-base,dc=org", None) + result_id = session.search( + settings.CBASE_BASE_DN, + ldap.SCOPE_SUBTREE, + "memberOf=cn=crew,ou=groups,dc=c-base,dc=org", + None + ) result_set = [] while True: - result_type, result_data = l.result(result_id, 0) - if (result_data == []): + result_type, result_data = session.result(result_id, 0) + if not result_data: break - else: - if result_type == ldap.RES_SEARCH_ENTRY: - result_set.append(result_data) + if result_type == ldap.RES_SEARCH_ENTRY: + result_set.append(result_data) - # list comprehension to get a list of user tupels in the format ("nickname", "nickname (real name)") + # list comprehension to get a list of user tupels in the + # format ("nickname", "nickname (real name)") userlist = [( x[0][1]['uid'][0].decode(), '%s (%s, %s)' % ( @@ -202,4 +248,5 @@ class MemberValues(object): ) for x in result_set] return sorted(userlist) except Exception: + LOGGER.exception('list_users failed') return [] diff --git a/account/forms.py b/account/forms.py index c946a87..8d0ca58 100755 --- a/account/forms.py +++ b/account/forms.py @@ -7,33 +7,41 @@ from django import forms from django.contrib.auth import authenticate from django.utils.translation import ugettext as _ + class UsernameField(forms.CharField): """ - The username field makes sure that usernames are always entered in lower-case. - If we do not convert the username to lower-case, Django will create more than - one user object in the database. If we then try to login again, the Django auth - subsystem will do an query that looks like this: username__iexact="username". The - result is an error, because iexact returns the objects for "username" and "Username". + The username field makes sure that usernames are always entered in + lower-case. If we do not convert the username to lower-case, Django will + create more than one user object in the database. If we then try to login + again, the Django auth subsystem will do an query that looks like this: + username__iexact="username". The result is an error, because iexact returns + the objects for "username" and "Username". """ - + def to_python(self, value): value = super(UsernameField, self).to_python(value) value = value.lower() return value - + class LoginForm(forms.Form): username = UsernameField(max_length=255) - password = forms.CharField(max_length=255, widget=forms.PasswordInput, + password = forms.CharField( + max_length=255, widget=forms.PasswordInput, help_text=_('Cookies must be enabled.')) - + def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') user = authenticate(username=username, password=password) if not user or not user.is_active: - raise forms.ValidationError(_('Sorry, that login was invalid. ' - 'Please try again.'), code='invalid_login') + raise forms.ValidationError( + _( + 'Sorry, that login was invalid. ' + 'Please try again.' + ), + code='invalid_login' + ) return self.cleaned_data def login(self, request): @@ -45,6 +53,7 @@ class LoginForm(forms.Form): class GastroPinField(forms.CharField): widget = forms.PasswordInput + def validate(self, value): """ Check if the value is all numeric and 4 - 8 chars long. @@ -56,7 +65,8 @@ class GastroPinField(forms.CharField): class GastroPinForm(forms.Form): gastropin1 = GastroPinField(label=_('New Gastro-PIN')) - gastropin2 = GastroPinField(label=_('Repeat Gastro-PIN'), + gastropin2 = GastroPinField( + label=_('Repeat Gastro-PIN'), help_text=_('Numerical only, 4 to 8 digits')) def clean(self): @@ -67,24 +77,33 @@ class GastroPinForm(forms.Form): if gastropin1 != gastropin2: raise forms.ValidationError( _('The PINs entered were not identical.'), - code='not_identical') + code='not_identical' + ) return cleaned_data class WlanPresenceForm(forms.Form): # Boolean fields must never be required. - presence = forms.BooleanField(required=False, - label=_('Enable WiFi presence')) + presence = forms.BooleanField( + required=False, + label=_('Enable WiFi presence') + ) class PasswordForm(forms.Form): - old_password = forms.CharField(max_length=255, widget=forms.PasswordInput, + old_password = forms.CharField( + max_length=255, widget=forms.PasswordInput, label=_('Old password'), - help_text=_('Enter your current password here.')) - password1 = forms.CharField(max_length=255, widget=forms.PasswordInput, - label=_('New password')) - password2 = forms.CharField(max_length=255, widget=forms.PasswordInput, - label=_('Repeat password')) + help_text=_( + 'Enter your current password here.')) + 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) @@ -97,8 +116,12 @@ class PasswordForm(forms.Form): user = authenticate(username=username, password=old_password) if not user or not user.is_active: - raise forms.ValidationError(_('The old password was incorrect.'), - code='old_password_wrong') + raise forms.ValidationError( + _( + 'The old password was incorrect.' + ), + code='old_password_wrong' + ) password1 = cleaned_data.get('password1') password2 = cleaned_data.get('password2') @@ -115,9 +138,14 @@ class PasswordForm(forms.Form): class RFIDForm(forms.Form): - rfid = forms.CharField(max_length=255, label=_('Your RFID'), - help_text=_('Find out your RFID by holding your RFID tag to the ' - 'reader in the airlock.')) + rfid = forms.CharField( + max_length=255, + label=_('Your RFID'), + help_text=_( + 'Find out your RFID by holding your RFID tag to the ' + 'reader in the airlock.' + ) + ) class SIPPinForm(forms.Form): @@ -135,30 +163,44 @@ class SIPPinForm(forms.Form): class NRF24Form(forms.Form): - nrf24 = forms.CharField(max_length=255, - label = _('NRF24-ID'), - help_text=_("Your r0ket's NRF24 identification")) + nrf24 = forms.CharField( + max_length=255, + label=_('NRF24-ID'), + help_text=_("Your r0ket's NRF24 identification") + ) class CLabPinForm(forms.Form): c_lab_pin1 = GastroPinField(label=_('New indoor PIN')) - c_lab_pin2 = GastroPinField(label=_('Repeat indoor PIN'), - help_text=_('Numerical only, 4 to 8 digits')) + c_lab_pin2 = GastroPinField( + label=_('Repeat indoor PIN'), + help_text=_('Numerical only, 4 to 8 digits') + ) class PreferredEmailForm(forms.Form): - preferred_email = forms.EmailField(max_length=255, required=False, - label = _('Preferred e-mail'), - help_text=_("Forward my mail to this address. Leave empty to use the c-base IMAP and SMTP servers.")) + preferred_email = forms.EmailField( + max_length=255, required=False, + label=_('Preferred e-mail'), + help_text=_( + "Forward my mail to this address. Leave empty to use the c-base " + "IMAP and SMTP servers." + ) + ) class AdminForm(forms.Form): username = forms.ChoiceField(choices=[]) - password1 = forms.CharField(max_length=255, widget=forms.PasswordInput, - label=_('New password')) - password2 = forms.CharField(max_length=255, widget=forms.PasswordInput, - label=_('Repeat password')) - + 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) @@ -166,10 +208,23 @@ class AdminForm(forms.Form): choices = [x for x in self._users] choices.insert(0, ('', 'Select username ...')) super(AdminForm, self).__init__(*args, **kwargs) - #self.fields.insert(0, 'username', forms.ChoiceField(choices=choices, - #help_text=_('Select the username for whom you want to reset the password.'))) - self.fields['username'] = forms.ChoiceField(choices=choices, - help_text=_('Select the username for whom you want to reset the password.')) + # self.fields.insert( + # 0, + # 'username', + # forms.ChoiceField( + # choices=choices, + # help_text=_( + # 'Select the username for whom you want ' + # 'to reset the password.' + # ) + # ) + # ) + self.fields['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() @@ -179,11 +234,13 @@ class AdminForm(forms.Form): if password1 != password2: raise forms.ValidationError( _('The new passwords were not identical.'), - code='not_identical') + code='not_identical' + ) if len(password1) < 6: raise forms.ValidationError( _('Password must be at least 6 characters long'), - code='to_short') + code='to_short' + ) return cleaned_data diff --git a/account/models.py b/account/models.py index 9db847a..d45d299 100644 --- a/account/models.py +++ b/account/models.py @@ -1,43 +1,73 @@ -from django.db import models +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Django models +""" + from django.contrib.auth.models import User +from django.db import models from django.db.models import signals + from account.signals import create_profile, delete_profile + class UserProfile(models.Model): - user = models.OneToOneField(User, editable=False, on_delete=models.CASCADE) - uid = models.CharField(verbose_name="User-ID", - max_length=8, - null=True, - default=None) - sippin = models.CharField(verbose_name="SIP PIN", - max_length=255, - null=True, - blank=True, - default=None) - gastropin = models.CharField(verbose_name="Gastro PIN", - max_length=255, - null=True, - blank=True, - default=None) - rfid = models.CharField(verbose_name="RFID", - max_length=255, - null=True, - blank=True, - default=None) - macaddress = models.CharField(verbose_name="MAC-Address", - max_length=255, - null=True, - blank=True, - default=None) - clabpin = models.CharField(verbose_name="c-lab PIN", - max_length=255, - null=True, - blank=True, - default=None) - preferred_email = models.CharField(verbose_name="preferred e-mail address", - max_length=1024, - null=True, - default=None) + """ + UserProfile to be attached to a django User model. + """ + user = models.OneToOneField( + User, + editable=False, + on_delete=models.CASCADE + ) + uid = models.CharField( + verbose_name="User-ID", + max_length=8, + null=True, + default=None + ) + sippin = models.CharField( + verbose_name="SIP PIN", + max_length=255, + null=True, + blank=True, + default=None + ) + gastropin = models.CharField( + verbose_name="Gastro PIN", + max_length=255, + null=True, + blank=True, + default=None + ) + rfid = models.CharField( + verbose_name="RFID", + max_length=255, + null=True, + blank=True, + default=None + ) + macaddress = models.CharField( + verbose_name="MAC-Address", + max_length=255, + null=True, + blank=True, + default=None + ) + clabpin = models.CharField( + verbose_name="c-lab PIN", + max_length=255, + null=True, + blank=True, + default=None + ) + preferred_email = models.CharField( + verbose_name="preferred e-mail address", + max_length=1024, + null=True, + default=None + ) is_member = models.BooleanField(default=False, editable=False) is_ldap_admin = models.BooleanField(default=False, editable=False) is_circle_member = models.BooleanField(default=False, editable=False) @@ -49,6 +79,7 @@ class UserProfile(models.Model): def __unicode__(self): return 'Profile: %s' % self.user.username + User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0]) signals.post_save.connect(create_profile, sender=User) signals.pre_delete.connect(delete_profile, sender=User) diff --git a/account/password_encryption.py b/account/password_encryption.py index d18938e..6eb6ff5 100644 --- a/account/password_encryption.py +++ b/account/password_encryption.py @@ -8,6 +8,7 @@ from Crypto.Cipher import AES ENCRYPTED_LDAP_PASSWORD = 'encrypted_ldap_password' + def encrypt_ldap_password(cleartext_pw): """ Encrypts the cleartext_pw with a randomly generated key. @@ -28,6 +29,7 @@ def encrypt_ldap_password(cleartext_pw): message = iv + aes.encrypt(cleartext_pw) return base64.b64encode(message).decode(), base64.b64encode(key).decode() + def decrypt_ldap_password(message, key): """ Takes an encrypted, base64 encoded password and the base64 encoded key. @@ -47,6 +49,7 @@ def decrypt_ldap_password(message, key): cleartext_pw = aes.decrypt(ciphertext) return cleartext_pw + def store_ldap_password(request, password): """ Stores the password in an encrypted session storage and returns the key. @@ -56,9 +59,10 @@ def store_ldap_password(request, password): request.session.save() return key + def get_ldap_password(request): cookies = request.COOKIES key = cookies.get('sessionkey', None) if not key: raise Exception('sessionkey not found in cookies.') - return decrypt_ldap_password(request.session[ENCRYPTED_LDAP_PASSWORD], key) \ No newline at end of file + return decrypt_ldap_password(request.session[ENCRYPTED_LDAP_PASSWORD], key) diff --git a/account/signals.py b/account/signals.py index 865e069..fd95496 100644 --- a/account/signals.py +++ b/account/signals.py @@ -4,6 +4,7 @@ def create_profile(sender, instance, signal, created, **kwargs): if created: UserProfile(user=instance).save() + def delete_profile(sender, instance, signal, **kwargs): from account.models import UserProfile - UserProfile(user=instance).delete() \ No newline at end of file + UserProfile(user=instance).delete() diff --git a/account/tests.py b/account/tests.py index ac863db..07c7e52 100644 --- a/account/tests.py +++ b/account/tests.py @@ -6,7 +6,9 @@ Replace this with more appropriate tests for your application. """ from django.test import TestCase -from password_encryption import encrypt_ldap_password, decrypt_ldap_password +from account.password_encryption import encrypt_ldap_password, \ + decrypt_ldap_password + class PasswordEncryptionTest(TestCase): """ @@ -22,8 +24,7 @@ class PasswordEncryptionTest(TestCase): print('key:', key) print('message:', message) - def test_decrypt_ldap_password(self): message, key = self.encrypt_it() decrypted = decrypt_ldap_password(message, key) - self.assertEqual(self.TEST_LDAP_PASSWD, decrypted) \ No newline at end of file + self.assertEqual(self.TEST_LDAP_PASSWD, decrypted) diff --git a/account/views.py b/account/views.py index 238984b..f61ca79 100755 --- a/account/views.py +++ b/account/views.py @@ -1,29 +1,30 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import os -import hashlib -import smbpasswd -import requests import collections +import hashlib +import os +import requests from django.conf import settings -from django.http import HttpResponse, HttpResponseRedirect -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 import login, logout from django.contrib.auth.decorators import login_required from django.contrib.auth.models import Group +from django.contrib.auth.models import User +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import get_object_or_404 from django.shortcuts import render +from django.shortcuts import render_to_response from django.utils.translation import ugettext as _ -from account.forms import GastroPinForm, WlanPresenceForm, LoginForm, PasswordForm, \ - RFIDForm, NRF24Form, SIPPinForm, CLabPinForm, AdminForm, PreferredEmailForm +import smbpasswd from account.cbase_members import retrieve_member, MemberValues +from account.forms import GastroPinForm, WlanPresenceForm, LoginForm, \ + PasswordForm, RFIDForm, NRF24Form, SIPPinForm, CLabPinForm, AdminForm, \ + PreferredEmailForm from account.password_encryption import * + def landingpage(request): if request.user.is_authenticated: return HttpResponseRedirect('/account') @@ -31,7 +32,7 @@ def landingpage(request): try: # just in case the group hasn't yet been synced admins = Group.objects.get(name="ldap_admins").user_set.all() - except: + except Exception: # else provide an emtpy list admins = [] @@ -42,7 +43,7 @@ def landingpage(request): try: user = User.objects.get(username=check_nickname) check_nickname = True - except: + except Exception: check_nickname = False # output as text if requested @@ -51,6 +52,7 @@ def landingpage(request): return render(request, 'base.html', locals()) + def auth_login(request): redirect_to = request.GET.get('next', '') or '/' if request.method == 'POST': @@ -76,6 +78,7 @@ def auth_login(request): form = LoginForm() return render(request, 'login.html', {'form': form}) + @login_required def home(request): member = retrieve_member(request) @@ -85,17 +88,23 @@ def home(request): url = "https://vorstand.c-base.org/cteward-api/legacy/member/%s" % username cteward = None try: - r = requests.get(url, verify=False, auth=(username, password)) + r = requests.get( + url, + verify=False, + auth=(username, password) + ) cteward = r.json() except Exception: pass - context = {'member': member.to_dict(), + context = { + 'member': member.to_dict(), 'groups': list(request.user.groups.all().order_by('name')), 'number_of_members': number_of_members, 'cteward': cteward, } return render(request, 'home.html', context) + @login_required def auth_logout(request): request.session.pop(ENCRYPTED_LDAP_PASSWORD) @@ -105,7 +114,8 @@ def auth_logout(request): response.delete_cookie('sessionkey') return response -@login_required(redirect_field_name="/" ,login_url="/account/login/") + +@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() @@ -115,13 +125,19 @@ def groups_list(request, group_name): is_admin = True return render_to_response("group_list.html", locals()) + @login_required def sippin(request): - return set_ldap_field(request, SIPPinForm, [('sippin', 'sippin')], - 'sippin.html') + return set_ldap_field( + request, + SIPPinForm, + [('sippin', 'sippin')], + 'sippin.html' + ) + def set_hash_field(request, form_type, in_field, out_field, hash_func, - template_name): + template_name): """ Abstract view for changing LDAP attributes that need to be hashed. Takes a function that converts the value into the hashed_value. @@ -136,16 +152,35 @@ def set_hash_field(request, form_type, in_field, out_field, hash_func, member.set(out_field, hashed_value) member.save() new_form = form_type(initial=initial) - return render(request, template_name, - {'message': _('Your changes have been saved. Thank you!'), - 'form': new_form, 'member': member.to_dict()}) + return render( + request, + template_name, + { + 'message': _('Your changes have been saved. Thank you!'), + 'form': new_form, + 'member': member.to_dict() + } + ) else: - return render(request, template_name, - {'form': form, 'member': member.to_dict()}) + return render( + request, + template_name, + { + 'form': form, + 'member': member.to_dict() + } + ) else: form = form_type(initial=initial) - return render(request, template_name, - {'form': form, 'member': member.to_dict()}) + return render( + request, + template_name, + { + 'form': form, + 'member': member.to_dict() + } + ) + @login_required def gastropin(request): @@ -154,22 +189,31 @@ def gastropin(request): bla = '%s%s' % (key, pin) return hashlib.sha256(bla.encode()).hexdigest() - return set_hash_field(request, GastroPinForm, - 'gastropin1', 'gastroPIN', calculate_gastro_hash, 'gastropin.html') + return set_hash_field( + request, + GastroPinForm, + 'gastropin1', + 'gastroPIN', + calculate_gastro_hash, + 'gastropin.html' + ) + @login_required def clabpin(request): - # if len(request.user.groups.filter(name__in=['cey-c-lab', 'cey-schleuse', 'cey-soundlab'])) < 1: - # return render(request, 'access_denied.html') + # names = ['cey-c-lab', 'cey-schleuse', 'cey-soundlab'] + # if len(request.user.groups.filter(name__in=names)) < 1: + # return render(request, 'access_denied.html') def calculate_clab_hash(pin): salt = os.urandom(12) - digest = hashlib.sha1(bytearray(pin, 'UTF-8')+salt).digest() + digest = hashlib.sha1(bytearray(pin, 'UTF-8') + salt).digest() pin_hash = '{SSHA}%s' % base64.b64encode(digest + salt).decode() return pin_hash return set_hash_field(request, CLabPinForm, 'c_lab_pin1', 'c-labPIN', - calculate_clab_hash, 'clabpin.html') + calculate_clab_hash, 'clabpin.html') + @login_required def password(request): @@ -196,17 +240,19 @@ def password(request): request.session.save() new_form = PasswordForm() response = render(request, 'password.html', - {'message': _('Your password was changed. Thank you!'), - 'form': new_form, 'member': member.to_dict()}) + {'message': _( + 'Your password was changed. Thank you!'), + 'form': new_form, 'member': member.to_dict()}) response.set_cookie('sessionkey', key) return response else: return render(request, 'password.html', - {'form': form, 'member': member.to_dict()}) + {'form': form, 'member': member.to_dict()}) else: form = PasswordForm() return render(request, 'password.html', - {'form': form, 'member': member.to_dict()}) + {'form': form, 'member': member.to_dict()}) + def set_ldap_field(request, form_type, field_names, template_name): """ @@ -230,36 +276,44 @@ def set_ldap_field(request, form_type, field_names, template_name): member.save() new_form = form_type(initial=initial) return render(request, template_name, - {'message': _('Your changes have been saved. Thank you!'), - 'form': new_form, 'member': member.to_dict()}) + {'message': _( + 'Your changes have been saved. Thank you!'), + 'form': new_form, 'member': member.to_dict()}) else: return render(request, template_name, - {'form': form, 'member': member.to_dict()}) + {'form': form, 'member': member.to_dict()}) 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, 'member': member.to_dict()}) + {'form': form, 'member': member.to_dict()}) + @login_required def wlan_presence(request): return set_ldap_field(request, WlanPresenceForm, - [('presence', 'wlanPresence')], 'wlan_presence.html') + [('presence', 'wlanPresence')], 'wlan_presence.html') + @login_required def rfid(request): return set_ldap_field(request, RFIDForm, [('rfid', 'rfid')], 'rfid.html') + @login_required def nrf24(request): - return set_ldap_field(request, NRF24Form, [('nrf24', 'nrf24')], 'nrf24.html') + return set_ldap_field(request, NRF24Form, [('nrf24', 'nrf24')], + 'nrf24.html') + @login_required def preferred_email(request): - return set_ldap_field(request, PreferredEmailForm, [('preferred_email', 'preferredEmail')], + return set_ldap_field(request, PreferredEmailForm, + [('preferred_email', 'preferredEmail')], 'preferred_email.html') + @login_required def admin(request): admin_member = retrieve_member(request) @@ -271,7 +325,8 @@ def admin(request): if form.is_valid(): new_password = form.cleaned_data['password1'] - admin_member.admin_change_password(form.cleaned_data['username'], new_password) + admin_member.admin_change_password(form.cleaned_data['username'], + new_password) member = MemberValues(form.cleaned_data['username'], new_password) member.set('sambaLMPassword', smbpasswd.lmhash(new_password)) @@ -280,42 +335,61 @@ def admin(request): 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}) + {'message': _( + 'The password for %s was changed. Thank you!' % + form.cleaned_data['username']), + 'form': new_form}) else: return render(request, 'admin.html', - {'form': form}) + {'form': form}) else: form = AdminForm(request=request, users=users) return render(request, 'admin.html', - {'form': form}) + {'form': form}) + + # username = cleaned_data.get('username') + # admin_username = self._request.user.username + # admin_password = self._request.session['ldap_password'] - #username = cleaned_data.get('username') - #admin_username = self._request.user.username - #admin_password = self._request.session['ldap_password'] def hammertime(request): return render(request, 'hammertime.html', {}) + @login_required def memberstatus(request): - #url = baseurl + route_operation_mapping['SessionCreate']['Route'] - #data = json.dumps({'UserLogin': username, 'Password': password}) + # url = baseurl + route_operation_mapping['SessionCreate']['Route'] + # data = json.dumps({'UserLogin': username, 'Password': password}) password = get_ldap_password(request) username = request.user.username - url = "https://vorstand.c-base.org/cteward-api/legacy/member/%s/contributions" % username - r = requests.get(url, verify=False, auth=(username, password)) + url = "https://vorstand.c-base.org" \ + "/cteward-api/legacy/member/%s/contributions" % username + r = requests.get( + url, + verify=False, + auth=(username, password) + ) contributions = r.json() try: - years = collections.OrderedDict(sorted(contributions['years'].items(), reverse=True)) + years = collections.OrderedDict( + sorted(contributions['years'].items(), reverse=True)) contributions['years'] = years.items() - except: pass + except: + pass url = "https://vorstand.c-base.org/cteward-api/legacy/member/%s" % username - r = requests.get(url, verify=False, auth=(username, password)) + r = requests.get( + url, + verify=False, + auth=(username, password) + ) cteward = r.json() - return render(request, 'memberstatus.html', {'contributions': contributions, 'cteward': cteward}) - - + return render( + request, 'memberstatus.html', + { + 'contributions': contributions, + 'cteward': cteward + } + )