From bc0258ea8f54c11269904728030727169ffccda3 Mon Sep 17 00:00:00 2001 From: cmile Date: Wed, 3 Oct 2018 00:16:28 +0200 Subject: [PATCH] upgrade to django 1.11.16 and python3.6 --- Dockerfile | 16 +++++++++++ account/cbase_members.py | 38 ++++++++++++++++--------- account/models.py | 2 +- account/password_encryption.py | 2 +- account/templates/base.html | 3 +- account/templates/hammertime.html | 3 +- account/tests.py | 4 +-- account/urls.py | 39 +++++++++++++------------- account/views.py | 25 ++++++++--------- cbapi_ldap/urls.py | 11 ++++---- cbmi/cbmi.db | Bin 0 -> 151552 bytes cbmi/settings.py | 45 ++++++++++++++++++++++-------- cbmi/urls.py | 15 +++++----- pop_members.py | 4 +-- requirements.txt | 15 +++++----- smbpasswd.py | 7 +++++ start | 10 +++++++ 17 files changed, 155 insertions(+), 84 deletions(-) create mode 100644 Dockerfile create mode 100644 cbmi/cbmi.db create mode 100644 smbpasswd.py create mode 100755 start diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..abceb94 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.6 + +VOLUME /opt/cbmi + +RUN apt-get update && apt-get install -y libsasl2-dev python-dev libldap2-dev libssl-dev + +ADD requirements.txt /requirements.txt +RUN pip install --upgrade -r /requirements.txt + +RUN ls /opt/cbmi + +EXPOSE 8000 +ENTRYPOINT ["/opt/cbmi/start"] + + + diff --git a/account/cbase_members.py b/account/cbase_members.py index b9ef86e..a9d0039 100644 --- a/account/cbase_members.py +++ b/account/cbase_members.py @@ -5,7 +5,7 @@ import ldap import copy from django.conf import settings -from password_encryption import get_ldap_password +from account.password_encryption import get_ldap_password """ Example configuration: @@ -14,11 +14,12 @@ CBASE_LDAP_URL = 'ldap://lea.cbrp3.c-base.org:389/' CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org' """ + def retrieve_member(request): ldap_password = get_ldap_password(request) session = dict(request.session) - print "session:", session - print "cookies:", request.COOKIES + print("session:", session) + print("cookies:", request.COOKIES) return MemberValues(request.user.username, ldap_password) @@ -26,6 +27,7 @@ class MemberValues(object): """ Dictionary-like abstraction of the c-base member attributes. """ + def __init__(self, username, password): self._username = username self._password = password @@ -42,6 +44,9 @@ class MemberValues(object): else: value = default + if value is not None: + value = value.decode() + # Decode if value == 'TRUE': return True @@ -79,7 +84,7 @@ class MemberValues(object): action = ldap.MOD_REPLACE if new_key not in self._old.keys(): action = ldap.MOD_ADD - mod_attrs.append((action, '%s' % new_key, new_value )) + mod_attrs.append((action, '%s' % new_key, new_value)) continue if self._old[new_key][0] != None and new_value == [None]: action = ldap.MOD_DELETE @@ -88,14 +93,13 @@ class MemberValues(object): # Set the attribute and wait for the LDAP server to complete. if self._old[new_key][0] != new_value[0]: action = ldap.MOD_REPLACE - mod_attrs.append((action, '%s' % new_key, new_value )) + mod_attrs.append((action, '%s' % new_key, new_value)) continue - - print "modattrs: ",mod_attrs + print("modattrs: ", mod_attrs) result = l.modify_s(dn, mod_attrs) # - # print "result is: ", result + # print("result is: ", result) l.unbind_s() def change_password(self, new_password): @@ -142,9 +146,10 @@ class MemberValues(object): searchFilter = "uid=%s" % self._username dn = settings.CBASE_BASE_DN - result = session.search_s(dn, searchScope, searchFilter, retrieveAttributes) + result = session.search_s( + dn, searchScope, searchFilter, retrieveAttributes) # TODO: latin1 - print "result is: ", result + print("result is: ", result) # TODO: if len(result)==0 session.unbind_s() return result[0][1] @@ -176,7 +181,7 @@ class MemberValues(object): l.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) + "memberOf=cn=crew,ou=groups,dc=c-base,dc=org", None) result_set = [] while True: result_type, result_data = l.result(result_id, 0) @@ -187,7 +192,14 @@ class MemberValues(object): result_set.append(result_data) # list comprehension to get a list of user tupels in the format ("nickname", "nickname (real name)") - userlist = [(x[0][1]['uid'][0], '%s (%s, %s)' % (x[0][1]['uid'][0], x[0][1]['cn'][0], x[0][1]['uidNumber'][0])) for x in result_set] + userlist = [( + x[0][1]['uid'][0].decode(), + '%s (%s, %s)' % ( + x[0][1]['uid'][0].decode(), + x[0][1]['cn'][0].decode(), + x[0][1]['uidNumber'][0].decode() + ) + ) for x in result_set] return sorted(userlist) - except: + except Exception: return [] diff --git a/account/models.py b/account/models.py index 72984e0..9db847a 100644 --- a/account/models.py +++ b/account/models.py @@ -4,7 +4,7 @@ from django.db.models import signals from account.signals import create_profile, delete_profile class UserProfile(models.Model): - user = models.OneToOneField(User, editable=False) + user = models.OneToOneField(User, editable=False, on_delete=models.CASCADE) uid = models.CharField(verbose_name="User-ID", max_length=8, null=True, diff --git a/account/password_encryption.py b/account/password_encryption.py index 0c4138c..d18938e 100644 --- a/account/password_encryption.py +++ b/account/password_encryption.py @@ -26,7 +26,7 @@ def encrypt_ldap_password(cleartext_pw): # do the encryption aes = AES.new(key, AES.MODE_CFB, iv) message = iv + aes.encrypt(cleartext_pw) - return base64.b64encode(message), base64.b64encode(key) + return base64.b64encode(message).decode(), base64.b64encode(key).decode() def decrypt_ldap_password(message, key): """ diff --git a/account/templates/base.html b/account/templates/base.html index e80b77e..393bc84 100644 --- a/account/templates/base.html +++ b/account/templates/base.html @@ -1,5 +1,6 @@ {% load i18n %} {% load crispy_forms_tags %} +{% load static from staticfiles %} @@ -66,7 +67,7 @@ + src="{% static 'img/logo.gif' %}" /> {% trans "member interface" %} diff --git a/account/tests.py b/account/tests.py index 078a96a..ac863db 100644 --- a/account/tests.py +++ b/account/tests.py @@ -19,8 +19,8 @@ class PasswordEncryptionTest(TestCase): def test_encrypt_ldap_password(self): message, key = self.encrypt_it() - print 'key:', key - print 'message:', message + print('key:', key) + print('message:', message) def test_decrypt_ldap_password(self): diff --git a/account/urls.py b/account/urls.py index 52882ae..a5f919e 100644 --- a/account/urls.py +++ b/account/urls.py @@ -1,20 +1,21 @@ -from django.conf.urls import patterns, url +from account.views import (admin, auth_login, auth_logout, clabpin, gastropin, + groups_list, home, memberstatus, nrf24, password, + preferred_email, rfid, sippin, wlan_presence) +from django.conf.urls import url - -urlpatterns = patterns( - '', - url(r'^login/$', 'account.views.auth_login', name="cbase_auth_login"), - url(r'^logout/$', 'account.views.auth_logout', name="auth_logout"), - url(r'^gastropin/$', 'account.views.gastropin', name='gastropin'), - url(r'^wlan_presence/$', 'account.views.wlan_presence', name='wlan_presence'), - url(r'^rfid/$', 'account.views.rfid', name='rfid'), - url(r'^nrf24/$', 'account.views.nrf24', name='nrf24'), - 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'^preferred_email/$', 'account.views.preferred_email', name='preferred_email'), - url(r'^admin/$', 'account.views.admin', name='admin'), - url(r'^memberstatus/$', 'account.views.memberstatus', name='memberstatus'), - url(r'^$', 'account.views.home', name="home"), - url(r'^groups/(?P[^/]+)/', 'account.views.groups_list'), -) +urlpatterns = [ + url(r'^login/$', auth_login, name="cbase_auth_login"), + url(r'^logout/$', auth_logout, name="auth_logout"), + url(r'^gastropin/$', gastropin, name='gastropin'), + url(r'^wlan_presence/$', wlan_presence, name='wlan_presence'), + url(r'^rfid/$', rfid, name='rfid'), + url(r'^nrf24/$', nrf24, name='nrf24'), + url(r'^password/$', password, name='password'), + url(r'^sippin/$', sippin, name='sippin'), + url(r'^clabpin/$', clabpin, name='clabpin'), + url(r'^preferred_email/$', preferred_email, name='preferred_email'), + url(r'^admin/$', admin, name='admin'), + url(r'^memberstatus/$', memberstatus, name='memberstatus'), + url(r'^$', home, name="home"), + url(r'^groups/(?P[^/]+)/', groups_list), +] diff --git a/account/views.py b/account/views.py index 3b610e5..065fa06 100644 --- a/account/views.py +++ b/account/views.py @@ -19,13 +19,13 @@ from django.contrib.auth.models import Group from django.shortcuts import render from django.utils.translation import ugettext as _ -from forms import GastroPinForm, WlanPresenceForm, LoginForm, PasswordForm, \ +from account.forms import GastroPinForm, WlanPresenceForm, LoginForm, PasswordForm, \ RFIDForm, NRF24Form, SIPPinForm, CLabPinForm, AdminForm, PreferredEmailForm -from cbase_members import retrieve_member, MemberValues -from password_encryption import * +from account.cbase_members import retrieve_member, MemberValues +from account.password_encryption import * def landingpage(request): - if request.user.is_authenticated(): + if request.user.is_authenticated: return HttpResponseRedirect('/account') login_form = LoginForm() try: @@ -77,8 +77,7 @@ def auth_login(request): else: form = LoginForm() - return render_to_response('login.html', - RequestContext(request, locals())) + return render_to_response('login.html', locals()) @login_required def home(request): @@ -88,13 +87,13 @@ def home(request): username = request.user.username url = "https://vorstand.c-base.org/cteward-api/legacy/member/%s" % username cteward = None - #try: - #r = requests.get(url, verify=False, auth=(username, password)) - #cteward = r.json() - #except: - #pass + try: + r = requests.get(url, verify=False, auth=(username, password)) + cteward = r.json() + except Exception: + pass context = {'member': member.to_dict(), - 'groups': sorted(list(request.user.groups.all())), + 'groups': list(request.user.groups.all().order_by('name')), 'number_of_members': number_of_members, 'cteward': cteward, } @@ -137,7 +136,7 @@ def set_hash_field(request, form_type, in_field, out_field, hash_func, form = form_type(request.POST) if form.is_valid(): hashed_value = hash_func(form.cleaned_data[in_field]) - print 'hashed value: ', hashed_value + print('hashed value: ', hashed_value) member.set(out_field, hashed_value) member.save() new_form = form_type(initial=initial) diff --git a/cbapi_ldap/urls.py b/cbapi_ldap/urls.py index bb83b0b..478f5b8 100644 --- a/cbapi_ldap/urls.py +++ b/cbapi_ldap/urls.py @@ -1,9 +1,10 @@ -from django.conf.urls import patterns, url +from django.conf.urls import url from jsonrpc import jsonrpc_site +from jsonrpc.views import browse from cbapi_ldap import views -urlpatterns = patterns( - '', - url(r'^ldap/browse/$', 'jsonrpc.views.browse', name='jsonrpc_browser'), + +urlpatterns = [ + url(r'^ldap/browse/$', browse, name='jsonrpc_browser'), url(r'^ldap/$', jsonrpc_site.dispatch, name='jsonrpc_mountpoint'), -) +] diff --git a/cbmi/cbmi.db b/cbmi/cbmi.db new file mode 100644 index 0000000000000000000000000000000000000000..7f2b0cdf6dfe20d01a5705627bff704117bd261c GIT binary patch literal 151552 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.11.16 #MySQL-python==1.2.5 -django-auth-ldap==1.2.6 -django-json-rpc -django-crispy-forms==1.5.2 -pycrypto==2.6.1 -smbpasswd==1.0.2 -requests==2.8.0 +django-auth-ldap>=1.7.0 +django-json-rpc>=0.7.2 +django-crispy-forms>=1.7.2 +gunicorn>=19.9.0 +pycrypto>=2.6.1 +passlib +requests>=2.19.1 diff --git a/smbpasswd.py b/smbpasswd.py new file mode 100644 index 0000000..41f0d6f --- /dev/null +++ b/smbpasswd.py @@ -0,0 +1,7 @@ +import passlib.hash + +def lmhash(s): + return passlib.hash.lmhash.encrypt(s).upper() + +def nthash(s): + return passlib.hash.nthash.encrypt(s).upper() diff --git a/start b/start new file mode 100755 index 0000000..9179ec5 --- /dev/null +++ b/start @@ -0,0 +1,10 @@ +#! /bin/bash + +cd /opt/cbmi + +python /opt/cbmi/manage.py makemigrations +python /opt/cbmi/manage.py migrate + +echo "from django.contrib.auth.models import User; User.objects.filter(email='admin@example.com').delete(); User.objects.create_superuser('admin', 'admin@example.com', 'fooderbar23')" | python /opt/cbmi/manage.py shell + +python /opt/cbmi/manage.py runserver 0.0.0.0:8000