Merge pull request #428 from tiwariav/task/3620/ssh_keys

task/3620 ssh_keys_choice page new design
This commit is contained in:
Pcoder 2017-08-03 22:53:12 +02:00 committed by GitHub
commit 3d051aee14
16 changed files with 857 additions and 369 deletions

View file

@ -19,7 +19,6 @@ from hosting.models import HostingOrder, HostingBill
from utils.stripe_utils import StripeUtils from utils.stripe_utils import StripeUtils
from datetime import datetime from datetime import datetime
from membership.models import CustomUser, StripeCustomer from membership.models import CustomUser, StripeCustomer
from opennebula_api.models import OpenNebulaManager from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer, VMTemplateSerializer from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer, VMTemplateSerializer
@ -34,6 +33,7 @@ class SuccessView(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if 'specs' not in request.session or 'user' not in request.session: if 'specs' not in request.session or 'user' not in request.session:
return HttpResponseRedirect(reverse('datacenterlight:index')) return HttpResponseRedirect(reverse('datacenterlight:index'))
elif 'token' not in request.session: elif 'token' not in request.session:
return HttpResponseRedirect(reverse('datacenterlight:payment')) return HttpResponseRedirect(reverse('datacenterlight:payment'))
elif 'order_confirmation' not in request.session: elif 'order_confirmation' not in request.session:
@ -79,7 +79,8 @@ class PricingView(TemplateView):
manager = OpenNebulaManager() manager = OpenNebulaManager()
template = manager.get_template(template_id) template = manager.get_template(template_id)
request.session['template'] = VirtualMachineTemplateSerializer(template).data request.session['template'] = VirtualMachineTemplateSerializer(
template).data
if not request.user.is_authenticated(): if not request.user.is_authenticated():
request.session['next'] = reverse('hosting:payment') request.session['next'] = reverse('hosting:payment')
@ -131,7 +132,8 @@ class BetaAccessView(FormView):
email = BaseEmail(**email_data) email = BaseEmail(**email_data)
email.send() email.send()
messages.add_message(self.request, messages.SUCCESS, self.success_message) messages.add_message(
self.request, messages.SUCCESS, self.success_message)
return render(self.request, 'datacenterlight/beta_success.html', {}) return render(self.request, 'datacenterlight/beta_success.html', {})
@ -183,7 +185,8 @@ class BetaProgramView(CreateView):
email = BaseEmail(**email_data) email = BaseEmail(**email_data)
email.send() email.send()
messages.add_message(self.request, messages.SUCCESS, self.success_message) messages.add_message(
self.request, messages.SUCCESS, self.success_message)
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
@ -227,7 +230,8 @@ class IndexView(CreateView):
storage_field = forms.IntegerField(validators=[self.validate_storage]) storage_field = forms.IntegerField(validators=[self.validate_storage])
price = request.POST.get('total') price = request.POST.get('total')
template_id = int(request.POST.get('config')) template_id = int(request.POST.get('config'))
template = VMTemplate.objects.filter(opennebula_vm_template_id=template_id).first() template = VMTemplate.objects.filter(
opennebula_vm_template_id=template_id).first()
template_data = VMTemplateSerializer(template).data template_data = VMTemplateSerializer(template).data
name = request.POST.get('name') name = request.POST.get('name')
@ -239,35 +243,40 @@ class IndexView(CreateView):
cores = cores_field.clean(cores) cores = cores_field.clean(cores)
except ValidationError as err: except ValidationError as err:
msg = '{} : {}.'.format(cores, str(err)) msg = '{} : {}.'.format(cores, str(err))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='cores') messages.add_message(
self.request, messages.ERROR, msg, extra_tags='cores')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try: try:
memory = memory_field.clean(memory) memory = memory_field.clean(memory)
except ValidationError as err: except ValidationError as err:
msg = '{} : {}.'.format(memory, str(err)) msg = '{} : {}.'.format(memory, str(err))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='memory') messages.add_message(
self.request, messages.ERROR, msg, extra_tags='memory')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try: try:
storage = storage_field.clean(storage) storage = storage_field.clean(storage)
except ValidationError as err: except ValidationError as err:
msg = '{} : {}.'.format(storage, str(err)) msg = '{} : {}.'.format(storage, str(err))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='storage') messages.add_message(
self.request, messages.ERROR, msg, extra_tags='storage')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try: try:
name = name_field.clean(name) name = name_field.clean(name)
except ValidationError as err: except ValidationError as err:
msg = '{} {}.'.format(name, _('is not a proper name')) msg = '{} {}.'.format(name, _('is not a proper name'))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='name') messages.add_message(
self.request, messages.ERROR, msg, extra_tags='name')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try: try:
email = email_field.clean(email) email = email_field.clean(email)
except ValidationError as err: except ValidationError as err:
msg = '{} {}.'.format(email, _('is not a proper email')) msg = '{} {}.'.format(email, _('is not a proper email'))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='email') messages.add_message(
self.request, messages.ERROR, msg, extra_tags='email')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form") return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
specs = { specs = {
@ -332,7 +341,8 @@ class IndexView(CreateView):
email = BaseEmail(**email_data) email = BaseEmail(**email_data)
email.send() email.send()
messages.add_message(self.request, messages.SUCCESS, self.success_message) messages.add_message(
self.request, messages.SUCCESS, self.success_message)
return super(IndexView, self).form_valid(form) return super(IndexView, self).form_valid(form)
@ -401,6 +411,7 @@ class PaymentOrderView(FormView):
# Create Billing Address # Create Billing Address
billing_address = form.save() billing_address = form.save()
request.session['billing_address_data'] = billing_address_data request.session['billing_address_data'] = billing_address_data
request.session['billing_address'] = billing_address.id request.session['billing_address'] = billing_address.id
request.session['token'] = token request.session['token'] = token
@ -425,7 +436,8 @@ class OrderConfirmationView(DetailView):
stripe_customer_id = request.session.get('customer') stripe_customer_id = request.session.get('customer')
customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
stripe_utils = StripeUtils() stripe_utils = StripeUtils()
card_details = stripe_utils.get_card_details(customer.stripe_id, request.session.get('token')) card_details = stripe_utils.get_card_details(
customer.stripe_id, request.session.get('token'))
context = { context = {
'site_url': reverse('datacenterlight:index'), 'site_url': reverse('datacenterlight:index'),
'cc_last4': card_details.get('response_object').get('last4'), 'cc_last4': card_details.get('response_object').get('last4'),
@ -441,7 +453,8 @@ class OrderConfirmationView(DetailView):
customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
billing_address_data = request.session.get('billing_address_data') billing_address_data = request.session.get('billing_address_data')
billing_address_id = request.session.get('billing_address') billing_address_id = request.session.get('billing_address')
billing_address = BillingAddress.objects.filter(id=billing_address_id).first() billing_address = BillingAddress.objects.filter(
id=billing_address_id).first()
vm_template_id = template.get('id', 1) vm_template_id = template.get('id', 1)
final_price = specs.get('price') final_price = specs.get('price')

View file

@ -195,7 +195,7 @@ CMS_TEMPLATES = (
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'app' 'NAME': 'app',
} }
} }

View file

@ -1,4 +1,4 @@
from .base import * # flake8: noqa from .base import * # flake8: noqa
# List of people that get admin messages # List of people that get admin messages
ADMINS = ((x, x + "@ungleich.ch") for x in ["web-team"]) ADMINS = ((x, x + "@ungleich.ch") for x in ["web-team"])

View file

@ -1,3 +1,5 @@
import datetime
from django import forms from django import forms
from membership.models import CustomUser from membership.models import CustomUser
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
@ -7,6 +9,10 @@ from django.utils.translation import ugettext_lazy as _
from .models import UserHostingKey from .models import UserHostingKey
def generate_ssh_key_name():
return 'dcl-generated-key-' + datetime.datetime.now().strftime('%m%d%y%H%M')
class HostingUserLoginForm(forms.Form): class HostingUserLoginForm(forms.Form):
email = forms.CharField(widget=forms.EmailInput()) email = forms.CharField(widget=forms.EmailInput())
@ -20,9 +26,11 @@ class HostingUserLoginForm(forms.Form):
password = self.cleaned_data.get('password') password = self.cleaned_data.get('password')
is_auth = authenticate(email=email, password=password) is_auth = authenticate(email=email, password=password)
if not is_auth: if not is_auth:
raise forms.ValidationError("Your username and/or password were incorrect.") raise forms.ValidationError(
_("Your username and/or password were incorrect."))
elif is_auth.validated == 0: elif is_auth.validated == 0:
raise forms.ValidationError(_("Your account is not activated yet.")) raise forms.ValidationError(
_("Your account is not activated yet."))
return self.cleaned_data return self.cleaned_data
def clean_email(self): def clean_email(self):
@ -58,15 +66,19 @@ class HostingUserSignupForm(forms.ModelForm):
class UserHostingKeyForm(forms.ModelForm): class UserHostingKeyForm(forms.ModelForm):
private_key = forms.CharField(widget=forms.HiddenInput(), required=False) private_key = forms.CharField(widget=forms.HiddenInput(), required=False)
public_key = forms.CharField(widget=forms.Textarea(), required=False, public_key = forms.CharField(widget=forms.Textarea(
help_text=_('Paste here your public key')) attrs={'class': 'form_public_key', 'placeholder': _('Paste here your public key')}),
required=False,
)
user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(), user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(),
required=False, widget=forms.HiddenInput()) required=False, widget=forms.HiddenInput())
name = forms.CharField(required=True) name = forms.CharField(required=False, widget=forms.TextInput(
attrs={'class': 'form_key_name', 'placeholder': _('Give a name to your key')}))
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request") self.request = kwargs.pop("request")
super(UserHostingKeyForm, self).__init__(*args, **kwargs) super(UserHostingKeyForm, self).__init__(*args, **kwargs)
self.fields['name'].label = _('Key name')
def clean_name(self): def clean_name(self):
return self.data.get('name') return self.data.get('name')
@ -76,7 +88,8 @@ class UserHostingKeyForm(forms.ModelForm):
def clean(self): def clean(self):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
if not self.cleaned_data.get('name', ''):
self.cleaned_data['name'] = generate_ssh_key_name()
if not cleaned_data.get('public_key'): if not cleaned_data.get('public_key'):
private_key, public_key = UserHostingKey.generate_keys() private_key, public_key = UserHostingKey.generate_keys()
cleaned_data.update({ cleaned_data.update({

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-07-17 00:53+0530\n" "POT-Creation-Date: 2017-08-03 03:31+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,359 +18,271 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: forms.py:25 msgid "Your username and/or password were incorrect."
msgstr "Dein Benutzername und/oder Dein Passwort ist falsch."
msgid "Your account is not activated yet." msgid "Your account is not activated yet."
msgstr "Dein Account wurde noch nicht aktiviert." msgstr "Dein Account wurde noch nicht aktiviert."
#: forms.py:62
msgid "Paste here your public key" msgid "Paste here your public key"
msgstr "Fügen Sie Ihren public key ein" msgstr "Füge deinen Public Key ein"
msgid "Give a name to your key"
msgstr "Gebe deinem SSH-Key einen Name"
msgid "Key name"
msgstr "Key-Name"
#: templates/hosting/base_short.html:71
msgid "My Virtual Machines" msgid "My Virtual Machines"
msgstr "Meine virtuellen Maschinen" msgstr "Meine virtuellen Maschinen"
#: templates/hosting/base_short.html:76 templates/hosting/orders.html.py:12
msgid "My Orders" msgid "My Orders"
msgstr "Meine Bestellungen" msgstr "Meine Bestellungen"
#: templates/hosting/base_short.html:85
msgid "Keys"
msgstr "Schlüssel"
#: templates/hosting/base_short.html:90
msgid "Notifications " msgid "Notifications "
msgstr "Benachrichtigungen" msgstr "Benachrichtigungen"
#: templates/hosting/base_short.html:93
msgid "Logout" msgid "Logout"
msgstr "Abmelden" msgstr "Abmelden"
#: templates/hosting/base_short.html:98
msgid "How it works"
msgstr "So funktioniert es"
#: templates/hosting/base_short.html:101
msgid "Your infrastructure"
msgstr "deine Infrastruktur"
#: templates/hosting/base_short.html:104
msgid "Our inftrastructure"
msgstr "Unsere Infrastruktur"
#: templates/hosting/base_short.html:107
msgid "Pricing"
msgstr "Preise"
#: templates/hosting/base_short.html:110
msgid "Contact"
msgstr "Kontakt"
#: templates/hosting/base_short.html:113
#: templates/hosting/confirm_reset_password.html:38
#: templates/hosting/login.html:17 templates/hosting/login.html.py:26
#: templates/hosting/reset_password.html:32 templates/hosting/signup.html:30
msgid "Login"
msgstr "Anmelden"
#: templates/hosting/bill_detail.html:11
msgid "Invoice" msgid "Invoice"
msgstr "Rechnung" msgstr "Rechnung"
#: templates/hosting/bill_detail.html:11 templates/hosting/order_detail.html:23
msgid "Order #" msgid "Order #"
msgstr "Bestellung #" msgstr "Bestellung #"
#: templates/hosting/bill_detail.html:25
msgid "ungleich GmbH" msgid "ungleich GmbH"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:26
msgid "buchhaltung@ungleich.ch" msgid "buchhaltung@ungleich.ch"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:27
msgid "Hauptstrasse 14" msgid "Hauptstrasse 14"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:28
msgid "CH-8775 Luchsingen" msgid "CH-8775 Luchsingen"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:29
msgid "Mwst-Nummer: CHE-109.549.333 MWST" msgid "Mwst-Nummer: CHE-109.549.333 MWST"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:60
msgid "Total:" msgid "Total:"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:68
#, python-format #, python-format
msgid "Alles Preise in CHF mit 8%% Mehrwertsteuer." msgid "Alles Preise in CHF mit 8%% Mehrwertsteuer."
msgstr "All prices in CHF including 8%% VAT" msgstr "All prices in CHF including 8%% VAT"
#: templates/hosting/bill_detail.html:69
msgid "Betrag zahlbar innerhalb von 30 Tagen ab Rechnungseingang." msgid "Betrag zahlbar innerhalb von 30 Tagen ab Rechnungseingang."
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:70
msgid "Kontoverbindung:" msgid "Kontoverbindung:"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:73
msgid "IBAN:" msgid "IBAN:"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:76
msgid "BIC:" msgid "BIC:"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:81
msgid "CH02 0900 0000 6071 8848 8" msgid "CH02 0900 0000 6071 8848 8"
msgstr "" msgstr ""
#: templates/hosting/bill_detail.html:84
msgid "POFICHBEXXX" msgid "POFICHBEXXX"
msgstr "" msgstr ""
#: templates/hosting/bills.html:12
msgid "Customers" msgid "Customers"
msgstr "Kunden" msgstr "Kunden"
#: templates/hosting/bills.html:16 templates/hosting/user_keys.html.py:25
msgid "Name" msgid "Name"
msgstr "" msgstr ""
#: templates/hosting/bills.html:17
msgid "Email" msgid "Email"
msgstr "" msgstr ""
#: templates/hosting/bills.html:28
msgid "View Bill" msgid "View Bill"
msgstr "Rechnung anzeigen" msgstr "Rechnung anzeigen"
#: templates/hosting/bills.html:41 templates/hosting/orders.html.py:82
#: templates/hosting/virtual_machines.html:70
msgid "previous" msgid "previous"
msgstr "vorherige" msgstr "vorherige"
#: templates/hosting/bills.html:47 templates/hosting/orders.html.py:88
#: templates/hosting/virtual_machines.html:76
msgid "next" msgid "next"
msgstr "nächste" msgstr "nächste"
#: templates/hosting/confirm_reset_password.html:10 msgid "SSH Key"
#: templates/hosting/login.html:12 templates/hosting/reset_password.html:10 msgstr "SSH Key"
#: templates/hosting/signup.html:9 templates/hosting/signup_validate.html:9
msgid "Choose a key option in order to access your VM"
msgstr "Wähle eine Option um Zugriff auf deine VM zu erhalten"
msgid "Generating a new key pair"
msgstr "Neuen SSH-Key erstellen"
msgid "I want to generate a new key pair"
msgstr "Ich möchte einen neuen SSH-Key erstellen"
msgid "Generate"
msgstr "Generieren"
msgid "Using existing key"
msgstr "Nutzung eines existierenden SSH-Keys"
msgid "I want to use my existing public key"
msgstr "Ich möchte einen existierenden SSH-Key nutzen"
msgid "Upload"
msgstr "Hochladen"
msgid "Your VM hosted in Switzerland" msgid "Your VM hosted in Switzerland"
msgstr "deine VM in der Schweiz" msgstr "deine VM in der Schweiz"
#: templates/hosting/confirm_reset_password.html:14
msgid "Set your new password" msgid "Set your new password"
msgstr "Setze dein neues Passwort" msgstr "Setze dein neues Passwort"
#: templates/hosting/confirm_reset_password.html:29
#: templates/hosting/reset_password.html:23
msgid "Reset" msgid "Reset"
msgstr "Zurücksetzen" msgstr "Zurücksetzen"
#: templates/hosting/confirm_reset_password.html:35
#: templates/hosting/reset_password.html:29 templates/hosting/signup.html:27
msgid "Already have an account ?" msgid "Already have an account ?"
msgstr "Hast Du bereits ein Benutzerkonto?" msgstr "Hast Du bereits ein Benutzerkonto?"
#: templates/hosting/create_virtual_machine.html:20 msgid "Login"
msgstr "Anmelden"
msgid "New Virtual Machine" msgid "New Virtual Machine"
msgstr "Neue virtuelle Maschine" msgstr "Neue virtuelle Maschine"
#: templates/hosting/create_virtual_machine.html:28
msgid "Step 1. Select VM Template:" msgid "Step 1. Select VM Template:"
msgstr "Wähle eine Vorlage" msgstr "Wähle eine Vorlage"
#: templates/hosting/create_virtual_machine.html:42
msgid "Step2. Select VM Configuration" msgid "Step2. Select VM Configuration"
msgstr "Wähle eine Konfiguration" msgstr "Wähle eine Konfiguration"
#: templates/hosting/create_virtual_machine.html:59
msgid "Price " msgid "Price "
msgstr "Preis" msgstr "Preis"
#: templates/hosting/create_virtual_machine.html:59
msgid "CHF/Month" msgid "CHF/Month"
msgstr "CHF/Monat" msgstr "CHF/Monat"
#: templates/hosting/create_virtual_machine.html:61
msgid "Start VM" msgid "Start VM"
msgstr "VM jetzt starten" msgstr "VM jetzt starten"
#: templates/hosting/emails/password_reset_email.html:2
#: templates/hosting/emails/password_reset_email.txt:2
#, python-format #, python-format
msgid "" msgid ""
"You're receiving this email because you requested a password reset for your " "You're receiving this email because you requested a password reset for your "
"user account at %(site_name)s." "user account at %(site_name)s."
msgstr "" msgstr ""
#: templates/hosting/emails/password_reset_email.html:4
#: templates/hosting/emails/password_reset_email.txt:4
msgid "Please go to the following page and choose a new password:" msgid "Please go to the following page and choose a new password:"
msgstr "" msgstr ""
#: templates/hosting/emails/password_reset_email.html:9
#: templates/hosting/emails/password_reset_email.txt:9
msgid "Thanks for using our site!" msgid "Thanks for using our site!"
msgstr "" msgstr ""
#: templates/hosting/emails/password_reset_email.html:11
#: templates/hosting/emails/password_reset_email.txt:11
#, python-format #, python-format
msgid "The %(site_name)s team" msgid "The %(site_name)s team"
msgstr "" msgstr ""
#: templates/hosting/login.html:34
msgid "Don't have an account yet ? " msgid "Don't have an account yet ? "
msgstr "Besitzt du kein Benutzerkonto?" msgstr "Besitzt du kein Benutzerkonto?"
#: templates/hosting/login.html:37 templates/hosting/signup.html.py:13
#: templates/hosting/signup.html:21 views.py:219
msgid "Sign up" msgid "Sign up"
msgstr "Registrieren" msgstr "Registrieren"
#: templates/hosting/login.html:39
msgid "Forgot your password ? " msgid "Forgot your password ? "
msgstr "Passwort vergessen?" msgstr "Passwort vergessen?"
#: templates/hosting/notifications.html:9
msgid "Notifications" msgid "Notifications"
msgstr "Benachrichtigungen" msgstr "Benachrichtigungen"
#: templates/hosting/notifications.html:16
msgid "Unread" msgid "Unread"
msgstr "Ungelesen" msgstr "Ungelesen"
#: templates/hosting/notifications.html:26
msgid "All" msgid "All"
msgstr "Alle" msgstr "Alle"
#: templates/hosting/notifications.html:38
msgid "Unread notifications" msgid "Unread notifications"
msgstr "Ungelesene Benachrichtigungen" msgstr "Ungelesene Benachrichtigungen"
#: templates/hosting/notifications.html:48
msgid "Mark as read" msgid "Mark as read"
msgstr "Als gelesen markieren" msgstr "Als gelesen markieren"
#: templates/hosting/notifications.html:59
msgid "All notifications" msgid "All notifications"
msgstr "Alle Benachrichtigungen" msgstr "Alle Benachrichtigungen"
#: templates/hosting/order_detail.html:23
msgid "Confirm Order" msgid "Confirm Order"
msgstr "Bestellung Bestätigen" msgstr "Bestellung Bestätigen"
#: templates/hosting/order_detail.html:29
msgid "Billed To:"
msgstr "Rechnungsadresse"
#: templates/hosting/order_detail.html:37 templates/hosting/orders.html:17
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
#: templates/hosting/order_detail.html:39
msgid "Status:" msgid "Status:"
msgstr "" msgstr ""
#: templates/hosting/order_detail.html:51 msgid "Billed To:"
msgstr "Rechnungsadresse"
msgid "Payment Method:" msgid "Payment Method:"
msgstr "Bezahlmethode" msgstr "Bezahlmethode"
#: templates/hosting/order_detail.html:62
msgid "Order summary" msgid "Order summary"
msgstr "Bestellungsübersicht" msgstr "Bestellungsübersicht"
#: templates/hosting/order_detail.html:65 templates/hosting/payment.html:13
#: templates/hosting/virtual_machine_detail.html:76
msgid "Cores" msgid "Cores"
msgstr "Prozessorkerne" msgstr "Prozessorkerne"
#: templates/hosting/order_detail.html:67 templates/hosting/payment.html:16
#: templates/hosting/virtual_machine_detail.html:82
msgid "Memory" msgid "Memory"
msgstr "Arbeitsspeicher" msgstr "Arbeitsspeicher"
#: templates/hosting/order_detail.html:69 templates/hosting/payment.html:19
msgid "Disk space" msgid "Disk space"
msgstr "Festplattenkapazität" msgstr "Festplattenkapazität"
#: templates/hosting/order_detail.html:71 templates/hosting/payment.html:41
msgid "Total" msgid "Total"
msgstr "Gesamt" msgstr "Gesamt"
#: templates/hosting/order_detail.html:77
msgid "Finish Configuration" msgid "Finish Configuration"
msgstr "Konfiguration beenden" msgstr "Konfiguration beenden"
#: templates/hosting/orders.html:18
msgid "Amount" msgid "Amount"
msgstr "Betrag" msgstr "Betrag"
#: templates/hosting/orders.html:19 templates/hosting/user_keys.html.py:27
#: templates/hosting/virtual_machine_detail.html:30
#: templates/hosting/virtual_machines.html:31
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: templates/hosting/orders.html:30
msgid "Approved" msgid "Approved"
msgstr "Akzeptiert" msgstr "Akzeptiert"
#: templates/hosting/orders.html:32
msgid "Declined" msgid "Declined"
msgstr "Abgelehnt" msgstr "Abgelehnt"
#: templates/hosting/orders.html:37 templates/hosting/virtual_machines.html:58
msgid "View Detail" msgid "View Detail"
msgstr "Details anzeigen" msgstr "Details anzeigen"
#: templates/hosting/orders.html:40
msgid "Cancel Order" msgid "Cancel Order"
msgstr "Bestellung stornieren" msgstr "Bestellung stornieren"
#: templates/hosting/orders.html:55 #, fuzzy
msgid "Do You want to delete your order?" #| msgid "Do You want to delete your order?"
msgid "Do you want to delete your order?"
msgstr "Willst du deine Bestellung löschen?" msgstr "Willst du deine Bestellung löschen?"
#: templates/hosting/orders.html:63 templates/hosting/user_keys.html.py:63
msgid "Close"
msgstr "Schliessen"
#: templates/hosting/orders.html:65 templates/hosting/user_keys.html.py:65
msgid "Delete" msgid "Delete"
msgstr "Löschen" msgstr "Löschen"
#: templates/hosting/payment.html:10
msgid "Your Order" msgid "Your Order"
msgstr "Deine Bestellung" msgstr "Deine Bestellung"
#: templates/hosting/payment.html:22
#: templates/hosting/virtual_machine_detail.html:98
msgid "Configuration" msgid "Configuration"
msgstr "Konfiguration" msgstr "Konfiguration"
#: templates/hosting/payment.html:41
msgid "including VAT" msgid "including VAT"
msgstr "inkl. Mehrwertsteuer" msgstr "inkl. Mehrwertsteuer"
#: templates/hosting/payment.html:55
msgid "Billing Address" msgid "Billing Address"
msgstr "Rechnungsadresse" msgstr "Rechnungsadresse"
#: templates/hosting/payment.html:66
msgid "Credit Card" msgid "Credit Card"
msgstr "Kreditkarte" msgstr "Kreditkarte"
#: templates/hosting/payment.html:71
msgid "" msgid ""
"\n" "\n"
" Please fill in your credit card information " " Please fill in your credit card information "
@ -385,7 +297,6 @@ msgstr ""
"\"https://stripe.com\" target=\"_blank\">Stripe</a> für die Bezahlung und " "\"https://stripe.com\" target=\"_blank\">Stripe</a> für die Bezahlung und "
"speichern keine Informationen in unserer Datenbank." "speichern keine Informationen in unserer Datenbank."
#: templates/hosting/payment.html:90
msgid "" msgid ""
"\n" "\n"
" You are not making any payment yet. " " You are not making any payment yet. "
@ -399,27 +310,21 @@ msgstr ""
"Kreditkateninformationen wirst du auf die Bestellbestätigungsseite " "Kreditkateninformationen wirst du auf die Bestellbestätigungsseite "
"weitergeleitet." "weitergeleitet."
#: templates/hosting/payment.html:101 templates/hosting/payment.html.py:143
msgid "Submit" msgid "Submit"
msgstr "Absenden" msgstr "Absenden"
#: templates/hosting/payment.html:113
msgid "Card Number" msgid "Card Number"
msgstr "Kreditkartennummer" msgstr "Kreditkartennummer"
#: templates/hosting/payment.html:117
msgid "Expiry Date" msgid "Expiry Date"
msgstr "Ablaufdatum" msgstr "Ablaufdatum"
#: templates/hosting/payment.html:122
msgid "CVC" msgid "CVC"
msgstr "" msgstr ""
#: templates/hosting/payment.html:126
msgid "Card Type" msgid "Card Type"
msgstr "Kartentyp" msgstr "Kartentyp"
#: templates/hosting/payment.html:135
msgid "" msgid ""
"\n" "\n"
" You are not making any payment " " You are not making any payment "
@ -433,125 +338,115 @@ msgstr ""
"Kreditkateninformationen wirst du auf die Bestellbestätigungsseite " "Kreditkateninformationen wirst du auf die Bestellbestätigungsseite "
"weitergeleitet." "weitergeleitet."
#: templates/hosting/payment.html:178
msgid "Processing" msgid "Processing"
msgstr "Weiter" msgstr "Weiter"
#: templates/hosting/payment.html:179
msgid "Enter your credit card number" msgid "Enter your credit card number"
msgstr "Deine Kreditkartennummer" msgstr "Deine Kreditkartennummer"
#: templates/hosting/reset_password.html:15
msgid "Reset your password" msgid "Reset your password"
msgstr "Passwort zurücksetzen" msgstr "Passwort zurücksetzen"
#: templates/hosting/user_key.html:11 templates/hosting/user_keys.html.py:9 msgid "Add your public SSH key"
msgid "Access Key" msgstr "Füge deinen öffentlichen SSH-Key hinzu"
msgstr "Zugriffsschlüssel"
#: templates/hosting/user_key.html:24 msgid "Use your created key to access to the VM"
msgid "Upload your own key. " msgstr "Benutze deinen erstellten SSH-Key um auf deine VM zugreifen zu können"
msgstr "Lade deinen Key hoch"
#: templates/hosting/user_key.html:28 msgid "Add SSH Key"
msgid "Or generate a new key pair." msgstr "Hinzufügen"
msgstr "Oder erstelle dein neues Keypaar"
#: templates/hosting/user_key.html:30 msgid "Or you can generate a new key pair"
msgid "Generate Key Pair" msgstr "Erstelle dein neues Keypaar"
msgstr "Schlüsselpaar generieren"
#: templates/hosting/user_key.html:40
msgid "Warning!" msgid "Warning!"
msgstr "Achtung!" msgstr "Achtung!"
#: templates/hosting/user_key.html:40 #, fuzzy
msgid "You can download your SSH private key once. Don't lost your key" #| msgid "You can download your SSH private key once. Don't lost your key"
msgid "You can download your SSH private key once. Don't loose your key"
msgstr "" msgstr ""
"Du kannst deinen privaten SSH Schlüssel nur einmal herunterladen. Beware ihn " "Du kannst deinen privaten SSH Schlüssel nur einmal herunterladen. Beware ihn "
"sicher auf." "sicher auf."
#: templates/hosting/user_keys.html:18 msgid "Your SSH Keys"
msgid "Add Key" msgstr "Deine SSH Keys"
msgstr "Schlüssel hinzufügen"
#: templates/hosting/user_keys.html:26 msgid ""
msgid "Created at" "To generate a new key pair or to upload your existing key, click 'Add Key'"
msgstr "Erstellt am" msgstr ""
"Um einen neuen SSH-Key zu erstellen oder um einen vorhandenen SSH-Key "
"hinzuzufügen, klicke auf 'Hinzufügen'"
#: templates/hosting/user_keys.html:43
msgid "Delete Key" msgid "Delete Key"
msgstr "Löschen" msgstr "Löschen"
#: templates/hosting/user_keys.html:56 msgid "Public Key"
msgstr ""
msgid "Private Key"
msgstr ""
msgid "Do You want to delete this key?" msgid "Do You want to delete this key?"
msgstr "Möchtest Du den Schlüssel löschen?" msgstr "Möchtest Du den Schlüssel löschen?"
#: templates/hosting/virtual_machine_detail.html:19 msgid "Close"
msgstr "Schliessen"
msgid "Show"
msgstr "Anzeigen"
msgid "Public ssh key"
msgstr ""
msgid "Download"
msgstr ""
msgid "Settings" msgid "Settings"
msgstr "Einstellungen" msgstr "Einstellungen"
#: templates/hosting/virtual_machine_detail.html:25
msgid "Billing" msgid "Billing"
msgstr "Abrechnungen" msgstr "Abrechnungen"
#: templates/hosting/virtual_machine_detail.html:60
msgid "Ip not assigned yet" msgid "Ip not assigned yet"
msgstr "Ip nicht zugewiesen" msgstr "Ip nicht zugewiesen"
#: templates/hosting/virtual_machine_detail.html:89
msgid "Disk" msgid "Disk"
msgstr "Festplatte" msgstr "Festplatte"
#: templates/hosting/virtual_machine_detail.html:108
msgid "Current pricing" msgid "Current pricing"
msgstr "Aktueller Preis" msgstr "Aktueller Preis"
#: templates/hosting/virtual_machine_detail.html:117
msgid "Current status" msgid "Current status"
msgstr "Aktueller Status" msgstr "Aktueller Status"
#: templates/hosting/virtual_machine_detail.html:142
msgid "Terminate Virtual Machine" msgid "Terminate Virtual Machine"
msgstr "Virtuelle Maschine beenden" msgstr "Virtuelle Maschine beenden"
#: templates/hosting/virtual_machine_detail.html:163
msgid "Terminate your Virtual Machine" msgid "Terminate your Virtual Machine"
msgstr "Ihre virtuelle Maschine beenden" msgstr "Ihre virtuelle Maschine beenden"
#: templates/hosting/virtual_machine_detail.html:166
msgid "Are you sure do you want to cancel your Virtual Machine " msgid "Are you sure do you want to cancel your Virtual Machine "
msgstr "Sind Sie sicher, dass Sie ihre virtuelle Maschine beenden wollen " msgstr "Sind Sie sicher, dass Sie ihre virtuelle Maschine beenden wollen "
#: templates/hosting/virtual_machine_detail.html:169
msgid "Cancel"
msgstr "Beenden"
#: templates/hosting/virtual_machines.html:9
msgid "Virtual Machines" msgid "Virtual Machines"
msgstr "Virtuelle Maschinen" msgstr "Virtuelle Maschinen"
#: templates/hosting/virtual_machines.html:22
msgid "Create VM" msgid "Create VM"
msgstr "Neue VM" msgstr "Neue VM"
#: templates/hosting/virtual_machines.html:28
msgid "ID" msgid "ID"
msgstr "" msgstr ""
#: templates/hosting/virtual_machines.html:29
msgid "Ipv4" msgid "Ipv4"
msgstr "IPv4" msgstr "IPv4"
#: templates/hosting/virtual_machines.html:30
msgid "Ipv6" msgid "Ipv6"
msgstr "IPv6" msgstr "IPv6"
#: views.py:207 views.py:229
msgid "login" msgid "login"
msgstr "einloggen" msgstr "einloggen"
#: views.py:212
msgid "" msgid ""
"Thank you for signing up. We have sent an email to you. Please follow the " "Thank you for signing up. We have sent an email to you. Please follow the "
"instructions in it to activate your account. Once activated, you can login " "instructions in it to activate your account. Once activated, you can login "
@ -561,32 +456,135 @@ msgstr ""
"den Anweisungen um deinen Account zu aktivieren. Danach kannst du dich über " "den Anweisungen um deinen Account zu aktivieren. Danach kannst du dich über "
"diesen" "diesen"
#: views.py:214 views.py:240
msgid "Go back to" msgid "Go back to"
msgstr "Zurück" msgstr "Zurück"
#: views.py:230
msgid "Account activation" msgid "Account activation"
msgstr "Accountaktivierung" msgstr "Accountaktivierung"
#: views.py:233
msgid "Your account has been activated." msgid "Your account has been activated."
msgstr "Dein Account wurde aktiviert." msgstr "Dein Account wurde aktiviert."
#: views.py:234
msgid "You can now" msgid "You can now"
msgstr "Du kannst dich nun" msgstr "Du kannst dich nun"
#: views.py:239
msgid "Sorry. Your request is invalid." msgid "Sorry. Your request is invalid."
msgstr "Entschuldigung, deine Anfrage ist ungültig." msgstr "Entschuldigung, deine Anfrage ist ungültig."
#: views.py:757
msgid "" msgid ""
"We could not find the requested VM. Please " "We could not find the requested VM. Please "
"contact Data Center Light Support." "contact Data Center Light Support."
msgstr "" msgstr ""
#~ msgid "Cancel"
#~ msgstr "Beenden"
#~ msgid "Add SSH key"
#~ msgstr "Hinzufügen"
#~ msgid "Keys"
#~ msgstr "Schlüssel"
#, fuzzy
#~| msgid "Contact"
#~ msgid "Content"
#~ msgstr "Kontakt"
#, fuzzy
#~| msgid "Contact"
#~ msgid "DG.Contact"
#~ msgstr "Kontakt"
#, fuzzy
#~| msgid "Home"
#~ msgid "DG.Home"
#~ msgstr "Home"
#, fuzzy
#~| msgid "Amount"
#~ msgid "Country"
#~ msgstr "Betrag"
#~ msgid "Log in"
#~ msgstr "Anmelden"
#, fuzzy
#~| msgid "Configuration"
#~ msgid "Donation #"
#~ msgstr "Konfiguration"
#, fuzzy
#~| msgid "Billing Address"
#~ msgid "Billing Address:"
#~ msgstr "Rechnungsadresse"
#, fuzzy
#~| msgid "Date"
#~ msgid "Date:"
#~ msgstr "Datum"
#, fuzzy
#~| msgid "Configuration"
#~ msgid "Donation"
#~ msgstr "Konfiguration"
#, fuzzy
#~| msgid "View Detail"
#~ msgid "View Donations"
#~ msgstr "Details anzeigen"
#~ msgid "You haven been logged out"
#~ msgstr "Sie wurden abgmeldet"
#, fuzzy
#~| msgid "Log in"
#~ msgid "Log in "
#~ msgstr "Anmelden"
#, fuzzy
#~| msgid "View Detail"
#~ msgid "DG.Detail"
#~ msgstr "Details anzeigen"
#, fuzzy
#~| msgid "Cancel"
#~ msgid "France"
#~ msgstr "Beenden"
#, fuzzy
#~| msgid "Enter your credit card number"
#~ msgid "Enter your name or company name"
#~ msgstr "Deine Kreditkartennummer"
#, fuzzy
#~| msgid "Card Number"
#~ msgid "Cardholder Name"
#~ msgstr "Kreditkartennummer"
#~ msgid "How it works"
#~ msgstr "So funktioniert es"
#~ msgid "Your infrastructure"
#~ msgstr "deine Infrastruktur"
#~ msgid "Our inftrastructure"
#~ msgstr "Unsere Infrastruktur"
#~ msgid "Pricing"
#~ msgstr "Preise"
#~ msgid "Access Key"
#~ msgstr "Zugriffsschlüssel"
#~ msgid "Upload your own key. "
#~ msgstr "Lade deinen Key hoch"
#~ msgid "Generate Key Pair"
#~ msgstr "Schlüsselpaar generieren"
#~ msgid "Created at"
#~ msgstr "Erstellt am"
#~ msgid "Billing Amount" #~ msgid "Billing Amount"
#~ msgstr "Rechnungsbetrag" #~ msgstr "Rechnungsbetrag"
@ -610,25 +608,6 @@ msgstr ""
#~ msgid "EXPIRATION DATE" #~ msgid "EXPIRATION DATE"
#~ msgstr "Ablaufdatum" #~ msgstr "Ablaufdatum"
#~ msgid "Home"
#~ msgstr "Home"
#~ msgid "Log in"
#~ msgstr "Anmelden"
#~ msgid "You haven been logged out"
#~ msgstr "Sie wurden abgmeldet"
#~ msgid "Upload Key"
#~ msgstr "Schlüssel hochladen"
#~ msgid ""
#~ "Use your created key to access to the machine. If you lost it, contact us."
#~ msgstr ""
#~ "Verwende deinen privaten SSH Schlüssel, um dich mit deinen Maschinen zu "
#~ "verbinden. Solltest du deinen privaten Schlüssel verloren haben, dann "
#~ "kontaktiere uns."
#~ msgid "Copy to Clipboard" #~ msgid "Copy to Clipboard"
#~ msgstr "Kopieren" #~ msgstr "Kopieren"
@ -638,6 +617,3 @@ msgstr ""
#~ msgstr "" #~ msgstr ""
#~ "Dein privater SSH Schlüssel wurde bereits generiert und heruntergeladen. " #~ "Dein privater SSH Schlüssel wurde bereits generiert und heruntergeladen. "
#~ "Falls du ihn verloren hast, kontaktiere uns." #~ "Falls du ihn verloren hast, kontaktiere uns."
#~ msgid "Generate my key"
#~ msgstr "Generiere meinen Schlüssel"

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2017-07-06 09:06
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hosting', '0040_hostingplan'),
]
operations = [
migrations.AddField(
model_name='userhostingkey',
name='private_key',
field=models.FileField(blank=True, upload_to='private_keys'),
),
]

View file

@ -101,6 +101,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
class UserHostingKey(models.Model): class UserHostingKey(models.Model):
user = models.ForeignKey(CustomUser) user = models.ForeignKey(CustomUser)
public_key = models.TextField() public_key = models.TextField()
private_key = models.FileField(upload_to='private_keys', blank=True)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)

View file

@ -58,6 +58,9 @@
width: 90%; width: 90%;
} }
} }
.btn:focus, .btn:active:focus {
outline: 0;
}
/***********Styles for Model********************/ /***********Styles for Model********************/
.modal-content { .modal-content {
@ -70,7 +73,7 @@
} }
.modal-header { .modal-header {
min-height: 25px; min-height: 30px;
} }
.modal-header .close { .modal-header .close {
@ -79,8 +82,12 @@
margin-top: 0; margin-top: 0;
position: absolute; position: absolute;
top: 0; top: 0;
right: 15px; right: 11px;
z-index: 10; z-index: 10;
line-height: 60px;
}
.modal-header .close span {
display: block;
} }
.modal-header .close:focus { .modal-header .close:focus {
@ -95,8 +102,8 @@
.modal-body { .modal-body {
text-align: center; text-align: center;
width: 100%; width: 100%;
float: left; float: left;
padding: 0px 30px 15px 30px; padding: 0px 40px 15px 30px;
} }
.modal-body .modal-icon i { .modal-body .modal-icon i {
font-size: 80px; font-size: 80px;
@ -142,7 +149,7 @@
@media (max-width: 767px) { @media (max-width: 767px) {
.modal-dialog { .modal-dialog {
/* top: 30%; */ /* top: 30%; */
width: 90%; width: 95%;
margin: 0 auto !important; margin: 0 auto !important;
} }
} }

View file

@ -0,0 +1,325 @@
/* ssh_keys_choice */
.h1-thin {
font-family: Lato, sans-serif;
font-weight: 300;
font-size: 32px;
}
.dashboard-container .page-header {
border: 0;
margin-top: 0;
}
.dashboard-choice-container .page-header p {
font-size: 16px;
font-family: Lato, sans-serif;
font-weight: 300;
}
.dashboard-choice-container h2 {
font-family: Lato, sans-serif;
font-weight: 400;
font-size: 22px;
margin-top: 0;
}
.choice-container {
border: 1px solid #C9C6C6;
padding: 25px;
border-radius: 1px;
}
.choice-container p{
font-size: 18px;
font-family: Lato, sans-serif;
font-weight: 300;
}
.choice-container-top {
border-bottom: 1px solid #C9C6C6;
padding-bottom: 25px;
margin-bottom: 25px;
}
.choice-container .choice-btn {
margin-top: 25px;
}
.choice-btn {
min-width: 110px;
background-color: #3C5480;
color: #fff;
border: 2px solid #3C5480;
padding: 4px 10px;
transition: 0.3s all ease-out;
}
.choice-btn:focus,
.choice-btn:hover,
.choice-btn:active {
color: #3C5480;
background-color: #fff;
}
.choice-btn-faded {
background-color: #8396C4;
border: 2px solid #8396C4;
}
@media (max-width: 767px) {
.h1-thin {
font-size: 27px;
}
.dashboard-choice-container h2 {
font-size: 20px;
}
.choice-container p {
font-size: 16px;
}
.choice-btn{
margin-top: 15px;
}
}
@media (max-width: 420px) {
.ssh-keys-table {table-layout: fixed;}
}
.ssh-keys-table thead tr th,
.ssh-keys-table tbody tr td{
color: #717274;
text-align: center;
border-bottom: 1px solid #cbcbcb;
vertical-align: middle;
}
.ssh-keys-table tbody tr{
border-bottom: 1px solid #cbcbcb;
}
.ssh-keys-table thead tr th:first-of-type,
.ssh-keys-table tbody tr td:first-of-type{
text-align: left;
}
.ssh-keys-table thead tr th:last-of-type,
.ssh-keys-table tbody tr td:last-of-type{
width: 20%;
}
.ssh-key-header {
color: #717274;
font-size: 16px;
font-weight: 300;
text-align: justify;
}
.ssh-header-container{
padding-top: 15px;
}
@media (min-width: 768px) {
.ssh-header-container {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.ssh-header-container p{
margin-bottom: 0;
}
}
.ssh-header-container p{
padding: 0;
color: #717274;
font-size: 16px;
font-weight: 300;
font-family: 'Lato';
}
.borderless tbody:before {
display: none !important;
}
.btn-custom-download{
background-color: #337ab7;
margin-top: auto;
margin-bottom: auto;
/* font-weight: 700; */
vertical-align: middle;
margin-right: 25px;
}
.btn-custom-delete{
width: 100px;
background-color: #f1f0f0;
}
.btn-custom-delete a, .btn-custom-download a{
text-decoration: none;
}
.modal-body p{
width: 100%;
word-wrap: break-word;
text-align: left;
}
@media screen and (max-width: 768px) {
.ssh-header-container{
flex-direction: column-reverse;
align-items: flex-start;
}
.btn-custom-delete{
width: auto;
}
.dashboard-container {
width: 100% !important;
}
.row {
/* margin-right: 0; */
/* margin-left: 0; */
}
.col-md-12, .col-sm-12{
padding-left: 5px;
padding-right: 5px;
}
}
@media (max-width: 360px){
.content-dashboard {
/* width: 100% !important; */
}
.container {
padding-right: 5px;
padding-left: 5px;
}
}
.dashboard-choice-container {
max-width: 834px !important;
}
.form_public_key{
resize: none;
}
@media (min-width: 768px) {
.form_key_name{
width:60%;
min-width: 215px;
}
}
.form_public_key,
.form_key_name{
position: relative;
border:none;
border-bottom: 1px solid grey;
box-shadow: none;
border-radius: 0;
font-family: 'Lato-Light', sans-serif;
font-size: 20px;
padding-left: 0;
}
.form_key_name::-webkit-input-placeholder{
font-size: 20px;
font-weight:100;
font-family: 'Lato-Light', sans-serif;
}
.form_key_name::-moz-input-placeholder{
font-size: 20px;
font-weight:200;
font-family: 'Lato-Light', sans-serif;
}
.form_key_name:-moz-input-placeholder{
font-family: 'Lato-Light', sans-serif;
font-size: 20px;
font-weight:200;
}
.form_key_name:-ms-input-placeholder {
font-size: 20px;
font-family: 'Lato-Light', sans-serif;
font-weight:200;
}
.form_public_key::-webkit-input-placeholder{
position: relative;
top: 110px;
font-size: 20px;
font-weight: 200;
font-family: 'Lato-Light', sans-serif;
}
.form_public_key::-moz-input-placeholder{
position: relative;
top: 110px;
font-size: 20px;
font-family: 'Lato-Light', sans-serif;
font-weight:200;
}
.form_public_key:-moz-input-placeholder{
position: relative;
top: 110px;
font-size: 20px;
font-weight:200;
font-family: 'Lato-Light', sans-serif;
}
.form_public_key:-ms-input-placeholder {
position: relative;
top: 110px;
font-size: 20px;
font-weight:200;
font-family: 'Lato-Light', sans-serif;
}
.underform-contaner{
margin-bottom: 20px;
}
@media (min-width: 767px) {
.underform-contaner {
display: flex;
vertical-align: middle;
align-items: center;
justify-content: space-between;
flex-direction: row;
}
}
@media (max-width: 767px) {
.underform-contaner .btn-container {
text-align: right;
}
}
.underform-contaner h4{
font-family: 'Lato-Light', sans-serif;
}
.underform-contaner button{
/* font-family: Lato; */
/* font-weight: 600; */
min-width: 120px;
height: 35px;
margin-top: 0;
}
.underform-contaner .btn-default{
background-color: #ccc;
color: #fff;
}
.control-label{
font-family: 'Lato-Light', sans-serif;
font-size: 20px;
font-weight:200;
}
.form-ssh h3{
margin-bottom: 40px;
}
.custom_form_button{
border-radius: 0;
}
.form_key_name:focus,
.form_public_key:focus,
.has-error .form_key_name,
.has-error .form_key_name:focus,
.has-error .form_public_key,
.has-error .form_public_key:focus,
.has-success .form_key_name,
.has-success .form_key_name:focus,
.has-success .form_public_key,
.has-success .form_public_key:focus {
box-shadow: none;
}
.wide440 {
max-width: 440px;
margin: auto;
}
.mob-only {
display: none;
}
@media (max-width: 767px) {
.mob-only {
display: initial;
}
.pc-only {
display: none;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

View file

@ -18,6 +18,7 @@
<!-- Custom CSS --> <!-- Custom CSS -->
<link href="{% static 'hosting/css/landing-page.css' %}" rel="stylesheet"> <link href="{% static 'hosting/css/landing-page.css' %}" rel="stylesheet">
<link href="{% static 'hosting/css/user_keys.css' %}" rel="stylesheet">
<link href="{% static 'hosting/css/payment.css' %}" rel="stylesheet"> <link href="{% static 'hosting/css/payment.css' %}" rel="stylesheet">
<link href="{% static 'hosting/css/order.css' %}" rel="stylesheet"> <link href="{% static 'hosting/css/order.css' %}" rel="stylesheet">
<link href="{% static 'hosting/css/orders.css' %}" rel="stylesheet"> <link href="{% static 'hosting/css/orders.css' %}" rel="stylesheet">
@ -27,7 +28,7 @@
<!-- Custom Fonts --> <!-- Custom Fonts -->
<link href='//fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'> <link href='//fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link href="//fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css"> <link href="//fonts.googleapis.com/css?family=Lato:300,400,500,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="{% static 'hosting/css/owl.carousel.min.css' %}"> <link rel="stylesheet" href="{% static 'hosting/css/owl.carousel.min.css' %}">
<link rel="stylesheet" href="{% static 'hosting/css/owl.theme.default.min.css' %}"> <link rel="stylesheet" href="{% static 'hosting/css/owl.theme.default.min.css' %}">
@ -84,7 +85,7 @@
<ul id="g-account-menu" class="dropdown-menu" role="menu"> <ul id="g-account-menu" class="dropdown-menu" role="menu">
<li> <li>
<a href="{% url 'hosting:ssh_keys' %}"> <a href="{% url 'hosting:ssh_keys' %}">
<i class="fa fa-key"></i> {% trans "Keys"%} <i class="fa fa-key"></i> {% trans "SSH Keys" %}
</a> </a>
</li> </li>
<li> <li>

View file

@ -0,0 +1,66 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3 i18n %}
{% block content %}
<div>
<div class="container virtual-machine-container dashboard-container dashboard-choice-container">
<div class="wide440">
<div class="page-header">
<h1 class="h1-thin"><i class="fa fa-key" aria-hidden="true"></i>&nbsp;{% trans "SSH Key"%}</h1>
<p>{% trans "Choose a key option in order to access your VM" %}.</p>
</div>
{% if messages %}
<div class="alert alert-warning">
{% for message in messages %}
<span>{{ message }}</span>
{% endfor %}
</div>
{% endif %}
<div class="choice-container">
<div class="choice-container-top">
<h2>{% trans "Generating a new key pair" %}</h2>
<p>{% trans "I want to generate a new key pair" %}.</p>
<form class="text-right" action="" method="post">
{% csrf_token %}
<button type="submit" class="btn choice-btn choice-btn-faded">
{% trans "Generate" %}
</button>
</form>
</div>
<div>
<h2>{% trans "Using existing key" %}</h2>
<p>{% trans "I want to use my existing public key"%}.</p>
<form class="text-right" action="{% url 'hosting:create_ssh_key' %}">
<button type="submit" class="btn choice-btn">
{% trans "Upload" %}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
{% if next_url %}
<script type="text/javascript">
window.location.href = '{{next_url}}';
</script>
{% endif %}
<script type="text/javascript">
window.onload = function () {
{% for user_key in keys %}
var locale_date = moment.utc(document.getElementById("ssh-created_at-{{user_key.id}}").textContent,'YYYY-MM-DD HH:mm').toDate();
locale_date = moment(locale_date).format("YYYY-MM-DD h:mm:ss a");
document.getElementById('ssh-created_at-{{user_key.id}}').innerHTML = locale_date;
{% endfor %}
};
</script>
{%endblock%}

View file

@ -2,52 +2,53 @@
{% load staticfiles bootstrap3 i18n %} {% load staticfiles bootstrap3 i18n %}
{% block content %} {% block content %}
<div> <div>
<div class="virtual-machine-container dashboard-container "> <div class="virtual-machine-container dashboard-container">
<div class="row"> <div class="row">
<div class="container-table col-md-9 col-md-offset-2"> <div class="col-md-9 col-md-offset-2">
<div class="col-sm-12"> <form method="POST" action="" novalidate class="form-ssh">
<form method="POST" action="" novalidate class="form-ssh"> {% csrf_token %}
{% csrf_token %} <div class="page-header">
<h3><i class="fa fa-key fa-separate" aria-hidden="true"></i>{% trans "Access Key"%} </h3> <h1 class="h1-thin"><i class="fa fa-key" aria-hidden="true"></i>&nbsp;{% trans "Add your public SSH key" %}</h1>
{% if messages %} </div>
{% if messages %}
<div class="alert alert-warning"> <div class="alert alert-warning">
{% for message in messages %} {% for message in messages %}
<span>{{ message }}</span> <span>{{ message }}</span>
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}
{% for field in form %} {% for field in form %}
{% bootstrap_field field %} {% bootstrap_field field %}
{% endfor %} {% endfor %}
{% buttons %} {% buttons %}
<button type="submit" class="btn btn-success"> <div class="underform-contaner">
{% trans "Upload your own key. "%} <h4>{% trans "Use your created key to access to the VM" %}.</h4>
<div class="btn-container">
<button type="submit" name="add_ssh" class="btn choice-btn choice-btn-faded">
{% trans "Add SSH Key" %}
</button> </button>
<br /> </div>
<br /> </div>
{% trans "Or generate a new key pair."%} <br /> <div class="underform-contaner">
<br /> <h4>{% trans "Or you can generate a new key pair"%}.</h4>
<button class="btn btn-success">{% trans "Generate Key Pair"%} </a> <div class="btn-container">
<button type="submit" name="generate" class="btn choice-btn">
{% trans "Generate" %}
</button> </button>
</div>
</div>
{% endbuttons %}
</form>
{% endbuttons %} {% if private_key %}
</form> <div class="alert alert-warning">
<h5> Use your created key to access to the machine. If you lost it, contact us. </h5> <strong>{% trans "Warning!"%}</strong>{% trans "You can download your SSH private key once. Don't loose your key" %}
</div>
{% if private_key %} <div class="form-group">
<div class="alert alert-warning"> <textarea class="form-control" rows="6" id="ssh_key" type="hidden" style="display:none">{{private_key}}</textarea>
</div>
<strong>{% trans "Warning!"%}</strong>{% trans "You can download your SSH private key once. Don't lost your key"%} {% endif %}
</div>
<div class="form-group">
<textarea class="form-control" rows="6" id="ssh_key" type="hidden" style="display:none">{{private_key}}</textarea>
</div>
{% endif %}
<div class="clearfix"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -3,85 +3,109 @@
{% block content %} {% block content %}
<div> <div>
<div class="container virtual-machine-container dashboard-container "> <div class="container virtual-machine-container dashboard-container ">
<div class="row"> <h1 class="h1-thin"><i class="fa fa-key" aria-hidden="true"></i>&nbsp;{% trans "Your SSH Keys" %}</h1>
<div class="col-md-9 col-md-offset-2"> {% if messages %}
<div class="col-sm-12"> <div class="alert alert-warning">
<h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3> {% for message in messages %}
{% if messages %} <span>{{ message }}</span>
<div class="alert alert-warning"> {% endfor %}
{% for message in messages %}
<span>{{ message }}</span>
{% endfor %}
</div>
{% endif %}
<p class="pull-right">
<a class="btn btn-success" href="{% url 'hosting:create_ssh_key' %}" >{% trans "Add Key"%} </a>
</p>
<h5> Use your created key to access to the machine. If you lost it, contact us. </h5>
<table class="table borderless table-hover">
<br/>
<thead>
<tr>
<th>{% trans "Name"%}</th>
<th>{% trans "Created at"%} </th>
<th>{% trans "Status"%} </th>
<th></th>
</tr>
</thead>
<tbody>
{% for user_key in keys %}
<tr>
<td scope="row">{{user_key.name}}</td>
<td><span id="ssh-created_at-{{user_key.id}}">{{user_key.created_at|date:'Y-m-d H:i' }}</span></td>
<td>
<span class="h3 label label-success"><strong>Active</strong></span>
</td>
<td>
<button type="button" class="btn btn-default" data-toggle="modal"
data-target="#Modal{{ user_key.id }}"><a
href="#">{% trans "Delete Key"%}</a>
</button>
<div class="modal fade" id="Modal{{user_key.id }}" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Confirm"><span
aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="modal-icon"><i class="fa fa-trash" aria-hidden="true"></i></div>
<h4 class="modal-title" id="ModalLabel">{% trans "Delete SSH Key"%}</h4>
<p class="modal-text">{% trans "Do You want to delete this key?"%}</p>
<form method="post" action="{% url 'hosting:delete_ssh_key' user_key.id %}">
{% csrf_token %}
<div class="modal-footer">
<button type="submit" class="btn btn-danger">{% trans "Delete"%}
</button>
</div>
</form>
</div>
</div>
</div> </div>
</div> {% endif %}
</td> <div class="ssh-header-container">
</tr> <p>{% trans "To generate a new key pair or to upload your existing key, click 'Add Key'" %}</p>
{% endfor %} <a class="btn choice-btn" href="{% url 'hosting:choice_ssh_keys' %}" >
</tbody> <span class="fa fa-plus"></span>&nbsp;&nbsp;{% trans "Add SSH Key" %}
</table> </a>
</div>
<table class="table borderless table-hover ssh-keys-table">
<br/>
<thead>
<tr>
<th>{% trans "Name" %}</th>
<th>{% trans "Delete Key" %}</th>
<th>{% trans "Public Key" %}</th>
<th>{% trans "Private Key" %}</th>
</tr>
</thead>
<tbody>
{% for user_key in keys %}
<tr>
<td scope="row">{{user_key.name}}</td>
<td>
<button type="button" class="btn btn-default btn-custom-delete" data-toggle="modal"
data-target="#Modal{{ user_key.id }}" style="color: #717274">
<span class="pc-only">{% trans "Delete" %}</span>
<span class="mob-only"><i class="fa fa-trash"></i></span>
</button>
<div class="modal fade" id="Modal{{user_key.id }}" tabindex="-1" role="dialog">
<div class="clearfix"></div> <div class="modal-dialog" role="document">
</div> <div class="modal-content">
</div> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
</div> aria-label="Confirm"><span
aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h4 class="modal-title" id="ModalLabel">{% trans "Do You want to delete this key?" %}</h4>
<form method="post" action="{% url 'hosting:delete_ssh_key' user_key.id %}">
{% csrf_token %}
<div class="modal-footer">
<button type="submit" class="btn btn-primary">{% trans "Delete" %}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</td>
<td>
<p type="button" data-toggle="modal" style="margin: 0" data-target="#Modal_public_key{{ user_key.id }}">
<a href="#">{% trans "Show" %}</a>
</p>
<div class="modal fade" id="Modal_public_key{{user_key.id }}" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Confirm"><span
aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h4 class="modal-title" id="ModalLabel_Public_Key">{% trans "Public ssh key" %}</h4>
<p style="margin-top: 10px;">{{ user_key.public_key }}</p>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">
{% trans "Close" %}
</button>
</div>
</div>
</div>
</div>
</div>
</td>
</td>
<td>
{% if user_key.private_key %}
<form action="{{ user_key.private_key.url }}">
<button style="color: #717274" type="submit" class="btn btn-default" data-toggle="modal"
>
<span class="pc-only">{% trans "Download" %}</span>
<span class="mob-only"><i class="fa fa-download"></i></span>
</button>
</form>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> </div>
{% if next_url %} {% if next_url %}

View file

@ -7,7 +7,7 @@ from .views import DjangoHostingView, RailsHostingView, PaymentVMView,\
VirtualMachineView, OrdersHostingDeleteView, NotificationsView, \ VirtualMachineView, OrdersHostingDeleteView, NotificationsView, \
MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, HostingPricingView,\ MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, HostingPricingView,\
CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, \ CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, \
SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, SSHKeyChoiceView
urlpatterns = [ urlpatterns = [
url(r'index/?$', IndexView.as_view(), name='index'), url(r'index/?$', IndexView.as_view(), name='index'),
@ -27,6 +27,8 @@ urlpatterns = [
name='virtual_machines'), name='virtual_machines'),
url(r'ssh_keys/?$', SSHKeyListView.as_view(), url(r'ssh_keys/?$', SSHKeyListView.as_view(),
name='ssh_keys'), name='ssh_keys'),
url(r'ssh_keys_choice/?$', SSHKeyChoiceView.as_view(),
name='choice_ssh_keys'),
url(r'delete_ssh_key/(?P<pk>\d+)/?$', SSHKeyDeleteView.as_view(), url(r'delete_ssh_key/(?P<pk>\d+)/?$', SSHKeyDeleteView.as_view(),
name='delete_ssh_key'), name='delete_ssh_key'),
url(r'create_ssh_key/?$', SSHKeyCreateView.as_view(), url(r'create_ssh_key/?$', SSHKeyCreateView.as_view(),

View file

@ -1,3 +1,7 @@
import uuid
from django.core.files.base import ContentFile
from oca.pool import WrongNameError, WrongIdError from oca.pool import WrongNameError, WrongIdError
from django.shortcuts import render from django.shortcuts import render
from django.http import Http404 from django.http import Http404
@ -24,7 +28,7 @@ from utils.forms import BillingAddressForm, PasswordResetRequestForm, UserBillin
from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
from utils.mailer import BaseEmail from utils.mailer import BaseEmail
from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey
from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm, generate_ssh_key_name
from .mixins import ProcessVMSelectionMixin from .mixins import ProcessVMSelectionMixin
from opennebula_api.models import OpenNebulaManager from opennebula_api.models import OpenNebulaManager
@ -193,8 +197,10 @@ class SignupView(CreateView):
name = form.cleaned_data.get('name') name = form.cleaned_data.get('name')
email = form.cleaned_data.get('email') email = form.cleaned_data.get('email')
password = form.cleaned_data.get('password') password = form.cleaned_data.get('password')
this_base_url = "{0}://{1}".format(self.request.scheme, self.request.get_host()) this_base_url = "{0}://{1}".format(self.request.scheme,
CustomUser.register(name, password, email, app='dcl', base_url=this_base_url) self.request.get_host())
CustomUser.register(name, password, email,
app='dcl', base_url=this_base_url)
return HttpResponseRedirect(reverse_lazy('hosting:signup-validate')) return HttpResponseRedirect(reverse_lazy('hosting:signup-validate'))
@ -204,8 +210,10 @@ class SignupValidateView(TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(SignupValidateView, self).get_context_data(**kwargs) context = super(SignupValidateView, self).get_context_data(**kwargs)
login_url = '<a href="' + reverse('hosting:login') + '">' + str(_('login')) + '</a>' login_url = '<a href="' + \
home_url = '<a href="' + reverse('datacenterlight:index') + '">Data Center Light</a>' reverse('hosting:login') + '">' + str(_('login')) + '</a>'
home_url = '<a href="' + \
reverse('datacenterlight:index') + '">Data Center Light</a>'
message = '{signup_success_message} {lurl}</a> \ message = '{signup_success_message} {lurl}</a> \
<br />{go_back} {hurl}.'.format( <br />{go_back} {hurl}.'.format(
signup_success_message=_( signup_success_message=_(
@ -226,15 +234,18 @@ class SignupValidatedView(SignupValidateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(SignupValidateView, self).get_context_data(**kwargs) context = super(SignupValidateView, self).get_context_data(**kwargs)
validated = CustomUser.validate_url(self.kwargs['validate_slug']) validated = CustomUser.validate_url(self.kwargs['validate_slug'])
login_url = '<a href="' + reverse('hosting:login') + '">' + str(_('login')) + '</a>' login_url = '<a href="' + \
reverse('hosting:login') + '">' + str(_('login')) + '</a>'
section_title = _('Account activation') section_title = _('Account activation')
if validated: if validated:
message = '{account_activation_string} <br /> {login_string} {lurl}.'.format( message = '{account_activation_string} <br /> {login_string} {lurl}.'.format(
account_activation_string=_("Your account has been activated."), account_activation_string=_(
"Your account has been activated."),
login_string=_("You can now"), login_string=_("You can now"),
lurl=login_url) lurl=login_url)
else: else:
home_url = '<a href="' + reverse('datacenterlight:index') + '">Data Center Light</a>' home_url = '<a href="' + \
reverse('datacenterlight:index') + '">Data Center Light</a>'
message = '{sorry_message} <br />{go_back_to} {hurl}'.format( message = '{sorry_message} <br />{go_back_to} {hurl}'.format(
sorry_message=_("Sorry. Your request is invalid."), sorry_message=_("Sorry. Your request is invalid."),
go_back_to=_('Go back to'), go_back_to=_('Go back to'),
@ -364,10 +375,29 @@ class SSHKeyListView(LoginRequiredMixin, ListView):
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
if not self.queryset: if not self.queryset:
return HttpResponseRedirect(reverse('hosting:create_ssh_key')) return HttpResponseRedirect(reverse('hosting:choice_ssh_keys'))
return super(SSHKeyListView, self).render_to_response(context, **response_kwargs) return super(SSHKeyListView, self).render_to_response(context, **response_kwargs)
class SSHKeyChoiceView(LoginRequiredMixin, View):
template_name = "hosting/choice_ssh_keys.html"
login_url = reverse_lazy('hosting:login')
def get(self, request, *args, **kwargs):
context = {}
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
name = generate_ssh_key_name()
private_key, public_key = UserHostingKey.generate_keys()
content = ContentFile(private_key)
ssh_key = UserHostingKey.objects.create(
user=request.user, public_key=public_key, name=name)
filename = name + '_' + str(uuid.uuid4())[:8] + '_private.pem'
ssh_key.private_key.save(filename, content)
return redirect(reverse_lazy('hosting:ssh_keys'), foo='bar')
class SSHKeyCreateView(LoginRequiredMixin, FormView): class SSHKeyCreateView(LoginRequiredMixin, FormView):
form_class = UserHostingKeyForm form_class = UserHostingKeyForm
model = UserHostingKey model = UserHostingKey
@ -383,6 +413,11 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
def form_valid(self, form): def form_valid(self, form):
form.save() form.save()
if 'dcl-generated-key-' in form.instance.name:
content = ContentFile(form.cleaned_data.get('private_key'))
filename = form.cleaned_data.get(
'name') + '_' + str(uuid.uuid4())[:8] + '_private.pem'
form.instance.private_key.save(filename, content)
context = self.get_context_data() context = self.get_context_data()
next_url = self.request.session.get( next_url = self.request.session.get(
@ -407,10 +442,11 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
manager = OpenNebulaManager() manager = OpenNebulaManager()
# Get user ssh key # Get user ssh key
public_key = form.cleaned_data.get('public_key', '').decode('utf-8') public_key = str(form.cleaned_data.get('public_key', ''))
# Add ssh key to user # Add ssh key to user
try: try:
manager.add_public_key(user=owner, public_key=public_key, merge=True) manager.add_public_key(
user=owner, public_key=public_key, merge=True)
except ConnectionError: except ConnectionError:
pass pass
except WrongNameError: except WrongNameError:
@ -421,6 +457,9 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
print(self.request.POST.dict()) print(self.request.POST.dict())
form = self.get_form() form = self.get_form()
required = 'add_ssh' in self.request.POST
form.fields['name'].required = required
form.fields['public_key'].required = required
if form.is_valid(): if form.is_valid():
return self.form_valid(form) return self.form_valid(form)
else: else:
@ -563,7 +602,7 @@ class PaymentVMView(LoginRequiredMixin, FormView):
# Create a Hosting Bill # Create a Hosting Bill
HostingBill.create( HostingBill.create(
customer=customer, billing_address=billing_address) customer=customer, billing_address=billing_address)
# Create Billing Address for User if he does not have one # Create Billing Address for User if he does not have one
if not customer.user.billing_addresses.count(): if not customer.user.billing_addresses.count():