diff --git a/.gitignore b/.gitignore index b3ebced..0772847 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,8 @@ venv .idea .DS_* *.pyc -db.sqlite3 -console/cert.pem +db.sqlite3* +console/cert.pem* tags dhcpd.* +webvirtcloud/settings.py diff --git a/README.md b/README.md index f1b3767..8ec15f5 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,23 @@ sudo service supervisor restart WebVirtCloud is a virtualization web interface for admins and users. It can delegate Virtual Machine's to users. A noVNC viewer presents a full graphical console to the guest domain. KVM is currently the only hypervisor supported. +### Generate secret key +You should generate SECRET_KEY after cloning repo. Then put it into webvirtcloud/settings.py. + +```python +import random, string +haystack = string.ascii_letters + string.digits + string.punctuation +print(''.join([random.SystemRandom().choice(haystack) for _ in range(50)])) +``` + ### Install WebVirtCloud panel (Ubuntu) ```bash sudo apt-get -y install git python-virtualenv python-dev libxml2-dev libvirt-dev zlib1g-dev nginx supervisor libsasl2-modules gcc pkg-config git clone https://github.com/retspen/webvirtcloud cd webvirtcloud +cp webvirtcloud/settings.py.template webvirtcloud/settings.py +# now put secret key to webvirtcloud/settings.py sudo cp conf/supervisor/webvirtcloud.conf /etc/supervisor/conf.d sudo cp conf/nginx/webvirtcloud.conf /etc/nginx/conf.d cd .. @@ -63,6 +74,8 @@ sudo yum -y install python-virtualenv python-devel libvirt-devel glibc gcc nginx ```bash sudo mkdir /srv && cd /srv sudo git clone https://github.com/retspen/webvirtcloud && cd webvirtcloud +cp webvirtcloud/settings.py.template webvirtcloud/settings.py +# now put secret key to webvirtcloud/settings.py ``` #### Start installation webvirtcloud diff --git a/accounts/backends.py b/accounts/backends.py index 77aa509..e66b94a 100644 --- a/accounts/backends.py +++ b/accounts/backends.py @@ -1,7 +1,13 @@ from django.contrib.auth.backends import RemoteUserBackend +from accounts.models import UserInstance, UserAttributes +from instances.models import Instance class MyRemoteUserBackend(RemoteUserBackend): + + #create_unknown_user = True + def configure_user(self, user): - user.is_superuser = True + #user.is_superuser = True + UserAttributes.configure_user(user) return user diff --git a/accounts/migrations/0009_auto_20171026_0805.py b/accounts/migrations/0009_auto_20171026_0805.py new file mode 100644 index 0000000..7d035c7 --- /dev/null +++ b/accounts/migrations/0009_auto_20171026_0805.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0008_merge'), + ] + + operations = [ + migrations.AlterField( + model_name='userattributes', + name='can_clone_instances', + field=models.BooleanField(default=True), + ), + ] diff --git a/accounts/models.py b/accounts/models.py index 06fefee..19e3a20 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth.models import User +from django.conf import settings from instances.models import Instance @@ -24,11 +25,33 @@ class UserSSHKey(models.Model): class UserAttributes(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) - can_clone_instances = models.BooleanField(default=False) + can_clone_instances = models.BooleanField(default=True) max_instances = models.IntegerField(default=1) max_cpus = models.IntegerField(default=1) max_memory = models.IntegerField(default=2048) max_disk_size = models.IntegerField(default=20) + @staticmethod + def create_missing_userattributes(user): + try: + userattributes = user.userattributes + except UserAttributes.DoesNotExist: + userattributes = UserAttributes(user=user) + userattributes.save() + + @staticmethod + def add_default_instances(user): + existing_instances = UserInstance.objects.filter(user=user) + if not existing_instances: + for instance_name in settings.NEW_USER_DEFAULT_INSTANCES: + instance = Instance.objects.get(name=instance_name) + user_instance = UserInstance(user=user, instance=instance) + user_instance.save() + + @staticmethod + def configure_user(user): + UserAttributes.create_missing_userattributes(user) + UserAttributes.add_default_instances(user) + def __unicode__(self): return self.user.username diff --git a/accounts/templates/account.html b/accounts/templates/account.html index c8d8c19..0b39978 100644 --- a/accounts/templates/account.html +++ b/accounts/templates/account.html @@ -13,6 +13,31 @@ {% include 'errors_block.html' %} + {% if request.user.is_superuser and publickeys %} +
+
+
+ + + + + + + + + {% for publickey in publickeys %} + + + + + {% endfor %} + +
{% trans "Key name" %}{% trans "Public key" %}
{{ publickey.keyname }}{{ publickey.keypublic|truncatechars:64 }}
+
+
+
+ {% endif %} +
{% if not user_insts %} @@ -112,4 +137,4 @@ {% endif %}
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/accounts/templates/profile.html b/accounts/templates/profile.html index 3d15393..d2213b4 100644 --- a/accounts/templates/profile.html +++ b/accounts/templates/profile.html @@ -41,6 +41,7 @@ + {% if show_profile_edit_password %}
{% csrf_token %}
@@ -67,6 +68,7 @@
+ {% endif %} {% if publickeys %}
@@ -93,23 +95,23 @@ {% endif %}
{% csrf_token %}
- +
- +
- +
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/accounts/templatetags/tags_fingerprint.py b/accounts/templatetags/tags_fingerprint.py index 5688039..31f3952 100644 --- a/accounts/templatetags/tags_fingerprint.py +++ b/accounts/templatetags/tags_fingerprint.py @@ -7,6 +7,9 @@ register = template.Library() @register.simple_tag def ssh_to_fingerprint(line): - key = base64.b64decode(line.strip().split()[1].encode('ascii')) - fp_plain = hashlib.md5(key).hexdigest() - return ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])) + try: + key = base64.b64decode(line.strip().split()[1].encode('ascii')) + fp_plain = hashlib.md5(key).hexdigest() + return ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])) + except Exception: + return 'Invalid key' diff --git a/accounts/views.py b/accounts/views.py index 155ecc8..5fdfb4d 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -20,6 +20,7 @@ def profile(request): error_messages = [] user = User.objects.get(id=request.user.id) publickeys = UserSSHKey.objects.filter(user_id=request.user.id) + show_profile_edit_password = settings.SHOW_PROFILE_EDIT_PASSWORD if request.method == 'POST': if 'username' in request.POST: @@ -70,21 +71,11 @@ def accounts(request): :param request: :return: """ - - def create_missing_userattributes(users): - for user in users: - try: - userattributes = user.userattributes - except UserAttributes.DoesNotExist: - userattributes = UserAttributes(user=user) - userattributes.save() - if not request.user.is_superuser: return HttpResponseRedirect(reverse('index')) error_messages = [] users = User.objects.all().order_by('username') - create_missing_userattributes(users) allow_empty_password = settings.ALLOW_EMPTY_PASSWORD if request.method == 'POST': @@ -98,6 +89,7 @@ def accounts(request): if not error_messages: new_user = User.objects.create_user(data['name'], None, data['password']) new_user.save() + UserAttributes.configure_user(new_user) return HttpResponseRedirect(request.get_full_path()) if 'edit' in request.POST: user_id = request.POST.get('user_id', '') @@ -155,9 +147,7 @@ def account(request, user_id): user = User.objects.get(id=user_id) user_insts = UserInstance.objects.filter(user_id=user_id) instances = Instance.objects.all().order_by('name') - - if user.username == request.user.username: - return HttpResponseRedirect(reverse('profile')) + publickeys = UserSSHKey.objects.filter(user_id=user_id) if request.method == 'POST': if 'delete' in request.POST: diff --git a/console/templates/console-base.html b/console/templates/console-base.html index d0e0e7a..10ef4a3 100644 --- a/console/templates/console-base.html +++ b/console/templates/console-base.html @@ -1,11 +1,12 @@ +{% load staticfiles %} {% load i18n %} - + - - + +