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