diff --git a/hosting/forms.py b/hosting/forms.py index c94c4822..d309c983 100644 --- a/hosting/forms.py +++ b/hosting/forms.py @@ -4,6 +4,7 @@ from django import forms from membership.models import CustomUser from django.contrib.auth import authenticate +from django.utils.translation import ugettext_lazy as _ from utils.stripe_utils import StripeUtils @@ -57,10 +58,12 @@ class HostingUserSignupForm(forms.ModelForm): class UserHostingKeyForm(forms.ModelForm): - private_key = forms.CharField(widget=forms.PasswordInput(), required=False) - public_key = forms.CharField(widget=forms.PasswordInput(), required=False) - user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(), required=False) - name = forms.CharField(required=False) + private_key = forms.CharField(widget=forms.HiddenInput(), required=False) + public_key = forms.CharField(widget=forms.Textarea(), required=False, + help_text=_('Paste here your public key')) + user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(), + required=False, widget=forms.HiddenInput()) + name = forms.CharField(required=True) def __init__(self, *args, **kwargs): self.request = kwargs.pop("request") @@ -69,9 +72,7 @@ class UserHostingKeyForm(forms.ModelForm): # print(self.fields) def clean_name(self): - return "dcl-priv-key-%s" % ( - ''.join(random.choice(string.ascii_lowercase) for i in range(7)) - ) + return self.data.get('name') def clean_user(self): return self.request.user @@ -90,4 +91,15 @@ class UserHostingKeyForm(forms.ModelForm): class Meta: model = UserHostingKey - fields = ['user', 'public_key', 'name'] + fields = ['user', 'name', 'public_key'] + labels = { + 'public_key': _('Writer'), + } + help_texts = { + 'public_key': 'Put your shit here', + } + error_messages = { + 'name': { + 'max_length': _("This writer's name is too long."), + }, + } diff --git a/hosting/templates/hosting/virtual_machine_key.html b/hosting/templates/hosting/virtual_machine_key.html index d1917381..a2c3aef7 100644 --- a/hosting/templates/hosting/virtual_machine_key.html +++ b/hosting/templates/hosting/virtual_machine_key.html @@ -6,7 +6,7 @@
-
+ {% csrf_token %}

{% trans "Access Key"%}

{% if messages %} @@ -15,28 +15,25 @@ {{ message }} {% endfor %}
- {% endif %} -
- {% if not user_key %} -

+ {% endif %} + {% for field in form %} + + {% bootstrap_field field %} + {% endfor %} + {% buttons %} +

-
- - -
-
-
- -

- {% trans "Or generate a new key pair."%} - -

-
+ +
+
+ {% trans "Or generate a new key pair."%}
+
+ + {% endbuttons %} +
- {% else %}
Use your created key to access to the machine. If you lost it, contact us.

@@ -49,6 +46,7 @@ + {% for user_key in keys %} @@ -57,9 +55,9 @@ + {% endfor %}
{{user_key.name}} {{user_key.created_at}}
- {% endif %} {% if private_key %} diff --git a/hosting/tests.py b/hosting/tests.py index 7ce503c2..7cee782d 100644 --- a/hosting/tests.py +++ b/hosting/tests.py @@ -1,3 +1,5 @@ from django.test import TestCase # Create your tests here. + +test_user_can_add_key() diff --git a/hosting/views.py b/hosting/views.py index f08ad1a4..a694373a 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -301,16 +301,12 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView): self ).get_context_data(**kwargs) - try: - user_key = UserHostingKey.objects.get( - user=self.request.user - ) - - except UserHostingKey.DoesNotExist: - user_key = None + user_keys = UserHostingKey.objects.filter( + user=self.request.user + ) context.update({ - 'user_key': user_key + 'keys': user_keys }) return context @@ -351,24 +347,25 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView): opennebula_user = user_pool.get_by_name(owner.email) # Get user ssh key - user_key = UserHostingKey.objects.get(user=owner) + public_key = form.cleaned_data.get('public_key') # Add ssh key to user manager.oneadmin_client.call('user.update', opennebula_user.id, - '{ssh_key}'.format(ssh_key=user_key.public_key)) + '{key}'.format(key=public_key)) return render(self.request, self.template_name, context) def post(self, request, *args, **kwargs): - try: - UserHostingKey.objects.get( - user=self.request.user - ) - return HttpResponseRedirect(reverse('hosting:key_pair')) + # try: + # UserHostingKey.objects.get( + # user=self.request.user + # ) + # return HttpResponseRedirect(reverse('hosting:key_pair')) - except UserHostingKey.DoesNotExist: - pass + # except UserHostingKey.DoesNotExist: + # pass + form = self.get_form() if form.is_valid(): return self.form_valid(form) diff --git a/opennebula_api/models.py b/opennebula_api/models.py index 052291c1..7872f6fc 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -446,7 +446,7 @@ class OpenNebulaManager(): Args: user (CustomUser): Dynamicweb user public_key (string): Public key to add to the user - replace (bool): Optional if True the new public key replaces the old + merge (bool): Optional if True the new public key replaces the old Raises: KeyExistsError: If replace is False and the user already has a diff --git a/opennebula_api/serializers.py b/opennebula_api/serializers.py index 60ce16f9..226d9f47 100644 --- a/opennebula_api/serializers.py +++ b/opennebula_api/serializers.py @@ -42,7 +42,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): class VirtualMachineSerializer(serializers.Serializer): """Serializer to map the virtual machine instance into JSON format.""" - name = serializers.CharField(read_only=True) + name = serializers.SerializerMethodField() cores = serializers.IntegerField(source='template.vcpu') disk = serializers.IntegerField(write_only=True) set_memory = serializers.IntegerField(write_only=True, label='Memory') @@ -127,6 +127,8 @@ class VirtualMachineSerializer(serializers.Serializer): nic = obj.template.nics[0] return nic.ip6_global + def get_name(self, obj): + return obj.name.strip('public-') def hexstr2int(string): return int(string.replace(':', ''), 16) diff --git a/opennebula_api/tests.py b/opennebula_api/tests.py index 0d6ed4eb..073eb0b9 100644 --- a/opennebula_api/tests.py +++ b/opennebula_api/tests.py @@ -99,10 +99,70 @@ class OpenNebulaManagerTestCases(TestCase): self.assertEqual(new_public_key, '{}\n{}'.format(old_public_key, public_key)) + def test_remove_public_key_to_user(self): + """ Test the manager can remove a public key from an user """ + self.manager.create_user(self.user) + user = self.manager._get_user(self.user) + public_key = 'test' + self.manager.add_public_key(self.user, public_key) + old_public_key = user.template.ssh_public_key + self.manager.remove_public_key(self.user, public_key) + user.info() + new_public_key = user.template.ssh_public_key + # Cleanup + user.delete() + + self.assertEqual(new_public_key, old_public_key.replace(public_key, '')) + + def test_requires_ssh_key_for_new_vm(self): """Test the opennebula manager requires the user to have a ssh key when creating a new vm""" +class VirtualMachineTestCase(TestCase): + def setUp(self): + """Define the test client and other test variables.""" + self.template_name = "Standard" + self.base_price = 0.0 + self.core_price = 5.0 + self.memory_price = 2.0 + self.disk_size_price = 0.6 + + self.cores = 1 + self.memory = 1 + self.disk_size = 10.0 + self.manager = OpenNebulaManager(email=None, password=None, create_user=False) + self.opennebula_id = self.manager.create_template(name=self.template_name, + cores=self.cores, + memory=self.memory, + disk_size=self.disk_size) + + self.template = VirtualMachineTemplate(opennebula_id=self.opennebula_id, + base_price=self.base_price, + memory_price=self.memory_price, + core_price=self.core_price, + disk_size_price=self.disk_size_price) + self.template_id = self.template.opennebula_id() + self.opennebula_id = self.manager.create_virtualmachine(template_id=self.template_id) + + self.virtualmachine = VirtualMachine(opennebula_id=self.opennebula_id, + template=self.template) + + def test_serializer_strips_of_public(self): + """ Test the serialized object contains no 'public-'.""" + + template = self.manager.get_templates().first() + serialized = VirtualMachineTemplateSerializer(template) + self.assertEqual(serialized.data.name, template.name.strip('public-')) + + + + def test_model_can_create_a_virtualmachine(self): + """Test the virtualmachine model can create a virtualmachine.""" + old_count = VirtualMachine.objects.count() + self.virtualmachine.save() + new_count = VirtualMachine.objects.count() + self.assertNotEqual(old_count, new_count)