1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2025-02-05 20:15:19 +00:00

Compare commits

..

No commits in common. "ca54ae0c653f5872989b7c40dc43bad39e77cf26" and "5e368d1ee05d7d5e0617c0f7dbc0a4639f56277f" have entirely different histories.

5 changed files with 217 additions and 74 deletions

View file

@ -385,73 +385,55 @@ python manage.py test
## LDAP Configuration ## LDAP Configuration
The config options below can be changed in `webvirtcloud/settings.py` file. Variants for Active Directory and OpenLDAP are shown. This is a minimal config to get LDAP running, for further info read the [django-auth-ldap documentation](https://django-auth-ldap.readthedocs.io). The example settings are based on an OpenLDAP server with groups defined as "cn" of class "groupOfUniqueNames"
Enable LDAP Enable LDAP
```bash ```bash
sudo sed -i "s~#\"django_auth_ldap.backend.LDAPBackend\",~\"django_auth_ldap.backend.LDAPBackend\",~g" /srv/webvirtcloud/webvirtcloud/settings.py sudo sed -i "s/LDAP_ENABLED = False/LDAP_ENABLED = True/g"" /srv/webvirtcloud/webvirtcloud/settings.py
``` ```
Set the LDAP server name and bind DN Set the LDAP server name and root DN
```python ```bash
# Active Directory sudo sed -i "s/LDAP_URL = ''/LDAP_URL = 'myldap.server.com'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
AUTH_LDAP_SERVER_URI = "ldap://example.com" sudo sed -i "s/LDAP_ROOT_DN = ''/LDAP_ROOT_DN = 'dc=server,dc=com'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
AUTH_LDAP_BIND_DN = "username@example.com"
AUTH_LDAP_BIND_PASSWORD = "password"
# OpenLDAP
AUTH_LDAP_SERVER_URI = "ldap://example.com"
AUTH_LDAP_BIND_DN = "CN=username,CN=Users,OU=example,OU=com"
AUTH_LDAP_BIND_PASSWORD = "password"
``` ```
Set the user filter and user and group search base and filter Set the passphrase to decrypt the password
```bash
```python sudo sed -i "s/pass:MYPASSPHRASE/pass:MYTRUEPASSPHRASE/g" /srv/webvirtcloud/webvirtcloud/.dec_ldap_pwd.sh
# Active Directory
AUTH_LDAP_USER_SEARCH = LDAPSearch(
"CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)"
)
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
"CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(objectClass=group)"
)
AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType()
# OpenLDAP
AUTH_LDAP_USER_SEARCH = LDAPSearch(
"CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(cn=%(user)s)"
)
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
"CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(objectClass=groupOfUniqueNames)"
)
AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType() # import needs to be changed at the top of settings.py
``` ```
Set group which is required to access WebVirtCloud. You may set this to `False` to disable this filter. Encrypt the password
```bash
```python echo MYPASSWORD | openssl enc -pbkdf2 -salt -pass pass:MYTRUEPASSPHRASE | base64
AUTH_LDAP_REQUIRE_GROUP = "CN=WebVirtCloud Access,CN=Users,DC=example,DC=com"
``` ```
Populate user fields with values from LDAP Set the user that has browse access to LDAP and its password encrypted
```python ```bash
AUTH_LDAP_USER_FLAGS_BY_GROUP = { sudo sed -i "s/LDAP_MASTER_DN = ''/LDAP_MASTER_DN = 'cn=admin,ou=users,dc=kendar,dc=org'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
"is_staff": "CN=WebVirtCloud Staff,CN=Users,DC=example,DC=com", sudo sed -i "s/LDAP_MASTER_PW_ENC = ''/LDAP_MASTER_PW_ENC = 'MYPASSWORDENCRYPTED'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
"is_superuser": "CN=WebVirtCloud Admins,CN=Users,DC=example,DC=com",
}
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
}
``` ```
Now when you login with an LDAP user it will be assigned the rights defined. The user will be authenticated then with LDAP and authorized through the WebVirtCloud permissions. Set the attribute that will be used to find the username, i usually use the cn
If you'd like to move a user from ldap to WebVirtCloud, just change its password from the UI and (eventually) remove from the group in LDAP. ```bash
sudo sed -i "s/LDAP_USER_UID_PREFIX = ''/LDAP_USER_UID_PREFIX = 'cn'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
```
You can now create the filters to retrieve the users for the various group. This will be used during the user creation only
```bash
sudo sed -i "s/LDAP_SEARCH_GROUP_FILTER_ADMINS = ''/LDAP_SEARCH_GROUP_FILTER_ADMINS = 'memberOf=cn=admins,dc=kendar,dc=org'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
sudo sed -i "s/LDAP_SEARCH_GROUP_FILTER_STAFF = ''/LDAP_SEARCH_GROUP_FILTER_STAFF = 'memberOf=cn=staff,dc=kendar,dc=org'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
sudo sed -i "s/LDAP_SEARCH_GROUP_FILTER_USERS = ''/LDAP_SEARCH_GROUP_FILTER_USERS = 'memberOf=cn=users,dc=kendar,dc=org'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
```
Now when you login with an LDAP user it will be assigned the rights defined. The user will be authenticated then with ldap and authorized through the WebVirtCloud permissions.
If you'd like to move a user from ldap to WebVirtCloud, just change its password from the UI and (eventually) remove from the group in ldap
## REST API / BETA ## REST API / BETA

View file

@ -20,4 +20,3 @@ djangorestframework==3.14.0
drf-nested-routers==0.93.4 drf-nested-routers==0.93.4
drf-yasg==1.21.7 drf-yasg==1.21.7
markdown>=3.4.1 markdown>=3.4.1
django-auth-ldap==4.5.0

18
webvirtcloud/.dec_ldap_pwd.sh Executable file
View file

@ -0,0 +1,18 @@
#!/bin/bash
#####
#
# LDAP PASSWORD DECRYPTION SCRIPT
#
#
#####
ENC_PASSWD=$1
echo $(echo $ENC_PASSWD | base64 -d | openssl enc -pbkdf2 -salt -d -pass pass:MYPASSPHRASE )

142
webvirtcloud/ldapbackend.py Normal file
View file

@ -0,0 +1,142 @@
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User, Group
from django.conf import settings
from accounts.models import UserAttributes, UserInstance, UserSSHKey
from django.contrib.auth.models import Permission
from logs.models import Logs
import uuid
try:
from ldap3 import Server, Connection, ALL
#/srv/webvirtcloud/ldap/ldapbackend.py
class LdapAuthenticationBackend(ModelBackend):
def get_LDAP_user(self, username, password, filterString):
print('get_LDAP_user {}'.format(username))
try:
server = Server(settings.LDAP_URL, port=settings.LDAP_PORT,
use_ssl=settings.USE_SSL,get_info=ALL)
connection = Connection(server,
settings.LDAP_MASTER_DN,
settings.LDAP_MASTER_PW, auto_bind=True)
connection.search(settings.LDAP_ROOT_DN,
'(&({attr}={login})({filter}))'.format(
attr=settings.LDAP_USER_UID_PREFIX,
login=username,
filter=filterString), attributes=['*'])
if len(connection.response) == 0:
print('get_LDAP_user-no response')
return None
specificUser = connection.response[0]
userDn = str(specificUser.get('raw_dn'),'utf-8')
userGivenName = connection.entries[0].givenName
userSn = connection.entries[0].sn
userMail = connection.entries[0].mail
with Connection(server, userDn, password) as con:
return username, userGivenName, userSn, userMail
except Exception as e:
print("LDAP Exception: {}".format(e))
return None
return None
def authenticate(self, request, username=None, password=None, **kwargs):
if not settings.LDAP_ENABLED:
return None
print("authenticate_ldap")
# Get the user information from the LDAP if he can be authenticated
isAdmin = False
isStaff = False
isTechnician = False
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_ADMINS)
isAdmin = requeteLdap is not None
isStaff = requeteLdap is not None
if requeteLdap is None:
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_STAFF)
isStaff = requeteLdap is not None
if requeteLdap is None:
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_TECHNICIANS)
isTechnician = requeteLdap is not None
if requeteLdap is None:
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_USERS)
if requeteLdap is None:
print("User does not belong to any search group. Check LDAP_SEARCH_GROUP_FILTER in settings.")
return None
techniciansGroup = Group.objects.get(name='Technicians')
try:
user = User.objects.get(username=username)
attributes = UserAttributes.objects.get(user=user)
user.is_staff = isStaff
user.is_superuser = isAdmin
if not isTechnician and user.groups.filter(name='Technicians').exists():
user.groups.remove(techniciansGroup)
elif isTechnician and not user.groups.filter(name='Technicians').exists():
user.groups.add(techniciansGroup)
else:
print("The user is already in the Technicians group")
user.save()
# TODO VERIFY
except User.DoesNotExist:
print(f"authenticate-create new user: {username}")
user = User(username=username)
user.first_name = requeteLdap[1]
user.last_name = requeteLdap[2]
user.email = requeteLdap[3]
user.is_active = True
user.is_staff = isStaff
user.is_superuser = isAdmin
user.set_password(uuid.uuid4().hex)
user.save()
if isTechnician:
user.groups.add(techniciansGroup)
maxInstances = 1
maxCpus = 1
maxMemory = 128
maxDiskSize = 1
if isStaff:
maxMemory = 2048
maxDiskSize = 20
permission = Permission.objects.get(codename='clone_instances')
user.user_permissions.add(permission)
if isAdmin:
maxInstances = -1
maxCpus = -1
maxMemory = -1
maxDiskSize = -1
permission = Permission.objects.get(codename='clone_instances')
user.user_permissions.add(permission)
user.save()
UserAttributes.objects.create(
user=user,
max_instances=maxInstances,
max_cpus=maxCpus,
max_memory=maxMemory,
max_disk_size=maxDiskSize,
)
user.save()
print("authenticate-user created")
return user
def get_user(self, user_id):
if not settings.LDAP_ENABLED:
return None
print("get_user_ldap")
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
print("get_user-user not found")
return None
except:
class LdapAuthenticationBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
return None
def get_user(self, user_id):
return None

View file

@ -3,9 +3,7 @@ Django settings for webvirtcloud project.
""" """
import ldap
import subprocess import subprocess
from django_auth_ldap.config import LDAPSearch, NestedActiveDirectoryGroupType
from pathlib import Path from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
@ -103,7 +101,7 @@ DATABASES = {
AUTHENTICATION_BACKENDS = [ AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend", "django.contrib.auth.backends.ModelBackend",
#"django_auth_ldap.backend.LDAPBackend", "webvirtcloud.ldapbackend.LdapAuthenticationBackend",
] ]
LOGIN_URL = "/accounts/login/" LOGIN_URL = "/accounts/login/"
@ -282,23 +280,27 @@ EMAIL_HOST_PASSWORD = ''
# LDAP Config # LDAP Config
# #
AUTH_LDAP_SERVER_URI = "ldap://example.com" LDAP_ENABLED = False
AUTH_LDAP_BIND_DN = "username@example.com" LDAP_URL = ''
AUTH_LDAP_BIND_PASSWORD = "password" LDAP_PORT = 389
AUTH_LDAP_USER_SEARCH = LDAPSearch( USE_SSL = False
"CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)" ## The user with search rights on ldap. (e.g cn=admin,dc=kendar,dc=org)
) LDAP_MASTER_DN = ''
AUTH_LDAP_GROUP_SEARCH = LDAPSearch( LDAP_MASTER_PW_ENC = ''
"CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(objectClass=group)" LDAP_MASTER_PW = subprocess.Popen(["bash", str(BASE_DIR) + "/webvirtcloud/.dec_ldap_pwd.sh", LDAP_MASTER_PW_ENC],stdout=subprocess.PIPE, encoding='utf8').stdout.read().strip('\n')
) ## The root dn (e.g. dc=kendar,dc=org)
AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType() LDAP_ROOT_DN = ''
AUTH_LDAP_REQUIRE_GROUP = "CN=WebVirtCloud Access,CN=Users,DC=example,DC=com" ## Queries to identify the users, i use groupOfUniqueNames on openldap
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
"is_staff": "CN=WebVirtCloud Staff,CN=Users,DC=example,DC=com", ### PLEASE BE SURE memberOf overlay is activated on slapd
"is_superuser": "CN=WebVirtCloud Admins,CN=Users,DC=example,DC=com", ## e.g. memberOf=cn=admins,cn=staff,cn=technicians,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
} LDAP_SEARCH_GROUP_FILTER_ADMINS = ''
AUTH_LDAP_USER_ATTR_MAP = { ## e.g. memberOf=cn=staff,cn=technicians,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
"first_name": "givenName", LDAP_SEARCH_GROUP_FILTER_STAFF = ''
"last_name": "sn", ## e.g. memberOf=cn=technicians,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
"email": "mail", LDAP_SEARCH_GROUP_FILTER_TECHNICIANS = ''
} ## e.g. memberOf=cn=webvirtcloud,ou=groups,dc=kendar,dc=org
LDAP_SEARCH_GROUP_FILTER_USERS = ''
## The user name prefix to identify the user name (e.g. cn)
LDAP_USER_UID_PREFIX = ''