mirror of
				https://github.com/retspen/webvirtcloud
				synced 2025-07-31 12:41:08 +00:00 
			
		
		
		
	Merge branch 'master' into master
This commit is contained in:
		
						commit
						296081d1e3
					
				
					 18 changed files with 167 additions and 240 deletions
				
			
		
							
								
								
									
										82
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										82
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
					@ -385,55 +385,73 @@ python manage.py test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## LDAP Configuration
 | 
					## LDAP Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The example settings are based on an OpenLDAP server with groups defined as "cn" of class "groupOfUniqueNames"
 | 
					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).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Enable LDAP
 | 
					Enable LDAP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
sudo sed -i "s/LDAP_ENABLED = False/LDAP_ENABLED = True/g"" /srv/webvirtcloud/webvirtcloud/settings.py
 | 
					sudo sed -i "s~#\"django_auth_ldap.backend.LDAPBackend\",~\"django_auth_ldap.backend.LDAPBackend\",~g" /srv/webvirtcloud/webvirtcloud/settings.py
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Set the LDAP server name and root DN
 | 
					Set the LDAP server name and bind DN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```python
 | 
				
			||||||
sudo sed -i "s/LDAP_URL = ''/LDAP_URL = 'myldap.server.com'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
 | 
					# Active Directory
 | 
				
			||||||
sudo sed -i "s/LDAP_ROOT_DN = ''/LDAP_ROOT_DN = 'dc=server,dc=com'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
 | 
					AUTH_LDAP_SERVER_URI = "ldap://example.com"
 | 
				
			||||||
 | 
					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 passphrase to decrypt the password
 | 
					Set the user filter and user and group search base and filter
 | 
				
			||||||
```bash
 | 
					
 | 
				
			||||||
sudo sed -i "s/pass:MYPASSPHRASE/pass:MYTRUEPASSPHRASE/g" /srv/webvirtcloud/webvirtcloud/.dec_ldap_pwd.sh
 | 
					```python
 | 
				
			||||||
 | 
					# 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
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Encrypt the password
 | 
					Set group which is required to access WebVirtCloud. You may set this to `False` to disable this filter.
 | 
				
			||||||
```bash
 | 
					
 | 
				
			||||||
echo MYPASSWORD | openssl enc -pbkdf2 -salt -pass pass:MYTRUEPASSPHRASE | base64
 | 
					```python
 | 
				
			||||||
 | 
					AUTH_LDAP_REQUIRE_GROUP = "CN=WebVirtCloud Access,CN=Users,DC=example,DC=com"
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Set the user that has browse access to LDAP and its password encrypted
 | 
					Populate user fields with values from LDAP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```python
 | 
				
			||||||
sudo sed -i "s/LDAP_MASTER_DN = ''/LDAP_MASTER_DN = 'cn=admin,ou=users,dc=kendar,dc=org'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
 | 
					AUTH_LDAP_USER_FLAGS_BY_GROUP = {
 | 
				
			||||||
sudo sed -i "s/LDAP_MASTER_PW_ENC = ''/LDAP_MASTER_PW_ENC = 'MYPASSWORDENCRYPTED'/g"" /srv/webvirtcloud/webvirtcloud/settings.py
 | 
					    "is_staff": "CN=WebVirtCloud Staff,CN=Users,DC=example,DC=com",
 | 
				
			||||||
 | 
					    "is_superuser": "CN=WebVirtCloud Admins,CN=Users,DC=example,DC=com",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					AUTH_LDAP_USER_ATTR_MAP = {
 | 
				
			||||||
 | 
					    "first_name": "givenName",
 | 
				
			||||||
 | 
					    "last_name": "sn",
 | 
				
			||||||
 | 
					    "email": "mail",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Set the attribute that will be used to find the username, i usually use the cn
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					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.
 | 
				
			||||||
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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
{% extends "base_auth.html" %}
 | 
					{% extends "base.html" %}
 | 
				
			||||||
{% load i18n %}
 | 
					{% load i18n %}
 | 
				
			||||||
{% block title %}
 | 
					{% block title %}
 | 
				
			||||||
    {% trans "WebVirtCloud" %} - {% trans "Sign Out"%}
 | 
					    {% trans "WebVirtCloud" %} - {% trans "Sign Out"%}
 | 
				
			||||||
| 
						 | 
					@ -14,4 +14,4 @@
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ def user_create(request):
 | 
				
			||||||
@superuser_only
 | 
					@superuser_only
 | 
				
			||||||
def user_update(request, pk):
 | 
					def user_update(request, pk):
 | 
				
			||||||
    user = get_object_or_404(User, pk=pk)
 | 
					    user = get_object_or_404(User, pk=pk)
 | 
				
			||||||
    attributes = UserAttributes.objects.get(user=user)
 | 
					    attributes, attributes_created = UserAttributes.objects.get_or_create(user=user)
 | 
				
			||||||
    user_form = forms.UserForm(request.POST or None, instance=user)
 | 
					    user_form = forms.UserForm(request.POST or None, instance=user)
 | 
				
			||||||
    attributes_form = forms.UserAttributesForm(
 | 
					    attributes_form = forms.UserAttributesForm(
 | 
				
			||||||
        request.POST or None, instance=attributes
 | 
					        request.POST or None, instance=attributes
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								appsettings/migrations/0009_alter_appsettings_id.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								appsettings/migrations/0009_alter_appsettings_id.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					# Generated by Django 4.2.5 on 2023-10-30 17:00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('appsettings', '0008_auto_20220905_1459'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='appsettings',
 | 
				
			||||||
 | 
					            name='id',
 | 
				
			||||||
 | 
					            field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										28
									
								
								appsettings/migrations/0010_auto_20231030_1305.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								appsettings/migrations/0010_auto_20231030_1305.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					# Generated by Django 4.2.5 on 2023-10-30 17:05
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def add_default_settings(apps, schema_editor):
 | 
				
			||||||
 | 
					    setting = apps.get_model("appsettings", "AppSettings")
 | 
				
			||||||
 | 
					    db_alias = schema_editor.connection.alias
 | 
				
			||||||
 | 
					    setting.objects.using(db_alias).bulk_create([
 | 
				
			||||||
 | 
					        setting(35, _("VM NIC Type"), "INSTANCE_NIC_DEFAULT_TYPE", "default", "default,e1000,e1000e,rt18139,virtio", _("Change instance default NIC type"))
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def del_default_settings(apps, schema_editor):
 | 
				
			||||||
 | 
					    setting = apps.get_model("appsettings", "AppSettings")
 | 
				
			||||||
 | 
					    db_alias = schema_editor.connection.alias
 | 
				
			||||||
 | 
					    setting.objects.using(db_alias).filter(key="INSTANCE_NIC_DEFAULT_TYPE").delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('appsettings', '0009_alter_appsettings_id')
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.RunPython(add_default_settings,del_default_settings)
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ server {
 | 
				
			||||||
        proxy_set_header X-Real-IP $remote_addr;
 | 
					        proxy_set_header X-Real-IP $remote_addr;
 | 
				
			||||||
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
 | 
					        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
 | 
				
			||||||
        proxy_set_header Host $host:$server_port;
 | 
					        proxy_set_header Host $host:$server_port;
 | 
				
			||||||
        proxy_set_header X-Forwarded-Proto $remote_addr;
 | 
					        proxy_set_header X-Forwarded-Proto http;
 | 
				
			||||||
        proxy_set_header X-Forwarded-Ssl off;
 | 
					        proxy_set_header X-Forwarded-Ssl off;
 | 
				
			||||||
        proxy_connect_timeout 1800;
 | 
					        proxy_connect_timeout 1800;
 | 
				
			||||||
        proxy_read_timeout 1800;
 | 
					        proxy_read_timeout 1800;
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,12 @@ server {
 | 
				
			||||||
        proxy_set_header Upgrade $http_upgrade;
 | 
					        proxy_set_header Upgrade $http_upgrade;
 | 
				
			||||||
        proxy_set_header Connection "upgrade";
 | 
					        proxy_set_header Connection "upgrade";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    location /websockify {
 | 
				
			||||||
 | 
					        proxy_pass http://wsnovncd;
 | 
				
			||||||
 | 
					        proxy_http_version 1.1;
 | 
				
			||||||
 | 
					        proxy_set_header Upgrade $http_upgrade;
 | 
				
			||||||
 | 
					        proxy_set_header Connection "upgrade";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
upstream wsnovncd {
 | 
					upstream wsnovncd {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ django-bootstrap-icons==0.8.6
 | 
				
			||||||
django-login-required-middleware==0.9.0
 | 
					django-login-required-middleware==0.9.0
 | 
				
			||||||
django-otp==1.3.0
 | 
					django-otp==1.3.0
 | 
				
			||||||
django-qr-code==3.1.1
 | 
					django-qr-code==3.1.1
 | 
				
			||||||
 | 
					django-auth-ldap==4.5.0
 | 
				
			||||||
gunicorn==21.2.0
 | 
					gunicorn==21.2.0
 | 
				
			||||||
libsass==0.22.0
 | 
					libsass==0.22.0
 | 
				
			||||||
libvirt-python==9.8.0
 | 
					libvirt-python==9.8.0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,7 +176,7 @@ def connect(sid, environ):
 | 
				
			||||||
    if child_pid:
 | 
					    if child_pid:
 | 
				
			||||||
        # already started child process, don't start another
 | 
					        # already started child process, don't start another
 | 
				
			||||||
        # write a new line so that when a client refresh the shell prompt is printed
 | 
					        # write a new line so that when a client refresh the shell prompt is printed
 | 
				
			||||||
        fd.write("\n")
 | 
					        os.write(fd, str.encode("\n"))
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # create child process attached to a pty we can read from and write to
 | 
					    # create child process attached to a pty we can read from and write to
 | 
				
			||||||
| 
						 | 
					@ -200,8 +200,13 @@ def disconnect(sid):
 | 
				
			||||||
    global child_pid
 | 
					    global child_pid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # kill pty process
 | 
					    # kill pty process
 | 
				
			||||||
    os.kill(child_pid, signal.SIGKILL)
 | 
					    try:
 | 
				
			||||||
    os.wait()
 | 
					        os.kill(child_pid, signal.SIGKILL)
 | 
				
			||||||
 | 
					        os.wait()
 | 
				
			||||||
 | 
					    except ProcessLookupError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    except ChildProcessError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # reset the variables
 | 
					    # reset the variables
 | 
				
			||||||
    fd = None
 | 
					    fd = None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,7 +200,7 @@
 | 
				
			||||||
                                                                        <div class="col-sm-7">
 | 
					                                                                        <div class="col-sm-7">
 | 
				
			||||||
                                                                            <select class="form-select" name="net_model">
 | 
					                                                                            <select class="form-select" name="net_model">
 | 
				
			||||||
                                                                                {% for model in net_models_host %}
 | 
					                                                                                {% for model in net_models_host %}
 | 
				
			||||||
                                                                                <option value="{{ model }}" {% if model == 'default'  %} selected {% endif %}>{{ model }}</option>
 | 
					                                                                                <option value="{{ model }}" {% if model == default_nic_type %} selected {% endif %}>{{ model }}</option>
 | 
				
			||||||
                                                                                {% endfor %}
 | 
					                                                                                {% endfor %}
 | 
				
			||||||
                                                                            </select>
 | 
					                                                                            </select>
 | 
				
			||||||
                                                                        </div>
 | 
					                                                                        </div>
 | 
				
			||||||
| 
						 | 
					@ -476,7 +476,7 @@
 | 
				
			||||||
                            <div class="col-sm-7">
 | 
					                            <div class="col-sm-7">
 | 
				
			||||||
                                <select class="form-select" name="net_model">
 | 
					                                <select class="form-select" name="net_model">
 | 
				
			||||||
                                    {% for model in net_models_host %}
 | 
					                                    {% for model in net_models_host %}
 | 
				
			||||||
                                    <option value="{{ model }}" {% if model == 'default'  %} selected {% endif %}>{{ model }}</option>
 | 
					                                    <option value="{{ model }}" {% if model == default_nic_type %} selected {% endif %}>{{ model }}</option>
 | 
				
			||||||
                                    {% endfor %}
 | 
					                                    {% endfor %}
 | 
				
			||||||
                                </select>
 | 
					                                </select>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
| 
						 | 
					@ -728,7 +728,7 @@
 | 
				
			||||||
                                <div class="col-sm-7">
 | 
					                                <div class="col-sm-7">
 | 
				
			||||||
                                    <select class="form-select" name="net_model">
 | 
					                                    <select class="form-select" name="net_model">
 | 
				
			||||||
                                        {% for model in net_models_host %}
 | 
					                                        {% for model in net_models_host %}
 | 
				
			||||||
                                        <option value="{{ model }}" {% if model == 'default'  %} selected {% endif %}>{{ model }}</option>
 | 
					                                        <option value="{{ model }}" {% if model == default_nic_type %} selected {% endif %}>{{ model }}</option>
 | 
				
			||||||
                                        {% endfor %}
 | 
					                                        {% endfor %}
 | 
				
			||||||
                                    </select>
 | 
					                                    </select>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import os
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
import string
 | 
					import string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from accounts.models import UserInstance
 | 
					from accounts.models import UserInstance, UserAttributes
 | 
				
			||||||
from appsettings.settings import app_settings
 | 
					from appsettings.settings import app_settings
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ def get_clone_free_names(size=10):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_user_quota(user, instance, cpu, memory, disk_size):
 | 
					def check_user_quota(user, instance, cpu, memory, disk_size):
 | 
				
			||||||
    ua = user.userattributes
 | 
					    ua, attributes_created = UserAttributes.objects.get_or_create(user=user)
 | 
				
			||||||
    msg = ""
 | 
					    msg = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if user.is_superuser:
 | 
					    if user.is_superuser:
 | 
				
			||||||
| 
						 | 
					@ -196,7 +196,7 @@ def get_dhcp_mac_address(vname):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_random_mac_address():
 | 
					def get_random_mac_address():
 | 
				
			||||||
    mac = "52:54:00:%02x:%02x:%02x" % (
 | 
					    mac = settings.MAC_OUI + ":%02x:%02x:%02x" % (
 | 
				
			||||||
        random.randint(0x00, 0xFF),
 | 
					        random.randint(0x00, 0xFF),
 | 
				
			||||||
        random.randint(0x00, 0xFF),
 | 
					        random.randint(0x00, 0xFF),
 | 
				
			||||||
        random.randint(0x00, 0xFF),
 | 
					        random.randint(0x00, 0xFF),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1692,6 +1692,7 @@ def create_instance(request, compute_id, arch, machine):
 | 
				
			||||||
        networks = sorted(conn.get_networks())
 | 
					        networks = sorted(conn.get_networks())
 | 
				
			||||||
        nwfilters = conn.get_nwfilters()
 | 
					        nwfilters = conn.get_nwfilters()
 | 
				
			||||||
        net_models_host = conn.get_network_models()
 | 
					        net_models_host = conn.get_network_models()
 | 
				
			||||||
 | 
					        default_nic_type = app_settings.INSTANCE_NIC_DEFAULT_TYPE
 | 
				
			||||||
        storages = sorted(conn.get_storages(only_actives=True))
 | 
					        storages = sorted(conn.get_storages(only_actives=True))
 | 
				
			||||||
        default_graphics = app_settings.QEMU_CONSOLE_DEFAULT_TYPE
 | 
					        default_graphics = app_settings.QEMU_CONSOLE_DEFAULT_TYPE
 | 
				
			||||||
        default_cdrom = app_settings.INSTANCE_CDROM_ADD
 | 
					        default_cdrom = app_settings.INSTANCE_CDROM_ADD
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
{% extends "base_auth.html" %}
 | 
					{% extends "base.html" %}
 | 
				
			||||||
{% load i18n %}
 | 
					{% load i18n %}
 | 
				
			||||||
{% block title %}{% trans "403" %}{% endblock %}
 | 
					{% block title %}{% trans "403" %}{% endblock %}
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
{% extends "base_auth.html" %}
 | 
					{% extends "base.html" %}
 | 
				
			||||||
{% load i18n %}
 | 
					{% load i18n %}
 | 
				
			||||||
{% block title %}{% trans "404" %}{% endblock %}
 | 
					{% block title %}{% trans "404" %}{% endblock %}
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@ import string
 | 
				
			||||||
import libvirt
 | 
					import libvirt
 | 
				
			||||||
import lxml.etree as etree
 | 
					import lxml.etree as etree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.conf import UserSettingsHolder, settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_kvm_available(xml):
 | 
					def is_kvm_available(xml):
 | 
				
			||||||
    kvm_domains = get_xml_path(xml, "//domain/@type='kvm'")
 | 
					    kvm_domains = get_xml_path(xml, "//domain/@type='kvm'")
 | 
				
			||||||
| 
						 | 
					@ -15,10 +17,12 @@ def is_kvm_available(xml):
 | 
				
			||||||
def randomMAC():
 | 
					def randomMAC():
 | 
				
			||||||
    """Generate a random MAC address."""
 | 
					    """Generate a random MAC address."""
 | 
				
			||||||
    # qemu MAC
 | 
					    # qemu MAC
 | 
				
			||||||
    oui = [0x52, 0x54, 0x00]
 | 
					    mac = settings.MAC_OUI + ":%02x:%02x:%02x" % (
 | 
				
			||||||
 | 
					        random.randint(0x00, 0xFF),
 | 
				
			||||||
    mac = oui + [random.randint(0x00, 0xFF), random.randint(0x00, 0xFF), random.randint(0x00, 0xFF)]
 | 
					        random.randint(0x00, 0xFF),
 | 
				
			||||||
    return ":".join(map(lambda x: "%02x" % x, mac))
 | 
					        random.randint(0x00, 0xFF),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    return mac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def randomUUID():
 | 
					def randomUUID():
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ configure_nginx () {
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  novncd_port_escape="$(echo -n "$novncd_port"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
 | 
					  novncd_port_escape="$(echo -n "$novncd_port"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
 | 
				
			||||||
  sed -i "s|\\(server 127.0.0.1:\\).*|\\1$novncd_port_escape;|" "$nginxfile"
 | 
					  sed -i "s|server 127.0.0.1:6080;|server 127.0.0.1:$novncd_port_escape;|" "$nginxfile"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -424,9 +424,15 @@ until [[ $setupfqdn == "yes" ]] || [[ $setupfqdn == "no" ]]; do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case $setupfqdn in
 | 
					  case $setupfqdn in
 | 
				
			||||||
    [yY] | [yY][Ee][Ss] )
 | 
					    [yY] | [yY][Ee][Ss] )
 | 
				
			||||||
    echo -n "  Q. What is the FQDN of your server? ($(hostname --fqdn)): "
 | 
					    fqdn=$(hostname --fqdn)
 | 
				
			||||||
      read -r fqdn
 | 
					    echo -n "  Q. What is the FQDN of your server? ($fqdn): "
 | 
				
			||||||
 | 
					      read -r fqdn_from_user
 | 
				
			||||||
      setupfqdn="yes"
 | 
					      setupfqdn="yes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if [ ! -z $fqdn_from_user ]; then
 | 
				
			||||||
 | 
					        fqdn=$fqdn_from_user
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      echo "     Setting to $fqdn"
 | 
					      echo "     Setting to $fqdn"
 | 
				
			||||||
      echo ""
 | 
					      echo ""
 | 
				
			||||||
      ;;
 | 
					      ;;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,18 +0,0 @@
 | 
				
			||||||
#!/bin/bash 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
##### 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# LDAP PASSWORD DECRYPTION SCRIPT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
##### 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ENC_PASSWD=$1 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo $(echo $ENC_PASSWD | base64 -d | openssl enc -pbkdf2 -salt -d -pass pass:MYPASSPHRASE )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,142 +0,0 @@
 | 
				
			||||||
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
 | 
					 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,9 @@ 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'.
 | 
				
			||||||
| 
						 | 
					@ -13,6 +15,8 @@ SECRET_KEY = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEBUG = False
 | 
					DEBUG = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MAC_OUI = '52:54:10'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALLOWED_HOSTS = ["*"]
 | 
					ALLOWED_HOSTS = ["*"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CSRF_TRUSTED_ORIGINS = ['http://localhost',]
 | 
					CSRF_TRUSTED_ORIGINS = ['http://localhost',]
 | 
				
			||||||
| 
						 | 
					@ -102,7 +106,7 @@ DATABASES = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AUTHENTICATION_BACKENDS = [
 | 
					AUTHENTICATION_BACKENDS = [
 | 
				
			||||||
    "django.contrib.auth.backends.ModelBackend",
 | 
					    "django.contrib.auth.backends.ModelBackend",
 | 
				
			||||||
    "webvirtcloud.ldapbackend.LdapAuthenticationBackend",
 | 
					    #"django_auth_ldap.backend.LDAPBackend",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LOGIN_URL = "/accounts/login/"
 | 
					LOGIN_URL = "/accounts/login/"
 | 
				
			||||||
| 
						 | 
					@ -196,7 +200,7 @@ WS_PUBLIC_PATH = "/novncd/"
 | 
				
			||||||
WS_CERT = None
 | 
					WS_CERT = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SOCKETIO_PORT = 6081
 | 
					SOCKETIO_PORT = 6081
 | 
				
			||||||
SOCKETIO_HOST = '0.0.0.0'
 | 
					SOCKETIO_HOST = "0.0.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Socketio public host
 | 
					# Socketio public host
 | 
				
			||||||
SOCKETIO_PUBLIC_HOST = None
 | 
					SOCKETIO_PUBLIC_HOST = None
 | 
				
			||||||
| 
						 | 
					@ -277,27 +281,23 @@ EMAIL_HOST_PASSWORD = ''
 | 
				
			||||||
# LDAP Config
 | 
					# LDAP Config
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LDAP_ENABLED = False
 | 
					AUTH_LDAP_SERVER_URI = "ldap://example.com"
 | 
				
			||||||
LDAP_URL = ''
 | 
					AUTH_LDAP_BIND_DN = "username@example.com"
 | 
				
			||||||
LDAP_PORT = 389
 | 
					AUTH_LDAP_BIND_PASSWORD = "password"
 | 
				
			||||||
USE_SSL = False
 | 
					AUTH_LDAP_USER_SEARCH = LDAPSearch(
 | 
				
			||||||
## The user with search rights on ldap. (e.g cn=admin,dc=kendar,dc=org)
 | 
					    "CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)"
 | 
				
			||||||
LDAP_MASTER_DN = ''
 | 
					)
 | 
				
			||||||
LDAP_MASTER_PW_ENC = ''
 | 
					AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
 | 
				
			||||||
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')
 | 
					    "CN=Users,DC=example,DC=com", ldap.SCOPE_SUBTREE, "(objectClass=group)"
 | 
				
			||||||
## The root dn (e.g. dc=kendar,dc=org)
 | 
					)
 | 
				
			||||||
LDAP_ROOT_DN = ''
 | 
					AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType()
 | 
				
			||||||
## Queries to identify the users, i use groupOfUniqueNames on openldap
 | 
					AUTH_LDAP_REQUIRE_GROUP = "CN=WebVirtCloud Access,CN=Users,DC=example,DC=com"
 | 
				
			||||||
 | 
					AUTH_LDAP_USER_FLAGS_BY_GROUP = {
 | 
				
			||||||
### PLEASE BE SURE memberOf overlay is activated on slapd
 | 
					    "is_staff": "CN=WebVirtCloud Staff,CN=Users,DC=example,DC=com",
 | 
				
			||||||
## e.g. memberOf=cn=admins,cn=staff,cn=technicians,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
 | 
					    "is_superuser": "CN=WebVirtCloud Admins,CN=Users,DC=example,DC=com",
 | 
				
			||||||
LDAP_SEARCH_GROUP_FILTER_ADMINS = ''
 | 
					}
 | 
				
			||||||
## e.g. memberOf=cn=staff,cn=technicians,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
 | 
					AUTH_LDAP_USER_ATTR_MAP = {
 | 
				
			||||||
LDAP_SEARCH_GROUP_FILTER_STAFF = ''
 | 
					    "first_name": "givenName",
 | 
				
			||||||
## e.g. memberOf=cn=technicians,cn=webvirtcloud,ou=groups,dc=kendar,dc=org
 | 
					    "last_name": "sn",
 | 
				
			||||||
LDAP_SEARCH_GROUP_FILTER_TECHNICIANS = ''
 | 
					    "email": "mail",
 | 
				
			||||||
## 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 = ''
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue