From aa9f1ae861117dcf1f0baca1699cb2cb06a49de0 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sat, 8 Feb 2020 02:22:29 +0000 Subject: [PATCH] Integrate LDAP API on user signup --- apiserver/apiserver/api/utils.py | 28 ++++++++++++++++-- apiserver/apiserver/api/utils_ldap.py | 41 ++++++++++++++++++++++++++ apiserver/apiserver/secrets.py.example | 10 +++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 apiserver/apiserver/api/utils_ldap.py diff --git a/apiserver/apiserver/api/utils.py b/apiserver/apiserver/api/utils.py index 25b2d08..be1e81b 100644 --- a/apiserver/apiserver/api/utils.py +++ b/apiserver/apiserver/api/utils.py @@ -13,7 +13,7 @@ from reportlab.lib.pagesizes import letter from django.db.models import Sum from django.core.cache import cache -from . import models, serializers +from . import models, serializers, utils_ldap try: from . import old_models except ImportError: @@ -225,6 +225,18 @@ def link_old_member(data, user): if member.user: raise ValidationError(dict(email='Old member already claimed.')) + if utils_ldap.is_configured(): + result = utils_ldap.find_user(user.username) + if result == 200: + pass + elif result == 404: + raise ValidationError(dict(username='Unable to find username in old portal.')) + else: + raise ValidationError(dict(non_field_errors='Problem connecting to LDAP server: find.')) + + if utils_ldap.set_password(data) != 200: + raise ValidationError(dict(non_field_errors='Problem connecting to LDAP server: set.')) + member.user = user member.first_name = data['first_name'] member.last_name = data['last_name'] @@ -252,6 +264,18 @@ def create_new_member(data, user): if old_members.filter(email=data['email']).exists(): raise ValidationError(dict(email='Account was found in old portal.')) + if utils_ldap.is_configured(): + result = utils_ldap.find_user(user.username) + if result == 200: + raise ValidationError(dict(username='Username was found in old portal.')) + elif result == 404: + pass + else: + raise ValidationError(dict(non_field_errors='Problem connecting to LDAP server.')) + + if utils_ldap.create_user(data) != 200: + raise ValidationError(dict(non_field_errors='Problem connecting to LDAP server: create.')) + models.Member.objects.create( user=user, first_name=data['first_name'], @@ -265,7 +289,7 @@ def register_user(data, user): link_old_member(data, user) else: create_new_member(data, user) - except ValidationError: + except: user.delete() raise diff --git a/apiserver/apiserver/api/utils_ldap.py b/apiserver/apiserver/api/utils_ldap.py new file mode 100644 index 0000000..178976d --- /dev/null +++ b/apiserver/apiserver/api/utils_ldap.py @@ -0,0 +1,41 @@ +import requests + +from apiserver import secrets + +def is_configured(): + return bool(secrets.LDAP_API_URL and secrets.LDAP_API_KEY) + +if not is_configured: + print('LDAP connection not configured.') + + +def ldap_api(route, data): + try: + headers = {'Authorization': 'Token ' + secrets.LDAP_API_KEY} + url = secrets.LDAP_API_URL + route + r = requests.post(url, data=data, headers=headers, timeout=3) + return r.status_code + except BaseException as e: + print('Problem GETting {}: {} - {}'.format(url, e.__class__.__name__, str(e))) + return None + +def find_user(username): + ldap_data = dict(username=username) + return ldap_api('find-user', ldap_data) + +def create_user(data): + ldap_data = dict( + first=data['first_name'], + last=data['last_name'], + username=data['username'], + email=data['email'], + password=data['password1'], + ) + return ldap_api('create-user', ldap_data) + +def set_password(data): + ldap_data = dict( + username=data['username'], + password=data['password1'], + ) + return ldap_api('set-password', ldap_data) diff --git a/apiserver/apiserver/secrets.py.example b/apiserver/apiserver/secrets.py.example index 2918934..4501c05 100644 --- a/apiserver/apiserver/secrets.py.example +++ b/apiserver/apiserver/secrets.py.example @@ -16,3 +16,13 @@ DJANGO_SECRET_KEY = '' # Running Django with a known SECRET_KEY defeats many of Django’s security # protections, and can lead to privilege escalation and remote code execution # vulnerabilities. + +# LDAP API url +# should contain the IP and port of the script and machine connected over VPN +# with trailing slash +LDAP_API_URL = '' + +# LDAP API key +# should be equal to the auth token value set in +# spaceport/ldapserver/secrets.py +LDAP_API_KEY = ''