Merge remote-tracking branch 'mainRepo/master' into task/5509/add-keys-to-opennebula-user
This commit is contained in:
commit
6d3b5f40c0
8 changed files with 88 additions and 6 deletions
|
@ -1,4 +1,8 @@
|
||||||
Next:
|
2.5.11: 2019-06-11
|
||||||
|
* #6672: [api] Check VM belongs to user in the infrastructure directly (MR!707)
|
||||||
|
* #bugfix: DE translation fix "Learn mehr" -> "Lerne mehr" (MR!708)
|
||||||
|
2.5.10: 2019-05-16
|
||||||
|
* #6672: [api] REST endpoint for ungleich-cli to verify if a VM belongs to a user (MR!705)
|
||||||
* #6670: [hosting/save_ssh_key] Upgrade cdist version to 5.0.1 to manage keys on Alpine linux
|
* #6670: [hosting/save_ssh_key] Upgrade cdist version to 5.0.1 to manage keys on Alpine linux
|
||||||
2.5.9: 2019-05-09
|
2.5.9: 2019-05-09
|
||||||
* #6669: [hosting] Fix opennebula vm query takes long (MR!703)
|
* #6669: [hosting] Fix opennebula vm query takes long (MR!703)
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
|
import pyotp
|
||||||
|
import requests
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from datacenterlight.tasks import create_vm_task
|
from datacenterlight.tasks import create_vm_task
|
||||||
from hosting.models import HostingOrder, HostingBill, OrderDetail
|
from hosting.models import HostingOrder, HostingBill, OrderDetail
|
||||||
|
@ -11,7 +14,6 @@ from .models import VMPricing, VMTemplate
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_cms_integration(name):
|
def get_cms_integration(name):
|
||||||
current_site = Site.objects.get_current()
|
current_site = Site.objects.get_current()
|
||||||
try:
|
try:
|
||||||
|
@ -100,3 +102,22 @@ def clear_all_session_vars(request):
|
||||||
'generic_payment_details', 'product_id']:
|
'generic_payment_details', 'product_id']:
|
||||||
if session_var in request.session:
|
if session_var in request.session:
|
||||||
del request.session[session_var]
|
del request.session[session_var]
|
||||||
|
|
||||||
|
|
||||||
|
def check_otp(name, realm, token):
|
||||||
|
data = {
|
||||||
|
"auth_name": settings.AUTH_NAME,
|
||||||
|
"auth_token": pyotp.TOTP(settings.AUTH_SEED).now(),
|
||||||
|
"auth_realm": settings.AUTH_REALM,
|
||||||
|
"name": name,
|
||||||
|
"realm": realm,
|
||||||
|
"token": token
|
||||||
|
}
|
||||||
|
response = requests.post(
|
||||||
|
"https://{OTP_SERVER}{OTP_VERIFY_ENDPOINT}".format(
|
||||||
|
OTP_SERVER=settings.OTP_SERVER,
|
||||||
|
OTP_VERIFY_ENDPOINT=settings.OTP_VERIFY_ENDPOINT
|
||||||
|
),
|
||||||
|
data=data
|
||||||
|
)
|
||||||
|
return response.status_code
|
||||||
|
|
|
@ -342,7 +342,7 @@ msgstr ""
|
||||||
"dieser Website erklärst Du Dich damit einverstanden, diese zu nutzen."
|
"dieser Website erklärst Du Dich damit einverstanden, diese zu nutzen."
|
||||||
|
|
||||||
msgid "Learn more"
|
msgid "Learn more"
|
||||||
msgstr "Learn mehr"
|
msgstr "Lerne mehr"
|
||||||
|
|
||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -721,6 +721,14 @@ X_FRAME_OPTIONS = ('SAMEORIGIN' if X_FRAME_OPTIONS_ALLOW_FROM_URI is None else
|
||||||
|
|
||||||
DEBUG = bool_env('DEBUG')
|
DEBUG = bool_env('DEBUG')
|
||||||
|
|
||||||
|
READ_VM_REALM = env('READ_VM_REALM')
|
||||||
|
AUTH_NAME = env('AUTH_NAME')
|
||||||
|
AUTH_SEED = env('AUTH_SEED')
|
||||||
|
AUTH_REALM = env('AUTH_REALM')
|
||||||
|
OTP_SERVER = env('OTP_SERVER')
|
||||||
|
OTP_VERIFY_ENDPOINT = env('OTP_VERIFY_ENDPOINT')
|
||||||
|
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
from .local import * # flake8: noqa
|
from .local import * # flake8: noqa
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -45,6 +45,11 @@ class Command(BaseCommand):
|
||||||
num_invoice_created = 0
|
num_invoice_created = 0
|
||||||
for invoice in all_invoices:
|
for invoice in all_invoices:
|
||||||
invoice['customer'] = user.stripecustomer
|
invoice['customer'] = user.stripecustomer
|
||||||
|
try:
|
||||||
|
existing_mhb = MonthlyHostingBill.objects.get(invoice_id=invoice['invoice_id'])
|
||||||
|
logger.debug("Invoice %s exists already. Not importing." % invoice['invoice_id'])
|
||||||
|
except MonthlyHostingBill.DoesNotExist as dne:
|
||||||
|
logger.debug("Invoice id %s does not exist" % invoice['invoice_id'])
|
||||||
num_invoice_created += 1 if MonthlyHostingBill.create(invoice) is not None else logger.error("Did not import invoice for %s" % str(invoice))
|
num_invoice_created += 1 if MonthlyHostingBill.create(invoice) is not None else logger.error("Did not import invoice for %s" % str(invoice))
|
||||||
self.stdout.write(
|
self.stdout.write(
|
||||||
self.style.SUCCESS("Number of invoices imported = %s" % num_invoice_created)
|
self.style.SUCCESS("Number of invoices imported = %s" % num_invoice_created)
|
||||||
|
|
|
@ -10,12 +10,13 @@ from .views import (
|
||||||
HostingPricingView, CreateVirtualMachinesView, HostingBillListView,
|
HostingPricingView, CreateVirtualMachinesView, HostingBillListView,
|
||||||
HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView,
|
HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView,
|
||||||
SSHKeyChoiceView, DashboardView, SettingsView, ResendActivationEmailView,
|
SSHKeyChoiceView, DashboardView, SettingsView, ResendActivationEmailView,
|
||||||
InvoiceListView, InvoiceDetailView
|
InvoiceListView, InvoiceDetailView, CheckUserVM
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'index/?$', IndexView.as_view(), name='index'),
|
url(r'index/?$', IndexView.as_view(), name='index'),
|
||||||
url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
|
url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
|
||||||
|
url(r'checkvm/?$', CheckUserVM.as_view(), name='check_vm'),
|
||||||
url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'),
|
url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'),
|
||||||
url(r'nodejs/?$', NodeJSHostingView.as_view(), name='nodejshosting'),
|
url(r'nodejs/?$', NodeJSHostingView.as_view(), name='nodejshosting'),
|
||||||
url(r'rails/?$', RailsHostingView.as_view(), name='railshosting'),
|
url(r'rails/?$', RailsHostingView.as_view(), name='railshosting'),
|
||||||
|
|
|
@ -28,13 +28,16 @@ from django.views.generic import (
|
||||||
)
|
)
|
||||||
from guardian.mixins import PermissionRequiredMixin
|
from guardian.mixins import PermissionRequiredMixin
|
||||||
from oca.pool import WrongIdError
|
from oca.pool import WrongIdError
|
||||||
|
from rest_framework.renderers import JSONRenderer
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
from stored_messages.api import mark_read
|
from stored_messages.api import mark_read
|
||||||
from stored_messages.models import Message
|
from stored_messages.models import Message
|
||||||
from stored_messages.settings import stored_messages_settings
|
from stored_messages.settings import stored_messages_settings
|
||||||
|
|
||||||
from datacenterlight.cms_models import DCLCalculatorPluginModel
|
from datacenterlight.cms_models import DCLCalculatorPluginModel
|
||||||
from datacenterlight.models import VMTemplate, VMPricing
|
from datacenterlight.models import VMTemplate, VMPricing
|
||||||
from datacenterlight.utils import create_vm, get_cms_integration
|
from datacenterlight.utils import create_vm, get_cms_integration, check_otp
|
||||||
from hosting.models import UserCardDetail
|
from hosting.models import UserCardDetail
|
||||||
from membership.models import CustomUser, StripeCustomer
|
from membership.models import CustomUser, StripeCustomer
|
||||||
from opennebula_api.models import OpenNebulaManager
|
from opennebula_api.models import OpenNebulaManager
|
||||||
|
@ -67,9 +70,12 @@ from .models import (
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \
|
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \
|
||||||
backend connection error. please try again in a few \
|
backend connection error. please try again in a few \
|
||||||
minutes."
|
minutes."
|
||||||
|
|
||||||
|
|
||||||
decorators = [never_cache]
|
decorators = [never_cache]
|
||||||
|
|
||||||
|
|
||||||
|
@ -1757,3 +1763,39 @@ def forbidden_view(request, exception=None, reason=''):
|
||||||
'again.')
|
'again.')
|
||||||
messages.add_message(request, messages.ERROR, err_msg)
|
messages.add_message(request, messages.ERROR, err_msg)
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
return HttpResponseRedirect(request.get_full_path())
|
||||||
|
|
||||||
|
|
||||||
|
class CheckUserVM(APIView):
|
||||||
|
renderer_classes = (JSONRenderer, )
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
try:
|
||||||
|
email = request.data['email']
|
||||||
|
ip = request.data['ip']
|
||||||
|
user = request.data['user']
|
||||||
|
realm = request.data['realm']
|
||||||
|
token = request.data['token']
|
||||||
|
if realm != settings.READ_VM_REALM:
|
||||||
|
return Response("User not allowed", 403)
|
||||||
|
response = check_otp(user, realm, token)
|
||||||
|
if response != 200:
|
||||||
|
return Response('Invalid token', 403)
|
||||||
|
manager = OpenNebulaManager()
|
||||||
|
# not the best way to lookup vms by ip
|
||||||
|
# TODO: make this optimal
|
||||||
|
vms = manager.get_vms()
|
||||||
|
users_vms = [vm for vm in vms if vm.uname == email]
|
||||||
|
if len(users_vms) == 0:
|
||||||
|
return Response('No VM found with the given email address',
|
||||||
|
404)
|
||||||
|
for vm in users_vms:
|
||||||
|
for nic in vm.template.nics:
|
||||||
|
if hasattr(nic, 'ip6_global'):
|
||||||
|
if nic.ip6_global == ip:
|
||||||
|
return Response('success', 200)
|
||||||
|
elif hasattr(nic, 'ip'):
|
||||||
|
if nic.ip == ip:
|
||||||
|
return Response('success', 200)
|
||||||
|
return Response('No VM found matching the ip address provided', 404)
|
||||||
|
except KeyError:
|
||||||
|
return Response('Not enough data provided', 400)
|
||||||
|
|
|
@ -98,3 +98,4 @@ amqp==2.2.1
|
||||||
vine==1.1.4
|
vine==1.1.4
|
||||||
cdist==5.0.1
|
cdist==5.0.1
|
||||||
git+https://github.com/ungleich/djangocms-multisite.git#egg=djangocms_multisite
|
git+https://github.com/ungleich/djangocms-multisite.git#egg=djangocms_multisite
|
||||||
|
pyotp
|
||||||
|
|
Loading…
Reference in a new issue