add ldap authentication and function to create ldap user on signup
This commit is contained in:
parent
be949448c5
commit
eab9d7b714
15 changed files with 154 additions and 2 deletions
|
@ -1,2 +1,6 @@
|
||||||
DEBUG=True
|
DEBUG=True
|
||||||
ALLOWED_HOSTS=.localhost, .ipv6.work
|
ALLOWED_HOSTS=.localhost, .ipv6.work
|
||||||
|
AUTH_LDAP_SERVER_URI=ldap://<ldap_host>
|
||||||
|
AUTH_LDAP_BIND_DN=cn=admin,dc=example,dc=com
|
||||||
|
AUTH_LDAP_BIND_PASSWORD=admin
|
||||||
|
AUTH_LDAP_USER_DN_TEMPLATE=uid=%(user)s,ou=users,dc=example,dc=com
|
10
README.md
10
README.md
|
@ -1,5 +1,13 @@
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
django-auth-ldap requires `openldap-devel`
|
||||||
|
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
docker build -t ipv6dotwork .
|
docker build -t ipv6dotwork .
|
||||||
|
|
||||||
sudo docker rm -f ipv6dotwork
|
sudo docker rm -f ipv6dotwork
|
||||||
|
|
||||||
sudo docker run -d -p 127.0.0.1:8001:8000 --env-file .env --name ipv6dotwork ipv6dotwork
|
sudo docker run -d -p 127.0.0.1:8001:8000 --env-file .env --name ipv6dotwork ipv6dotwork
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ INSTALLED_APPS += [
|
||||||
# Our apps
|
# Our apps
|
||||||
INSTALLED_APPS += [
|
INSTALLED_APPS += [
|
||||||
'jobs',
|
'jobs',
|
||||||
|
'users',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -120,7 +121,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = (
|
AUTHENTICATION_BACKENDS = (
|
||||||
'rules.permissions.ObjectPermissionBackend',
|
'rules.permissions.ObjectPermissionBackend',
|
||||||
'django.contrib.auth.backends.ModelBackend',
|
'django_auth_ldap.backend.LDAPBackend',
|
||||||
)
|
)
|
||||||
|
|
||||||
LOGIN_REDIRECT_URL = '/'
|
LOGIN_REDIRECT_URL = '/'
|
||||||
|
@ -153,3 +154,30 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles/')
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
|
|
||||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
|
|
||||||
|
|
||||||
|
AUTH_LDAP_SERVER_URI = config('AUTH_LDAP_SERVER_URI')
|
||||||
|
AUTH_LDAP_BIND_DN = config('AUTH_LDAP_BIND_DN')
|
||||||
|
AUTH_LDAP_BIND_PASSWORD = config('AUTH_LDAP_BIND_PASSWORD')
|
||||||
|
AUTH_LDAP_USER_DN_TEMPLATE = config('AUTH_LDAP_USER_DN_TEMPLATE')
|
||||||
|
AUTH_LDAP_USER_ATTR_MAP = {
|
||||||
|
'first_name': 'givenName',
|
||||||
|
'last_name': 'sn',
|
||||||
|
'email': 'mail',
|
||||||
|
}
|
||||||
|
AUTH_LDAP_ALWAYS_UPDATE_USER = True
|
||||||
|
LOGGING = {
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'version': 1,
|
||||||
|
'handlers': {
|
||||||
|
'console': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'django_auth_ldap': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'handlers': ['console'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ from django.contrib import admin
|
||||||
from django.urls import path, include, re_path
|
from django.urls import path, include, re_path
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
|
|
||||||
|
from users.views import signup
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(
|
re_path(
|
||||||
'login/',
|
'login/',
|
||||||
|
@ -27,6 +29,7 @@ urlpatterns = [
|
||||||
'logout/',
|
'logout/',
|
||||||
auth_views.LogoutView.as_view(),
|
auth_views.LogoutView.as_view(),
|
||||||
name='logout'),
|
name='logout'),
|
||||||
|
path('signup/', signup),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('', include('jobs.urls'))
|
path('', include('jobs.urls'))
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,3 +3,4 @@ django-crispy-forms==1.7.2
|
||||||
git+https://github.com/yourlabs/django-autocomplete-light.git#egg=django-autocomplete-light
|
git+https://github.com/yourlabs/django-autocomplete-light.git#egg=django-autocomplete-light
|
||||||
rules==2.0
|
rules==2.0
|
||||||
python-decouple==3.1
|
python-decouple==3.1
|
||||||
|
ldap3==2.5.1
|
||||||
|
|
0
users/__init__.py
Normal file
0
users/__init__.py
Normal file
3
users/admin.py
Normal file
3
users/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
5
users/apps.py
Normal file
5
users/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class UsersConfig(AppConfig):
|
||||||
|
name = 'users'
|
19
users/forms.py
Normal file
19
users/forms.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
class SignUpForm(UserCreationForm):
|
||||||
|
first_name = forms.CharField(
|
||||||
|
max_length=30, required=False, help_text='Optional.')
|
||||||
|
last_name = forms.CharField(
|
||||||
|
max_length=30, required=False, help_text='Optional.')
|
||||||
|
email = forms.EmailField(
|
||||||
|
max_length=254, help_text='Required. Inform a valid email address.')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ('username', 'first_name', 'last_name',
|
||||||
|
'email', 'password1', 'password2', )
|
28
users/ldap_funcs.py
Normal file
28
users/ldap_funcs.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from ldap3 import Server, ServerPool, Connection, ObjectDef, AttrDef, Reader, Writer
|
||||||
|
|
||||||
|
server = Server(settings.AUTH_LDAP_SERVER_URI)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def create_user(user, password, firstname, lastname, email):
|
||||||
|
conn = Connection(server, settings.AUTH_LDAP_BIND_DN,
|
||||||
|
settings.AUTH_LDAP_BIND_PASSWORD)
|
||||||
|
if not conn.bind():
|
||||||
|
raise Exception('Could not connect to LDAP Server')
|
||||||
|
obj_new_user = ObjectDef(
|
||||||
|
['inetOrgPerson'], conn)
|
||||||
|
w = Writer(conn, obj_new_user)
|
||||||
|
dn = 'uid=%s,ou=users,dc=example,dc=com' % user
|
||||||
|
w.new(dn)
|
||||||
|
w[0].givenName = firstname
|
||||||
|
w[0].sn = lastname
|
||||||
|
w[0].cn = firstname + " " + lastname
|
||||||
|
w[0].mail = email
|
||||||
|
w[0].userPassword = password
|
||||||
|
|
||||||
|
if not w.commit():
|
||||||
|
conn.unbind()
|
||||||
|
raise Exception("Couldn't write user")
|
||||||
|
conn.unbind()
|
||||||
|
return True
|
0
users/migrations/__init__.py
Normal file
0
users/migrations/__init__.py
Normal file
3
users/models.py
Normal file
3
users/models.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
21
users/templates/users/signup.html
Normal file
21
users/templates/users/signup.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block body_content %}
|
||||||
|
<h2>Sign up</h2>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
<p>
|
||||||
|
{{ field.label_tag }}<br>
|
||||||
|
{{ field }}
|
||||||
|
{% if field.help_text %}
|
||||||
|
<small style="color: grey">{{ field.help_text }}</small>
|
||||||
|
{% endif %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<p style="color: red">{{ error }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Sign up</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
3
users/tests.py
Normal file
3
users/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
26
users/views.py
Normal file
26
users/views.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import login, authenticate
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
from .forms import SignUpForm
|
||||||
|
from .ldap_funcs import create_user
|
||||||
|
|
||||||
|
|
||||||
|
def signup(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = SignUpForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
username = form.cleaned_data.get('username')
|
||||||
|
raw_password = form.cleaned_data.get('password1')
|
||||||
|
first_name = form.cleaned_data.get('first_name')
|
||||||
|
last_name = form.cleaned_data.get('last_name')
|
||||||
|
email = form.cleaned_data.get('email')
|
||||||
|
create_user(username, raw_password, first_name, last_name, email)
|
||||||
|
form.save()
|
||||||
|
user = authenticate(username=username, password=raw_password)
|
||||||
|
login(request, user, backend='django_auth_ldap.backend.LDAPBackend')
|
||||||
|
return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
|
||||||
|
else:
|
||||||
|
form = SignUpForm()
|
||||||
|
return render(request, 'users/signup.html', {'form': form})
|
Loading…
Reference in a new issue