From 636b5bb1bc0065cc0e265cdf5118dca11c10f3f7 Mon Sep 17 00:00:00 2001 From: Real-Gecko Date: Tue, 16 Jun 2020 18:35:08 +0600 Subject: [PATCH] Reworked some account views --- accounts/forms.py | 30 +++ .../migrations/0005_auto_20200616_1039.py | 20 ++ accounts/models.py | 5 +- accounts/templates/account.html | 189 ++++++------------ .../templates/create_user_inst_block.html | 36 ---- accounts/urls.py | 3 + accounts/views.py | 115 +++++------ instances/models.py | 2 +- 8 files changed, 179 insertions(+), 221 deletions(-) create mode 100644 accounts/forms.py create mode 100644 accounts/migrations/0005_auto_20200616_1039.py delete mode 100644 accounts/templates/create_user_inst_block.html diff --git a/accounts/forms.py b/accounts/forms.py new file mode 100644 index 0000000..8c05b75 --- /dev/null +++ b/accounts/forms.py @@ -0,0 +1,30 @@ +from django.forms import ModelForm, ValidationError +from django.utils.translation import ugettext_lazy as _ + +from appsettings.models import AppSettings + +from .models import UserInstance + + +class UserInstanceForm(ModelForm): + def __init__(self, *args, **kwargs): + super(UserInstanceForm, self).__init__(*args, **kwargs) + + # Make user and instance fields not editable after creation + instance = getattr(self, 'instance', None) + if instance and instance.id is not None: + self.fields['user'].disabled = True + self.fields['instance'].disabled = True + + def clean_instance(self): + instance = self.cleaned_data['instance'] + if AppSettings.objects.get(key="ALLOW_INSTANCE_MULTIPLE_OWNER").value == 'False': + exists = UserInstance.objects.filter(instance=instance) + if exists: + raise ValidationError(_('Instance owned by another user')) + + return instance + + class Meta: + model = UserInstance + fields = '__all__' diff --git a/accounts/migrations/0005_auto_20200616_1039.py b/accounts/migrations/0005_auto_20200616_1039.py new file mode 100644 index 0000000..bf48ddc --- /dev/null +++ b/accounts/migrations/0005_auto_20200616_1039.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.13 on 2020-06-16 10:39 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('instances', '0003_auto_20200615_0637'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('accounts', '0004_auto_20200615_0637'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='userinstance', + unique_together={('user', 'instance')}, + ), + ] diff --git a/accounts/models.py b/accounts/models.py index 614dfb9..072d9f2 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -15,7 +15,10 @@ class UserInstance(models.Model): is_vnc = models.BooleanField(default=False) def __str__(self): - return self.instance.name + return _('Instance "%(inst)s" of user %(user)s') % {'inst': self.instance, 'user': self.user} + + class Meta: + unique_together = ['user', 'instance'] class UserSSHKey(models.Model): diff --git a/accounts/templates/account.html b/accounts/templates/account.html index 087f431..658c35f 100644 --- a/accounts/templates/account.html +++ b/accounts/templates/account.html @@ -1,140 +1,83 @@ {% extends "base.html" %} {% load i18n %} -{% block title %}{% trans "User" %} - {{ user }}{% endblock %} +{% load icons %} +{% block title %}{% trans "User Profile" %} - {{ user }}{% endblock %} {% block content %}
- {% include 'create_user_inst_block.html' %} - + + {% icon 'plus' %} + +
{% include 'errors_block.html' %} - {% if request.user.is_superuser and publickeys %} -
-
-
- - + + +
+
+
+ + + + + + + + + + + + {% for inst in user_insts %} - - - - - - {% for publickey in publickeys %} - - - + + + + + + + {% endfor %} - -
#{% trans "Instance" %}{% trans "VNC" %}{% trans "Resize" %}{% trans "Delete" %}{% trans "Action" %}
{% trans "Key name" %}{% trans "Public key" %}
{{ publickey.keyname }}{{ publickey.keypublic|truncatechars:64 }}{{ forloop.counter }}{{ inst.instance.name }}{{ inst.is_vnc }}{{ inst.is_change }}{{ inst.is_delete }} + + {% icon 'pencil' %} + + + + {% icon 'trash' %} + +
-
+ + +
+
+ + + + + + + + + {% for publickey in publickeys %} + + + + + {% endfor %} + +
{% trans "Key name" %}{% trans "Public key" %}
{{ publickey.keyname }}{{ publickey.keypublic|truncatechars:64 }}
- {% endif %} - -
-
- {% if not user_insts %} -
-
- - {% trans "Warning" %}: {% trans "User doesn't have any Instance" %} -
-
- {% else %} -
- - - - - - - - - - - - - {% for inst in user_insts %} - - - - - - - - - - {% endfor %} - -
#{% trans "Instance" %}{% trans "VNC" %}{% trans "Resize" %}{% trans "Delete" %}{% trans "Action" %}
{{ forloop.counter }}{{ inst.instance.name }}{{ inst.is_vnc }}{{ inst.is_change }}{{ inst.is_delete }} - - - - - - - -
{% csrf_token %} - - -
-
-
- {% endif %} -
-
-{% endblock %} +{% endblock content %} diff --git a/accounts/templates/create_user_inst_block.html b/accounts/templates/create_user_inst_block.html deleted file mode 100644 index c496c01..0000000 --- a/accounts/templates/create_user_inst_block.html +++ /dev/null @@ -1,36 +0,0 @@ -{% load i18n %} -{% if request.user.is_superuser %} - - - - - - -{% endif %} \ No newline at end of file diff --git a/accounts/urls.py b/accounts/urls.py index bf4ad8b..6e170ae 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -9,4 +9,7 @@ urlpatterns = [ path('profile/', views.profile, name='profile'), path('profile//', views.account, name='account'), path('change_password/', views.change_password, name='change_password'), + path('user_instance/create//', views.user_instance_create, name='user_instance_create'), + path('user_instance//update/', views.user_instance_update, name='user_instance_update'), + path('user_instance//delete/', views.user_instance_delete, name='user_instance_delete'), ] diff --git a/accounts/views.py b/accounts/views.py index 53d120f..2bd765c 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -7,7 +7,7 @@ from django.contrib.auth.decorators import permission_required from django.contrib.auth.forms import PasswordChangeForm from django.core.validators import ValidationError from django.http import HttpResponseRedirect -from django.shortcuts import redirect, render +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.translation import ugettext_lazy as _ @@ -16,15 +16,11 @@ from admin.decorators import superuser_only from appsettings.models import AppSettings from instances.models import Instance +from . import forms + def profile(request): - """ - :param request: - :return: - """ - error_messages = [] - # user = User.objects.get(id=request.user.id) publickeys = UserSSHKey.objects.filter(user_id=request.user.id) if request.method == 'POST': @@ -35,20 +31,6 @@ def profile(request): user.email = email request.user.save() return HttpResponseRedirect(request.get_full_path()) - if 'oldpasswd' in request.POST: - oldpasswd = request.POST.get('oldpasswd', '') - password1 = request.POST.get('passwd1', '') - password2 = request.POST.get('passwd2', '') - if not password1 or not password2: - error_messages.append("Passwords didn't enter") - if password1 and password2 and password1 != password2: - error_messages.append("Passwords don't match") - if not request.user.check_password(oldpasswd): - error_messages.append("Old password is wrong!") - if not error_messages: - request.user.set_password(password1) - request.user.save() - return HttpResponseRedirect(request.get_full_path()) if 'keyname' in request.POST: keyname = request.POST.get('keyname', '') keypublic = request.POST.get('keypublic', '') @@ -76,51 +58,12 @@ def profile(request): @superuser_only def account(request, user_id): - """ - :param request: - :param user_id: - :return: - """ - error_messages = [] user = User.objects.get(id=user_id) user_insts = UserInstance.objects.filter(user_id=user_id) instances = Instance.objects.all().order_by('name') publickeys = UserSSHKey.objects.filter(user_id=user_id) - if request.method == 'POST': - if 'delete' in request.POST: - user_inst = request.POST.get('user_inst', '') - del_user_inst = UserInstance.objects.get(id=user_inst) - del_user_inst.delete() - return HttpResponseRedirect(request.get_full_path()) - if 'permission' in request.POST: - user_inst = request.POST.get('user_inst', '') - inst_vnc = request.POST.get('inst_vnc', '') - inst_change = request.POST.get('inst_change', '') - inst_delete = request.POST.get('inst_delete', '') - edit_user_inst = UserInstance.objects.get(id=user_inst) - edit_user_inst.is_change = bool(inst_change) - edit_user_inst.is_delete = bool(inst_delete) - edit_user_inst.is_vnc = bool(inst_vnc) - edit_user_inst.save() - return HttpResponseRedirect(request.get_full_path()) - if 'add' in request.POST: - inst_id = request.POST.get('inst_id', '') - - if AppSettings.objects.get(key="ALLOW_INSTANCE_MULTIPLE_OWNER").value == 'True': - check_inst = UserInstance.objects.filter(instance_id=int(inst_id), user_id=int(user_id)) - else: - check_inst = UserInstance.objects.filter(instance_id=int(inst_id)) - - if check_inst: - msg = _("Instance already added") - error_messages.append(msg) - else: - add_user_inst = UserInstance(instance_id=int(inst_id), user_id=int(user_id)) - add_user_inst.save() - return HttpResponseRedirect(request.get_full_path()) - return render(request, 'account.html', locals()) @@ -138,3 +81,55 @@ def change_password(request): else: form = PasswordChangeForm(request.user) return render(request, 'accounts/change_password_form.html', {'form': form}) + + +@superuser_only +def user_instance_create(request, user_id): + user = get_object_or_404(User, pk=user_id) + + form = forms.UserInstanceForm(request.POST or None, initial={'user': user}) + if form.is_valid(): + form.save() + return redirect(reverse('account', args=[user.id])) + + return render( + request, + 'common/form.html', + { + 'form': form, + 'title': _('Create User Instance'), + }, + ) + + +@superuser_only +def user_instance_update(request, pk): + user_instance = get_object_or_404(UserInstance, pk=pk) + form = forms.UserInstanceForm(request.POST or None, instance=user_instance) + if form.is_valid(): + form.save() + return redirect(reverse('account', args=[user_instance.user.id])) + + return render( + request, + 'common/form.html', + { + 'form': form, + 'title': _('Update User Instance'), + }, + ) + + +@superuser_only +def user_instance_delete(request, pk): + user_instance = get_object_or_404(UserInstance, pk=pk) + if request.method == 'POST': + user = user_instance.user + user_instance.delete() + return redirect(reverse('account', args=[user.id])) + + return render( + request, + 'common/confirm_delete.html', + {'object': user_instance}, + ) diff --git a/instances/models.py b/instances/models.py index daa2e5f..cec6d39 100644 --- a/instances/models.py +++ b/instances/models.py @@ -12,7 +12,7 @@ class Instance(Model): created = DateField(_('created'), auto_now_add=True) def __str__(self): - return self.name + return f'{self.compute}/{self.name}' class PermissionSet(Model):