Ldap server integration
This commit is contained in:
parent
1ae785acf3
commit
54a90f8359
|
@ -8,4 +8,6 @@ staticfiles/*
|
||||||
cache/
|
cache/
|
||||||
celerybeat-schedule
|
celerybeat-schedule
|
||||||
celerybeat.pid
|
celerybeat.pid
|
||||||
.minio.sys
|
.minio.sys
|
||||||
|
buckets
|
||||||
|
*.pyc
|
||||||
|
|
22
README.org
22
README.org
|
@ -111,6 +111,14 @@ Setup / create new certs
|
||||||
letsencrypt certonly --renew --webroot -w /var/www/.well-known -d stage.maidstone-hackspace.org.uk
|
letsencrypt certonly --renew --webroot -w /var/www/.well-known -d stage.maidstone-hackspace.org.uk
|
||||||
letsencrypt certonly --webroot -w /var/www/.well-known -d stage.maidstone-hackspace.org.uk
|
letsencrypt certonly --webroot -w /var/www/.well-known -d stage.maidstone-hackspace.org.uk
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
Automation of renewal process
|
||||||
|
create a file called =/etc/cron.monthly/letsencrypt-renew.sh= and make it executable with chmod +x, then place your above commands in the file like in the example below.
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
#!/bin/bash
|
||||||
|
letsencrypt certonly --webroot --renew-by-default --agree-tos -w /var/www/.well-known -d stage.maidstone-hackspace.org.uk
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
*** Postgres tips
|
*** Postgres tips
|
||||||
Connect to the database inside container to run sql commands.
|
Connect to the database inside container to run sql commands.
|
||||||
#+BEGIN_SRC bash
|
#+BEGIN_SRC bash
|
||||||
|
@ -139,3 +147,17 @@ letsencrypt config
|
||||||
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
sudo chmod -R a+rX static/
|
sudo chmod -R a+rX static/
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(let ((default-directory "/docker:hackdev_django_1:/app"))
|
||||||
|
(python-shell-make-comint "python manage.py shell" "Python" 'show))
|
||||||
|
#+END_SRC
|
||||||
|
** Test
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq python-shell-interpreter "/docker:hackdev_django_1:/usr/local/bin/python")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: /docker:hackdev_django_1:/usr/local/bin/python
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,7 @@ LOCAL_APPS = (
|
||||||
'mhackspace.core',
|
'mhackspace.core',
|
||||||
'mhackspace.requests',
|
'mhackspace.requests',
|
||||||
'mhackspace.register',
|
'mhackspace.register',
|
||||||
|
'mhackspace.ldapsync',
|
||||||
'mhackspace.rfid',
|
'mhackspace.rfid',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -344,10 +345,10 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
|
||||||
# PASSWORD HASHING
|
# PASSWORD HASHING
|
||||||
PASSWORD_HASHERS = [
|
PASSWORD_HASHERS = [
|
||||||
|
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
|
||||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -538,3 +539,7 @@ CACHES = {
|
||||||
'TIMEOUT': None
|
'TIMEOUT': None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LDAP_SERVER = env('LDAP_SERVER', default='172.19.0.6')
|
||||||
|
LDAP_PASSWORD = env('LDAP_ADMIN_PASSWORD', default='secretldappassword')
|
||||||
|
LDAP_ROOT = env('LDAP_ROOT', default='dc=maidstone-hackspace, dc=org, dc=uk')
|
||||||
|
|
|
@ -12,7 +12,7 @@ TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
|
||||||
# INTERNAL_IPS = ['127.0.0.1', '10.0.2.2', '172.22.0.9', '192.168.1.113', '172.22.0.4', '0.0.0.0']
|
# INTERNAL_IPS = ['127.0.0.1', '10.0.2.2', '172.22.0.9', '192.168.1.113', '172.22.0.4', '0.0.0.0']
|
||||||
# tricks to have debug toolbar when developing with docker
|
# tricks to have debug toolbar when developing with docker
|
||||||
if os.environ.get('USE_DOCKER') == 'yes':
|
if os.environ.get('USE_DOCKER') == 'yes':
|
||||||
ip = socket.gethostbyname('nginx')
|
# ip = socket.gethostbyname('nginx')
|
||||||
INTERNAL_IPS += [ip[:-1] + "1"]
|
INTERNAL_IPS += [ip[:-1] + "1"]
|
||||||
ip = socket.gethostbyname(socket.gethostname())
|
ip = socket.gethostbyname(socket.gethostname())
|
||||||
INTERNAL_IPS += [ip[:-1] + "1"]
|
INTERNAL_IPS += [ip[:-1] + "1"]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#rename me to .env, and change per environment, .env should not be commited contains
|
#rename me to .env, and change per environment, .env should not be commited contains
|
||||||
#sensitive settings
|
#sensitive settings
|
||||||
|
#Python config
|
||||||
|
PYTHONPATH=/app/
|
||||||
|
|
||||||
#for dev only
|
#for dev only
|
||||||
USE_DOCKER_DEBUG=yes
|
USE_DOCKER_DEBUG=yes
|
||||||
|
@ -58,3 +60,10 @@ MATRIX_PASSWORD=
|
||||||
|
|
||||||
MINIO_ACCESS_KEY=thing
|
MINIO_ACCESS_KEY=thing
|
||||||
MINIO_SECRET_KEY=thing
|
MINIO_SECRET_KEY=thing
|
||||||
|
|
||||||
|
# LDAP Service
|
||||||
|
LDAP_ORGANISATION=Maidstone Hackspace
|
||||||
|
LDAP_DOMAIN=maidstone-hackspace.org.uk
|
||||||
|
LDAP_ADMIN_PASSWORD=secret-ldap-password
|
||||||
|
LDAP_SERVER=directory
|
||||||
|
LDAP_ROOT=dc=maidstone-hackspace, dc=org, dc=uk
|
||||||
|
|
8
live.yml
8
live.yml
|
@ -15,6 +15,7 @@ services:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
- postgres_backup:/backups
|
- postgres_backup:/backups
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
restart: always
|
||||||
|
|
||||||
django:
|
django:
|
||||||
build:
|
build:
|
||||||
|
@ -28,9 +29,11 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
- sockets:/data/sockets
|
- sockets:/data/sockets
|
||||||
|
restart: always
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:latest
|
image: redis:latest
|
||||||
|
restart: always
|
||||||
|
|
||||||
celeryworker:
|
celeryworker:
|
||||||
build:
|
build:
|
||||||
|
@ -43,6 +46,7 @@ services:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
command: celery -A mhackspace.celeryapp worker -l INFO
|
command: celery -A mhackspace.celeryapp worker -l INFO
|
||||||
|
restart: always
|
||||||
|
|
||||||
celerybeat:
|
celerybeat:
|
||||||
build:
|
build:
|
||||||
|
@ -55,3 +59,7 @@ services:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
command: celery -A mhackspace.celeryapp beat -l INFO
|
command: celery -A mhackspace.celeryapp beat -l INFO
|
||||||
|
restart: always
|
||||||
|
directory:
|
||||||
|
image: osixia/openldap:1.2.0
|
||||||
|
env_file: .env
|
||||||
|
|
|
@ -105,3 +105,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./mhackspace:/data
|
- ./mhackspace:/data
|
||||||
command: server --config-dir /tmp/minio /data
|
command: server --config-dir /tmp/minio /data
|
||||||
|
|
||||||
|
directory:
|
||||||
|
image: osixia/openldap:1.2.0
|
||||||
|
env_file: .env
|
||||||
|
|
|
@ -40,3 +40,4 @@ docker-compose -f dev.yml run django python manage.py migrate
|
||||||
#+BEGIN_SRC sh
|
#+BEGIN_SRC sh
|
||||||
docker-compose -f dev.yml run django python manage.py createsuperuser
|
docker-compose -f dev.yml run django python manage.py createsuperuser
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Command(BaseCommand):
|
||||||
feed = AutoFixture(Feed)
|
feed = AutoFixture(Feed)
|
||||||
feed.create(10)
|
feed.create(10)
|
||||||
|
|
||||||
post = AutoFixture(Post, follow_fk=True)
|
post = AutoFixture(Post, generate_fk=True)
|
||||||
post.create(10)
|
post.create(10)
|
||||||
|
|
||||||
categorys = AutoFixture(Category)
|
categorys = AutoFixture(Category)
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
#+TITLE: Hackspace LDAP examples
|
||||||
|
|
||||||
|
* Introduction
|
||||||
|
LDAP is a direcotry service that is often used to authenticate users, it has support in a lot of apps so we maintain a ldap server to provided authentication.
|
||||||
|
|
||||||
|
** Usefull links
|
||||||
|
https://www.redpill-linpro.com/techblog/2016/08/16/ldap-password-hash.html
|
||||||
|
** setup
|
||||||
|
Setup an ldap server inside docker
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
docker run --name hackspace-ldap --restart=always --env LDAP_ORGANISATION="Maidstone Hackspace" --env LDAP_DOMAIN="maidstone-hackspace.org.uk" --env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.2.0
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Add Objects
|
||||||
|
** Add Organizational Units
|
||||||
|
#+BEGIN_SRC python :results value
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
LDAP_PASSWORD = 'secretldappassword'
|
||||||
|
LDAP_ROOT = 'dc=maidstone-hackspace, dc=org, dc=uk'
|
||||||
|
LDAP_SERVER = '172.18.0.2'
|
||||||
|
|
||||||
|
server = Server(LDAP_SERVER)
|
||||||
|
conn = Connection(server, 'cn=admin, %s' % LDAP_ROOT, LDAP_PASSWORD, auto_bind=True)
|
||||||
|
|
||||||
|
conn.add('ou=users,dc=maidstone-hackspace, dc=org, dc=uk', 'organizationalUnit')
|
||||||
|
conn.add('ou=groups,dc=maidstone-hackspace, dc=org, dc=uk', 'organizationalUnit')
|
||||||
|
return conn.result
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
| result | : | 0 | description | : | success | dn | : | | message | : | | referrals | : | hline | type | : | addResponse |
|
||||||
|
|
||||||
|
** Add Groups
|
||||||
|
#+BEGIN_SRC python :results value
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
LDAP_PASSWORD = 'secretldappassword'
|
||||||
|
LDAP_ROOT = 'dc=maidstone-hackspace, dc=org, dc=uk'
|
||||||
|
LDAP_SERVER = '172.18.0.2'
|
||||||
|
|
||||||
|
server = Server(LDAP_SERVER)
|
||||||
|
conn = Connection(server, 'cn=admin, %s' % LDAP_ROOT, LDAP_PASSWORD, auto_bind=True)
|
||||||
|
|
||||||
|
g = {'objectClass': ['groupOfNames', 'top'], 'cn': 'g1', 'member': ['cn=admin',]}
|
||||||
|
conn.add('cn=g1, ou=groups,dc=maidstone-hackspace, dc=org, dc=uk', attributes=g)
|
||||||
|
conn.add('cn=g2, ou=groups,dc=maidstone-hackspace, dc=org, dc=uk', attributes=g)
|
||||||
|
return conn.result
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
| result | : | 0 | description | : | success | dn | : | | message | : | | referrals | : | hline | type | : | addResponse |
|
||||||
|
|
||||||
|
** Add Users
|
||||||
|
#+BEGIN_SRC python :results value
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
LDAP_PASSWORD = 'secretldappassword'
|
||||||
|
LDAP_ROOT = 'dc=maidstone-hackspace, dc=org, dc=uk'
|
||||||
|
LDAP_SERVER = '172.18.0.2'
|
||||||
|
|
||||||
|
server = Server(LDAP_SERVER)
|
||||||
|
conn = Connection(server, 'cn=admin, %s' % LDAP_ROOT, LDAP_PASSWORD, auto_bind=True)
|
||||||
|
|
||||||
|
u = {'objectClass': ['inetOrgPerson', 'person', 'top'], 'sn': 'user_sn', 'cn': 'First Last', 'userPassword': ''}
|
||||||
|
conn.add('cn=user2,ou=users,dc=maidstone-hackspace, dc=org, dc=uk', attributes=u)
|
||||||
|
return conn.result
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
| result | : | 0 | description | : | success | dn | : | | message | : | | referrals | : | hline | type | : | addResponse |
|
||||||
|
|
||||||
|
* Modify objects
|
||||||
|
** Modify groups
|
||||||
|
#+BEGIN_SRC python :results raw
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL, MODIFY_REPLACE, MODIFY_DELETE
|
||||||
|
server = Server('172.17.0.2')
|
||||||
|
conn = Connection(server, 'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk', 'JonSn0w', auto_bind=True)
|
||||||
|
print(conn.bind())
|
||||||
|
conn.modify(
|
||||||
|
'cn=g1, ou=groups,dc=maidstone-hackspace, dc=org, dc=uk',
|
||||||
|
{'member': [
|
||||||
|
(MODIFY_REPLACE, ['cn=admin','cn=user1'])]})
|
||||||
|
return conn.result
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
{'result': 0, 'description': 'success', 'dn': '', 'message': '', 'referrals': None, 'type': 'modifyResponse'}
|
||||||
|
|
||||||
|
* Search objects
|
||||||
|
** Check group exists
|
||||||
|
#+BEGIN_SRC python :results value
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
server = Server('172.17.0.2')
|
||||||
|
conn = Connection(server, 'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk', 'JonSn0w', auto_bind=True)
|
||||||
|
print(conn.bind())
|
||||||
|
return conn.search('cn=g4, ou=groups, dc=maidstone-hackspace, dc=org, dc=uk', '(objectclass=groupOfNames)')
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: False
|
||||||
|
|
||||||
|
* List objects
|
||||||
|
** list users
|
||||||
|
#+BEGIN_SRC python :results value
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
server = Server('172.19.0.6')
|
||||||
|
conn = Connection(server, 'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk', 'secretldappassword', auto_bind=True)
|
||||||
|
print(conn.bind())
|
||||||
|
conn.search('dc=maidstone-hackspace, dc=org, dc=uk', '(objectclass=person)')
|
||||||
|
return conn.entries
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
| DN: | cn=oly | ou=users | dc=maidstone-hackspace | dc=org | dc=uk | - | STATUS: | Read | - | READ | TIME: | 2018-04-23T21:13:46.919782 | DN: | cn=test | ou=users | dc=maidstone-hackspace | dc=org | dc=uk | - | STATUS: | Read | - | READ | TIME: | 2018-04-23T21:13:46.919828 |
|
||||||
|
|
||||||
|
** list groups
|
||||||
|
#+BEGIN_SRC python :results table
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL, SUBTREE
|
||||||
|
server = Server('172.17.0.2')
|
||||||
|
conn = Connection(server, 'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk', 'JonSn0w', auto_bind=True)
|
||||||
|
print(conn.bind())
|
||||||
|
conn.search(
|
||||||
|
search_base='ou=groups, dc=maidstone-hackspace, dc=org, dc=uk',
|
||||||
|
search_filter='(objectclass=groupOfNames)',
|
||||||
|
search_scope=SUBTREE,
|
||||||
|
attributes=['cn', 'member'])
|
||||||
|
return conn.entries[0]
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** list organizational units
|
||||||
|
#+BEGIN_SRC python :results table
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
server = Server('172.17.0.2')
|
||||||
|
conn = Connection(server, 'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk', 'JonSn0w', auto_bind=True)
|
||||||
|
print(conn.bind())
|
||||||
|
conn.search('dc=maidstone-hackspace, dc=org, dc=uk', '(objectclass=organizationalUnit)')
|
||||||
|
return conn.entries
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
| DN: | ou=users | dc=maidstone-hackspace | dc=org | dc=uk | - | STATUS: | Read | - | READ | TIME: | 2018-04-19T22:29:32.989385 | DN: | ou=groups | dc=maidstone-hackspace | dc=org | dc=uk | - | STATUS: | Read | - | READ | TIME: | 2018-04-19T22:29:32.989433 |
|
||||||
|
|
||||||
|
#+BEGIN_SRC python :results table
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
server = Server('172.19.0.3')
|
||||||
|
conn = Connection(server, 'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk', 'secretldappassword', auto_bind=True)
|
||||||
|
print(conn.bind())
|
||||||
|
conn.search('dc=maidstone-hackspace, dc=org, dc=uk', '(objectclass=organizationalUnit)')
|
||||||
|
return conn.entries
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
| |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* Queries
|
||||||
|
Testing with elisp
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq ldap-default-host "test.maidstone-hackspace.org.uk")
|
||||||
|
(setq ldap-default-base "dc=test, dc=maidstone-hackspace, dc=org, dc=uk")
|
||||||
|
(setq ldap-host-alist '(("ldap://test.maidstone-hackspace.org.uk"
|
||||||
|
timelimit "10"
|
||||||
|
password "password-here"
|
||||||
|
base "dc=test, dc=maidstone-hackspace, dc=org, dc=uk"
|
||||||
|
binddn "cn=admin, dc=test, dc=maidstone-hackspace, dc=org, dc=uk")))
|
||||||
|
(ldap-search "(objectclass=person)")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Testing with ldap search
|
||||||
|
#+BEGIN_SRC shell
|
||||||
|
docker exec hackstage_directory_1 ldapsearch -x -H ldap://localhost -b "dc=test, dc=maidstone-hackspace, dc=org, dc=uk" -D "cn=admin, dc=test, dc=maidstone-hackspace, dc=org, dc=uk" -w password-here
|
||||||
|
#+END_SRC
|
|
@ -0,0 +1,3 @@
|
||||||
|
from mhackspace.celeryapp import app as celery_app
|
||||||
|
|
||||||
|
__all__ = ['celery_app']
|
|
@ -0,0 +1,22 @@
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
from django.forms.models import model_to_dict
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from mhackspace.subscriptions.payments import select_provider
|
||||||
|
from mhackspace.users.models import Membership, User
|
||||||
|
from mhackspace.subscriptions.helper import create_or_update_membership
|
||||||
|
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
#from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
from celery import shared_task
|
||||||
|
from .models import User
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Sync database directory'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
for user in User.objects.all():
|
||||||
|
self.stdout.write(self.style.NOTICE('test %s' % user.username))
|
||||||
|
for group in Group.objects.all():
|
||||||
|
self.stdout.write(self.style.NOTICE('test %s' % group.name))
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from mhackspace.ldapsync.tasks import (
|
||||||
|
ldap_list_users, ldap_list_groups, ldap_list_organizational_units, conn)
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'List database directory'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
self.stdout.write(self.style.NOTICE('Listing Organizational units.....'))
|
||||||
|
for row in ldap_list_organizational_units(conn):
|
||||||
|
self.stdout.write(self.style.NOTICE('\t%s' % row.entry_dn))
|
||||||
|
|
||||||
|
self.stdout.write(self.style.NOTICE('Listing Users.....'))
|
||||||
|
for row in ldap_list_users(conn):
|
||||||
|
self.stdout.write(self.style.NOTICE('\t%s' % row.entry_dn))
|
||||||
|
|
||||||
|
self.stdout.write(self.style.NOTICE('Listing Groups.....'))
|
||||||
|
for row in ldap_list_groups(conn):
|
||||||
|
self.stdout.write(self.style.NOTICE('\t%s' % row.entry_dn))
|
|
@ -0,0 +1,35 @@
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from mhackspace.users.models import User
|
||||||
|
from mhackspace.ldapsync.tasks import (
|
||||||
|
ldap_add_user, ldap_add_group, ldap_add_organizational_unit, conn)
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Sync database directory'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
self.stdout.write(self.style.NOTICE('Loading Organizational unit.....'))
|
||||||
|
|
||||||
|
ldap_add_organizational_unit(conn, 'users')
|
||||||
|
ldap_add_organizational_unit(conn, 'groups')
|
||||||
|
|
||||||
|
self.stdout.write(self.style.NOTICE('Loading Users.....'))
|
||||||
|
|
||||||
|
for user in User.objects.all():
|
||||||
|
result = ldap_add_user(
|
||||||
|
conn,
|
||||||
|
username=user.username,
|
||||||
|
password=user.password)
|
||||||
|
if result.get('message'):
|
||||||
|
self.stdout.write(result.get('message'))
|
||||||
|
self.stdout.write(self.style.NOTICE('\ttest %s' % user.username))
|
||||||
|
|
||||||
|
self.stdout.write(self.style.NOTICE('Loading Groups.....'))
|
||||||
|
|
||||||
|
for group in Group.objects.all():
|
||||||
|
result = ldap_add_group(conn, group.name, ['admin', ])
|
||||||
|
if result.get('message'):
|
||||||
|
self.stdout.write(result.get('message'))
|
||||||
|
|
||||||
|
self.stdout.write(self.style.NOTICE('\ttest %s' % group.name))
|
|
@ -0,0 +1,103 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
from ldap3 import Server, Connection, ObjectDef, AttrDef, Reader, Writer, ALL
|
||||||
|
from celery import shared_task
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
server = Server(settings.LDAP_SERVER)
|
||||||
|
conn = Connection(
|
||||||
|
server,
|
||||||
|
'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk',
|
||||||
|
settings.LDAP_PASSWORD,
|
||||||
|
auto_bind=True)
|
||||||
|
|
||||||
|
|
||||||
|
def ldap_list_organizational_units(connection):
|
||||||
|
connection.search(
|
||||||
|
'%s' % (settings.LDAP_ROOT),
|
||||||
|
'(objectclass=organizationalUnit)')
|
||||||
|
for result in connection.entries:
|
||||||
|
yield result
|
||||||
|
|
||||||
|
|
||||||
|
def ldap_list_groups(connection):
|
||||||
|
connection.search(
|
||||||
|
'%s' % (settings.LDAP_ROOT),
|
||||||
|
'(objectclass=groupOfNames)')
|
||||||
|
for result in connection.entries:
|
||||||
|
yield result
|
||||||
|
|
||||||
|
|
||||||
|
def ldap_list_users(connection):
|
||||||
|
connection.search(
|
||||||
|
'%s' % (settings.LDAP_ROOT),
|
||||||
|
'(objectclass=person)')
|
||||||
|
for result in connection.entries:
|
||||||
|
yield result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def ldap_add_organizational_unit(connection, name):
|
||||||
|
exists = connection.search(
|
||||||
|
'cn=%s, %s' % (name, settings.LDAP_ROOT),
|
||||||
|
'(objectclass=organizationalUnit)')
|
||||||
|
|
||||||
|
if exists is False:
|
||||||
|
connection.add(
|
||||||
|
'ou=%s, %s' % (name, settings.LDAP_ROOT),
|
||||||
|
'organizationalUnit')
|
||||||
|
return connection.result
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def ldap_add_group(connection, group, users):
|
||||||
|
exists = connection.search(
|
||||||
|
'cn=%s, ou=groups, %s' % (group, settings.LDAP_ROOT),
|
||||||
|
'(objectclass=groupOfNames)')
|
||||||
|
|
||||||
|
cn_list = ['cn=' + u for u in users]
|
||||||
|
g = {'objectClass': ['groupOfNames', 'top'], 'cn': group, 'member': cn_list}
|
||||||
|
if exists is False:
|
||||||
|
connection.add(
|
||||||
|
'cn=%s, ou=groups, %s' % (group, settings.LDAP_ROOT),
|
||||||
|
attributes=g)
|
||||||
|
return connection.result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def ldap_add_user(connection, username, name='', password=None):
|
||||||
|
u = {'objectClass': ['inetOrgPerson', 'person', 'top'], 'sn': 'user_sn', 'cn': 'First Last', 'userPassword': ''}
|
||||||
|
if not password:
|
||||||
|
return
|
||||||
|
|
||||||
|
exists = connection.search(
|
||||||
|
'cn=%s, ou=users, %s' % (username, settings.LDAP_ROOT),
|
||||||
|
'(objectclass=inetOrgPerson)')
|
||||||
|
|
||||||
|
u = {
|
||||||
|
'objectClass': ['inetOrgPerson', 'person', 'top'],
|
||||||
|
'sn': 'user_sn',
|
||||||
|
'cn': 'First Last name',
|
||||||
|
'userPassword': password,
|
||||||
|
}
|
||||||
|
if exists is False:
|
||||||
|
connection.add(
|
||||||
|
'cn=%s, ou=users, %s' % (username, settings.LDAP_ROOT),
|
||||||
|
attributes=u)
|
||||||
|
return connection.result
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def complete_directory_sync(self):
|
||||||
|
server = Server(settings.LDAP_SERVER)
|
||||||
|
conn = Connection(
|
||||||
|
server,
|
||||||
|
'cn=admin, dc=maidstone-hackspace, dc=org, dc=uk',
|
||||||
|
settings.LDAP_PASSWORD,
|
||||||
|
auto_bind=True)
|
||||||
|
|
||||||
|
for user in User.objects.all():
|
||||||
|
ldap_add_user(conn, user.username)
|
|
@ -55,8 +55,8 @@ def send_topic_update_email(sender, instance, **kwargs):
|
||||||
matrix_message.delay(
|
matrix_message.delay(
|
||||||
prefix=' - REQUEST',
|
prefix=' - REQUEST',
|
||||||
message='%s - https://%s%s' % (
|
message='%s - https://%s%s' % (
|
||||||
Site.objects.get_current().domain,
|
|
||||||
instance.title,
|
instance.title,
|
||||||
|
Site.objects.get_current().domain,
|
||||||
instance.get_absolute_url()))
|
instance.get_absolute_url()))
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -100,4 +100,6 @@ django-celery-beat==1.0.1
|
||||||
|
|
||||||
argon2-cffi
|
argon2-cffi
|
||||||
django-cors-headers
|
django-cors-headers
|
||||||
magic
|
python-magic
|
||||||
|
ldap3
|
||||||
|
bcrypt==3.1.4
|
||||||
|
|
11
stage.yml
11
stage.yml
|
@ -15,6 +15,7 @@ services:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
- postgres_backup:/backups
|
- postgres_backup:/backups
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
restart: always
|
||||||
|
|
||||||
django:
|
django:
|
||||||
build:
|
build:
|
||||||
|
@ -29,9 +30,11 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
- sockets:/data/sockets
|
- sockets:/data/sockets
|
||||||
|
restart: always
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:latest
|
image: redis:latest
|
||||||
|
restart: always
|
||||||
|
|
||||||
celeryworker:
|
celeryworker:
|
||||||
build:
|
build:
|
||||||
|
@ -44,6 +47,7 @@ services:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
command: celery -A mhackspace.celeryapp worker -l INFO
|
command: celery -A mhackspace.celeryapp worker -l INFO
|
||||||
|
restart: always
|
||||||
|
|
||||||
celerybeat:
|
celerybeat:
|
||||||
build:
|
build:
|
||||||
|
@ -56,3 +60,10 @@ services:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
command: celery -A mhackspace.celeryapp beat -l INFO
|
command: celery -A mhackspace.celeryapp beat -l INFO
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
directory:
|
||||||
|
image: osixia/openldap:1.2.0
|
||||||
|
ports:
|
||||||
|
- "0.0.0.0:389:389"
|
||||||
|
env_file: .env
|
||||||
|
|
Loading…
Reference in New Issue