269 lines
9.9 KiB
Python
269 lines
9.9 KiB
Python
|
import uuid
|
||
|
|
||
|
from django.conf import settings
|
||
|
from django.contrib import messages
|
||
|
from django.contrib.auth import authenticate, login
|
||
|
from django.contrib.auth.tokens import default_token_generator
|
||
|
from django.core.files.base import ContentFile
|
||
|
from django.urls import reverse_lazy
|
||
|
from django.http import HttpResponseRedirect
|
||
|
from django.shortcuts import render
|
||
|
from django.utils.encoding import force_bytes
|
||
|
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||
|
from django.utils.translation import gettext_lazy as _
|
||
|
from django.views.decorators.cache import cache_control
|
||
|
from django.views.generic import FormView, CreateView
|
||
|
|
||
|
from datacenterlight.utils import get_cms_integration
|
||
|
from hosting.forms import UserHostingKeyForm
|
||
|
from hosting.models import UserHostingKey
|
||
|
from membership.models import CustomUser
|
||
|
from opennebula_api.opennebula_manager import OpenNebulaManager
|
||
|
from utils.hosting_utils import get_all_public_keys
|
||
|
from .forms import SetPasswordForm
|
||
|
from .mailer import BaseEmail
|
||
|
|
||
|
|
||
|
class SignupViewMixin(CreateView):
|
||
|
model = CustomUser
|
||
|
success_url = None
|
||
|
|
||
|
def get_success_url(self):
|
||
|
next_url = self.request.POST.get('next') if self.request.POST.get(
|
||
|
'next') \
|
||
|
else self.success_url
|
||
|
|
||
|
return next_url
|
||
|
|
||
|
def form_valid(self, form):
|
||
|
name = form.cleaned_data.get('name')
|
||
|
email = form.cleaned_data.get('email')
|
||
|
password = form.cleaned_data.get('password')
|
||
|
|
||
|
CustomUser.register(name, password, email)
|
||
|
auth_user = authenticate(email=email, password=password)
|
||
|
login(self.request, auth_user)
|
||
|
|
||
|
return HttpResponseRedirect(self.get_success_url())
|
||
|
|
||
|
|
||
|
class LoginViewMixin(FormView):
|
||
|
success_url = None
|
||
|
|
||
|
def get_success_url(self):
|
||
|
next_url = self.request.POST.get('next', self.success_url)
|
||
|
if not next_url:
|
||
|
return self.success_url
|
||
|
return next_url
|
||
|
|
||
|
def form_valid(self, form):
|
||
|
email = form.cleaned_data.get('email')
|
||
|
password = form.cleaned_data.get('password')
|
||
|
auth_user = authenticate(email=email, password=password)
|
||
|
|
||
|
if auth_user:
|
||
|
login(self.request, auth_user)
|
||
|
return HttpResponseRedirect(self.get_success_url())
|
||
|
|
||
|
return HttpResponseRedirect(self.get_success_url())
|
||
|
|
||
|
@cache_control(no_cache=True, must_revalidate=True, no_store=True)
|
||
|
def get(self, request, *args, **kwargs):
|
||
|
if self.request.user.is_authenticated():
|
||
|
return HttpResponseRedirect(self.get_success_url())
|
||
|
|
||
|
return super(LoginViewMixin, self).get(request, *args, **kwargs)
|
||
|
|
||
|
|
||
|
class ResendActivationLinkViewMixin(FormView):
|
||
|
success_message = _(
|
||
|
"An email with the activation link has been sent to you")
|
||
|
|
||
|
def generate_email_context(self, user):
|
||
|
context = {
|
||
|
'base_url': "{0}://{1}".format(self.request.scheme,
|
||
|
self.request.get_host()),
|
||
|
'activation_link': reverse_lazy(
|
||
|
'hosting:validate',
|
||
|
kwargs={'validate_slug': user.validation_slug}
|
||
|
),
|
||
|
'dcl_text': settings.DCL_TEXT,
|
||
|
}
|
||
|
return context
|
||
|
|
||
|
def form_valid(self, form):
|
||
|
email = form.cleaned_data.get('email')
|
||
|
user = CustomUser.objects.get(email=email)
|
||
|
messages.add_message(self.request, messages.SUCCESS,
|
||
|
self.success_message)
|
||
|
context = self.generate_email_context(user)
|
||
|
email_data = {
|
||
|
'subject': '{dcl_text} {account_activation}'.format(
|
||
|
dcl_text=settings.DCL_TEXT,
|
||
|
account_activation=_('Account Activation')
|
||
|
),
|
||
|
'to': email,
|
||
|
'context': context,
|
||
|
'template_name': self.email_template_name,
|
||
|
'template_path': self.email_template_path,
|
||
|
'from_address': settings.DCL_SUPPORT_FROM_ADDRESS
|
||
|
}
|
||
|
email = BaseEmail(**email_data)
|
||
|
email.send()
|
||
|
return HttpResponseRedirect(self.get_success_url())
|
||
|
|
||
|
|
||
|
class PasswordResetViewMixin(FormView):
|
||
|
success_message = _(
|
||
|
"The link to reset your password has been sent to your email")
|
||
|
site = ''
|
||
|
|
||
|
def test_generate_email_context(self, user):
|
||
|
context = {
|
||
|
'user': user,
|
||
|
'token': default_token_generator.make_token(user),
|
||
|
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
|
||
|
'site_name': 'ungleich' if self.site != 'dcl' else settings.DCL_TEXT,
|
||
|
'base_url': "{0}://{1}".format(self.request.scheme,
|
||
|
self.request.get_host())
|
||
|
}
|
||
|
return context
|
||
|
|
||
|
def form_valid(self, form):
|
||
|
email = form.cleaned_data.get('email')
|
||
|
user = CustomUser.objects.get(email=email)
|
||
|
messages.add_message(self.request, messages.SUCCESS,
|
||
|
self.success_message)
|
||
|
context = self.test_generate_email_context(user)
|
||
|
email_data = {
|
||
|
'subject': _('Password Reset'),
|
||
|
'to': email,
|
||
|
'context': context,
|
||
|
'template_name': 'password_reset_email',
|
||
|
'template_path': self.template_email_path
|
||
|
}
|
||
|
if self.site == 'dcl':
|
||
|
email_data['from_address'] = settings.DCL_SUPPORT_FROM_ADDRESS
|
||
|
email = BaseEmail(**email_data)
|
||
|
email.send()
|
||
|
|
||
|
return HttpResponseRedirect(self.get_success_url())
|
||
|
|
||
|
|
||
|
class PasswordResetConfirmViewMixin(FormView):
|
||
|
form_class = SetPasswordForm
|
||
|
|
||
|
def post(self, request, uidb64=None, token=None, *arg, **kwargs):
|
||
|
try:
|
||
|
uid = urlsafe_base64_decode(uidb64)
|
||
|
user = CustomUser.objects.get(pk=uid)
|
||
|
except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
|
||
|
user = None
|
||
|
|
||
|
form = self.form_class(request.POST)
|
||
|
|
||
|
if user is not None and default_token_generator.check_token(user,
|
||
|
token):
|
||
|
if form.is_valid():
|
||
|
new_password = form.cleaned_data['new_password2']
|
||
|
user.set_password(new_password)
|
||
|
user.save()
|
||
|
messages.success(request, _('Password has been reset.'))
|
||
|
return self.form_valid(form)
|
||
|
else:
|
||
|
messages.error(request,
|
||
|
_('Password reset has not been successful.'))
|
||
|
form.add_error(None,
|
||
|
_('Password reset has not been successful.'))
|
||
|
return self.form_invalid(form)
|
||
|
|
||
|
else:
|
||
|
messages.error(request,
|
||
|
_('The reset password link is no longer valid.'))
|
||
|
form.add_error(None,
|
||
|
_('The reset password link is no longer valid.'))
|
||
|
return self.form_invalid(form)
|
||
|
|
||
|
|
||
|
class SSHKeyCreateView(FormView):
|
||
|
form_class = UserHostingKeyForm
|
||
|
model = UserHostingKey
|
||
|
template_name = 'hosting/user_key.html'
|
||
|
login_url = reverse_lazy('hosting:login')
|
||
|
context_object_name = "virtual_machine"
|
||
|
success_url = reverse_lazy('hosting:ssh_keys')
|
||
|
|
||
|
def get_form_kwargs(self):
|
||
|
kwargs = super(SSHKeyCreateView, self).get_form_kwargs()
|
||
|
kwargs.update({'request': self.request})
|
||
|
return kwargs
|
||
|
|
||
|
def form_valid(self, form):
|
||
|
form.save()
|
||
|
if settings.DCL_SSH_KEY_NAME_PREFIX 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()
|
||
|
|
||
|
next_url = self.request.session.get(
|
||
|
'next',
|
||
|
reverse_lazy('hosting:create_virtual_machine')
|
||
|
)
|
||
|
|
||
|
if 'next' in self.request.session:
|
||
|
context.update({
|
||
|
'next_url': next_url
|
||
|
})
|
||
|
del (self.request.session['next'])
|
||
|
|
||
|
if form.cleaned_data.get('private_key'):
|
||
|
context.update({
|
||
|
'private_key': form.cleaned_data.get('private_key'),
|
||
|
'key_name': form.cleaned_data.get('name'),
|
||
|
'form': UserHostingKeyForm(request=self.request),
|
||
|
})
|
||
|
|
||
|
if self.request.user.is_authenticated():
|
||
|
owner = self.request.user
|
||
|
manager = OpenNebulaManager(
|
||
|
email=owner.username,
|
||
|
password=owner.password
|
||
|
)
|
||
|
keys_to_save = get_all_public_keys(self.request.user)
|
||
|
manager.save_key_in_opennebula_user('\n'.join(keys_to_save))
|
||
|
else:
|
||
|
self.request.session["new_user_hosting_key_id"] = form.instance.id
|
||
|
return HttpResponseRedirect(self.success_url)
|
||
|
|
||
|
def post(self, request, *args, **kwargs):
|
||
|
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():
|
||
|
return self.form_valid(form)
|
||
|
else:
|
||
|
return self.form_invalid(form)
|
||
|
|
||
|
|
||
|
class AskSSHKeyView(SSHKeyCreateView):
|
||
|
form_class = UserHostingKeyForm
|
||
|
template_name = "datacenterlight/add_ssh_key.html"
|
||
|
success_url = reverse_lazy('datacenterlight:order_confirmation')
|
||
|
context_object_name = "dcl_vm_buy_add_ssh_key"
|
||
|
|
||
|
@cache_control(no_cache=True, must_revalidate=True, no_store=True)
|
||
|
def get(self, request, *args, **kwargs):
|
||
|
context = {
|
||
|
'site_url': reverse_lazy('datacenterlight:index'),
|
||
|
'cms_integration': get_cms_integration('default'),
|
||
|
'form': UserHostingKeyForm(request=self.request),
|
||
|
'keys': get_all_public_keys(self.request.user)
|
||
|
}
|
||
|
return render(request, self.template_name, context)
|
||
|
|
||
|
def post(self, request, *args, **kwargs):
|
||
|
self.success_url = self.request.session.get("order_confirm_url")
|
||
|
return super(AskSSHKeyView, self).post(self, request, *args, **kwargs)
|