upgrade to django 1.11.16 and python3.6

This commit is contained in:
cmile 2018-10-03 00:16:28 +02:00
parent b32465e85f
commit bc0258ea8f
17 changed files with 155 additions and 84 deletions

16
Dockerfile Normal file
View file

@ -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"]

View file

@ -5,7 +5,7 @@ import ldap
import copy import copy
from django.conf import settings from django.conf import settings
from password_encryption import get_ldap_password from account.password_encryption import get_ldap_password
""" """
Example configuration: 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' CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org'
""" """
def retrieve_member(request): def retrieve_member(request):
ldap_password = get_ldap_password(request) ldap_password = get_ldap_password(request)
session = dict(request.session) session = dict(request.session)
print "session:", session print("session:", session)
print "cookies:", request.COOKIES print("cookies:", request.COOKIES)
return MemberValues(request.user.username, ldap_password) return MemberValues(request.user.username, ldap_password)
@ -26,6 +27,7 @@ class MemberValues(object):
""" """
Dictionary-like abstraction of the c-base member attributes. Dictionary-like abstraction of the c-base member attributes.
""" """
def __init__(self, username, password): def __init__(self, username, password):
self._username = username self._username = username
self._password = password self._password = password
@ -42,6 +44,9 @@ class MemberValues(object):
else: else:
value = default value = default
if value is not None:
value = value.decode()
# Decode # Decode
if value == 'TRUE': if value == 'TRUE':
return True return True
@ -79,7 +84,7 @@ class MemberValues(object):
action = ldap.MOD_REPLACE action = ldap.MOD_REPLACE
if new_key not in self._old.keys(): if new_key not in self._old.keys():
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[new_key][0] != None and new_value == [None]:
action = ldap.MOD_DELETE action = ldap.MOD_DELETE
@ -88,14 +93,13 @@ class MemberValues(object):
# Set the attribute and wait for the LDAP server to complete. # Set the attribute and wait for the LDAP server to complete.
if self._old[new_key][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)
print "modattrs: ",mod_attrs
result = l.modify_s(dn, mod_attrs) result = l.modify_s(dn, mod_attrs)
# #
# print "result is: ", result # print("result is: ", result)
l.unbind_s() l.unbind_s()
def change_password(self, new_password): def change_password(self, new_password):
@ -142,9 +146,10 @@ class MemberValues(object):
searchFilter = "uid=%s" % self._username searchFilter = "uid=%s" % self._username
dn = settings.CBASE_BASE_DN dn = settings.CBASE_BASE_DN
result = session.search_s(dn, searchScope, searchFilter, retrieveAttributes) result = session.search_s(
dn, searchScope, searchFilter, retrieveAttributes)
# TODO: latin1 # TODO: latin1
print "result is: ", result print("result is: ", 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]
@ -187,7 +192,14 @@ class MemberValues(object):
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 = [(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) return sorted(userlist)
except: except Exception:
return [] return []

View file

@ -4,7 +4,7 @@ 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) user = models.OneToOneField(User, editable=False, on_delete=models.CASCADE)
uid = models.CharField(verbose_name="User-ID", uid = models.CharField(verbose_name="User-ID",
max_length=8, max_length=8,
null=True, null=True,

View file

@ -26,7 +26,7 @@ def encrypt_ldap_password(cleartext_pw):
# do the encryption # do the encryption
aes = AES.new(key, AES.MODE_CFB, iv) aes = AES.new(key, AES.MODE_CFB, iv)
message = iv + aes.encrypt(cleartext_pw) 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): def decrypt_ldap_password(message, key):
""" """

View file

@ -1,5 +1,6 @@
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load static from staticfiles %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de"> <html lang="de">
@ -66,7 +67,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
</a> </a>
<span class="brand"><a href="/"><img style="margin-top: -10px;" <span class="brand"><a href="/"><img style="margin-top: -10px;"
src="{{ STATIC_URL }}img/logo.gif" /></a> src="{% static 'img/logo.gif' %}" /></a>
<a href="/">{% trans "member interface" %}</a> <a href="/">{% trans "member interface" %}</a>
</span> </span>
<div class="nav-collapse collapse"> <div class="nav-collapse collapse">

View file

@ -11,7 +11,8 @@
<div class="row"> <div class="row">
<div class="text-center span4 offset4" style="background-color: #eee;"> <div class="text-center span4 offset4" style="background-color: #eee;">
<img src="{{ STATIC_URL }}img/mchammer.gif" /> <img src='{% static "img/mchammer.gif" %}' />
</div> </div>
</div> </div>
</div> </div>

View file

@ -19,8 +19,8 @@ class PasswordEncryptionTest(TestCase):
def test_encrypt_ldap_password(self): def test_encrypt_ldap_password(self):
message, key = self.encrypt_it() message, key = self.encrypt_it()
print 'key:', key print('key:', key)
print 'message:', message print('message:', message)
def test_decrypt_ldap_password(self): def test_decrypt_ldap_password(self):

View file

@ -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 = [
urlpatterns = patterns( url(r'^login/$', auth_login, name="cbase_auth_login"),
'', url(r'^logout/$', auth_logout, name="auth_logout"),
url(r'^login/$', 'account.views.auth_login', name="cbase_auth_login"), url(r'^gastropin/$', gastropin, name='gastropin'),
url(r'^logout/$', 'account.views.auth_logout', name="auth_logout"), url(r'^wlan_presence/$', wlan_presence, name='wlan_presence'),
url(r'^gastropin/$', 'account.views.gastropin', name='gastropin'), url(r'^rfid/$', rfid, name='rfid'),
url(r'^wlan_presence/$', 'account.views.wlan_presence', name='wlan_presence'), url(r'^nrf24/$', nrf24, name='nrf24'),
url(r'^rfid/$', 'account.views.rfid', name='rfid'), url(r'^password/$', password, name='password'),
url(r'^nrf24/$', 'account.views.nrf24', name='nrf24'), url(r'^sippin/$', sippin, name='sippin'),
url(r'^password/$', 'account.views.password', name='password'), url(r'^clabpin/$', clabpin, name='clabpin'),
url(r'^sippin/$', 'account.views.sippin', name='sippin'), url(r'^preferred_email/$', preferred_email, name='preferred_email'),
url(r'^clabpin/$', 'account.views.clabpin', name='clabpin'), url(r'^admin/$', admin, name='admin'),
url(r'^preferred_email/$', 'account.views.preferred_email', name='preferred_email'), url(r'^memberstatus/$', memberstatus, name='memberstatus'),
url(r'^admin/$', 'account.views.admin', name='admin'), url(r'^$', home, name="home"),
url(r'^memberstatus/$', 'account.views.memberstatus', name='memberstatus'), url(r'^groups/(?P<group_name>[^/]+)/', groups_list),
url(r'^$', 'account.views.home', name="home"), ]
url(r'^groups/(?P<group_name>[^/]+)/', 'account.views.groups_list'),
)

View file

@ -19,13 +19,13 @@ from django.contrib.auth.models import Group
from django.shortcuts import render from django.shortcuts import render
from django.utils.translation import ugettext as _ 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 RFIDForm, NRF24Form, SIPPinForm, CLabPinForm, AdminForm, PreferredEmailForm
from cbase_members import retrieve_member, MemberValues from account.cbase_members import retrieve_member, MemberValues
from 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')
login_form = LoginForm() login_form = LoginForm()
try: try:
@ -77,8 +77,7 @@ def auth_login(request):
else: else:
form = LoginForm() form = LoginForm()
return render_to_response('login.html', return render_to_response('login.html', locals())
RequestContext(request, locals()))
@login_required @login_required
def home(request): def home(request):
@ -88,13 +87,13 @@ def home(request):
username = request.user.username username = request.user.username
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: except Exception:
#pass pass
context = {'member': member.to_dict(), 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, 'number_of_members': number_of_members,
'cteward': cteward, 'cteward': cteward,
} }
@ -137,7 +136,7 @@ def set_hash_field(request, form_type, in_field, out_field, hash_func,
form = form_type(request.POST) form = form_type(request.POST)
if form.is_valid(): if form.is_valid():
hashed_value = hash_func(form.cleaned_data[in_field]) 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.set(out_field, hashed_value)
member.save() member.save()
new_form = form_type(initial=initial) new_form = form_type(initial=initial)

View file

@ -1,9 +1,10 @@
from django.conf.urls import patterns, url from django.conf.urls import url
from jsonrpc import jsonrpc_site from jsonrpc import jsonrpc_site
from jsonrpc.views import browse
from cbapi_ldap import views from cbapi_ldap import views
urlpatterns = patterns(
'', urlpatterns = [
url(r'^ldap/browse/$', 'jsonrpc.views.browse', name='jsonrpc_browser'), url(r'^ldap/browse/$', browse, name='jsonrpc_browser'),
url(r'^ldap/$', jsonrpc_site.dispatch, name='jsonrpc_mountpoint'), url(r'^ldap/$', jsonrpc_site.dispatch, name='jsonrpc_mountpoint'),
) ]

BIN
cbmi/cbmi.db Normal file

Binary file not shown.

View file

@ -1,4 +1,5 @@
# Django settings for cbmi project. # Django settings for cbmi project.
import os
DEBUG = True DEBUG = True
TEMPLATE_DEBUG = DEBUG TEMPLATE_DEBUG = DEBUG
@ -10,14 +11,17 @@ ADMINS = (
MANAGERS = ADMINS MANAGERS = ADMINS
PROJECT_DIR = os.path.abspath(os.path.dirname(__file__))
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.mysql', # 'ENGINE': 'django.db.backends.mysql',
'NAME': 'cbmi', # 'NAME': 'cbmi',
'USER': 'cbmi', # 'USER': 'cbmi',
'PASSWORD': 'cbmi', # 'PASSWORD': 'cbmi',
'HOST': '', # 'HOST': '',
'PORT': '', # 'PORT': '',
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_DIR, 'cbmi.db'),
} }
} }
@ -69,6 +73,7 @@ STATICFILES_DIRS = (
# Always use forward slashes, even on Windows. # Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths. # Don't forget to use absolute paths, not relative paths.
'/home/cbmi/cbmi/static', '/home/cbmi/cbmi/static',
'/opt/cbmi/static',
) )
# List of finder classes that know how to find static files in # List of finder classes that know how to find static files in
@ -99,15 +104,14 @@ TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.request" "django.core.context_processors.request"
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE = [
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection: 'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
)
ROOT_URLCONF = 'cbmi.urls' ROOT_URLCONF = 'cbmi.urls'
@ -120,6 +124,23 @@ TEMPLATE_DIRS = (
# Don't forget to use absolute paths, not relative paths. # Don't forget to use absolute paths, not relative paths.
) )
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'builtins': [],
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
import ldap import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
@ -230,5 +251,5 @@ LOGIN_URL = '/account/login/'
try: try:
from local_settings import * from local_settings import *
except ImportError, e: except ImportError as e:
print 'Unable to load local_settings.py:', e print('Unable to load local_settings.py:', e)

View file

@ -1,17 +1,18 @@
from django.conf.urls import patterns, include, url from django.conf.urls import include, url
from django.contrib import admin from django.contrib import admin
from account.views import hammertime, landingpage
admin.autodiscover() admin.autodiscover()
urlpatterns = patterns('', urlpatterns = [
url(r'^stop/hammertime/$', 'account.views.hammertime', name="hammertime"),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^stop/hammertime/$', hammertime, name="hammertime"),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', admin.site.urls),
url(r'^cbapi/', include("cbapi_ldap.urls")), url(r'^cbapi/', include("cbapi_ldap.urls")),
url(r'account/', include('account.urls')), url(r'account/', include('account.urls')),
url(r'^$', 'account.views.landingpage', name="landingpage"), url(r'^$', landingpage, name="landingpage"),
) ]

View file

@ -57,6 +57,6 @@ def populate_members():
for m in sorted(all_members()): for m in sorted(all_members()):
member = LDAPBackend().populate_user(m) member = LDAPBackend().populate_user(m)
if member: if member:
print 'Populated: %s' % member print('Populated: %s' % member)
else: else:
print 'Not found: %s' % m print('Not found: %s' % m)

View file

@ -1,8 +1,9 @@
Django==1.8.4 Django>=1.11.16
#MySQL-python==1.2.5 #MySQL-python==1.2.5
django-auth-ldap==1.2.6 django-auth-ldap>=1.7.0
django-json-rpc django-json-rpc>=0.7.2
django-crispy-forms==1.5.2 django-crispy-forms>=1.7.2
pycrypto==2.6.1 gunicorn>=19.9.0
smbpasswd==1.0.2 pycrypto>=2.6.1
requests==2.8.0 passlib
requests>=2.19.1

7
smbpasswd.py Normal file
View file

@ -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()

10
start Executable file
View file

@ -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