Sign up
diff --git a/hosting/test_views.py b/hosting/test_views.py
index 0e9c7626..b2deb6d7 100644
--- a/hosting/test_views.py
+++ b/hosting/test_views.py
@@ -10,7 +10,7 @@ from model_mommy import mommy
from membership.models import CustomUser, StripeCustomer
from .models import VirtualMachineType, HostingOrder, VirtualMachinePlan
from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView, LoginView, SignupView, \
- PaymentVMView, OrdersHostingDetailView, OrdersHostingListView, VirtualMachineDetailView, \
+ PaymentVMView, OrdersHostingDetailView, OrdersHostingListView, VirtualMachineView, \
VirtualMachinesPlanListView
from utils.tests import BaseTestCase
@@ -172,16 +172,16 @@ class PaymentVMViewTest(BaseTestCase):
settings.STRIPE_API_PUBLIC_KEY)
-class VirtualMachineDetailViewTest(BaseTestCase):
+class VirtualMachineViewTest(BaseTestCase):
def setUp(self):
- super(VirtualMachineDetailViewTest, self).setUp()
+ super(VirtualMachineViewTest, self).setUp()
self.stripe_customer = mommy.make(StripeCustomer, user=self.customer)
self.vm = mommy.make(VirtualMachinePlan)
self.order = mommy.make(HostingOrder, customer=self.stripe_customer, vm_plan=self.vm)
self.url = reverse('hosting:virtual_machines', kwargs={'pk': self.vm.id})
- self.view = VirtualMachineDetailView()
+ self.view = VirtualMachineView()
self.expected_template = 'hosting/virtual_machine_detail.html'
def url_resolve_to_view_correctly(self):
diff --git a/hosting/urls.py b/hosting/urls.py
index 83bab74b..225dd19e 100644
--- a/hosting/urls.py
+++ b/hosting/urls.py
@@ -4,7 +4,7 @@ from .views import DjangoHostingView, RailsHostingView, PaymentVMView,\
NodeJSHostingView, LoginView, SignupView, IndexView, \
OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\
VirtualMachineView, GenerateVMSSHKeysView, OrdersHostingDeleteView, NotificationsView, \
- MarkAsReadNotificationView
+ MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView
urlpatterns = [
url(r'index/?$', IndexView.as_view(), name='index'),
@@ -27,6 +27,9 @@ urlpatterns = [
name='read_notification'),
url(r'login/?$', LoginView.as_view(), name='login'),
url(r'signup/?$', SignupView.as_view(), name='signup'),
+ url(r'reset-password/?$', PasswordResetView.as_view(), name='reset_password'),
+ url(r'reset-password-confirm/(?P[0-9A-Za-z]+)-(?P.+)/$',
+ PasswordResetConfirmView.as_view(), name='reset_password_confirm'),
url(r'^logout/?$', 'django.contrib.auth.views.logout',
{'next_page': '/hosting/login?logged_out=true'}, name='logout')
]
diff --git a/hosting/views.py b/hosting/views.py
index eca04023..09f94ac9 100644
--- a/hosting/views.py
+++ b/hosting/views.py
@@ -4,6 +4,10 @@ from django.core.urlresolvers import reverse_lazy, reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import View, CreateView, FormView, ListView, DetailView,\
DeleteView, TemplateView, UpdateView
+from django.contrib.auth.tokens import default_token_generator
+from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
+from django.contrib import messages
+from django.utils.encoding import force_bytes
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login
from django.conf import settings
@@ -16,7 +20,7 @@ from stored_messages.api import mark_read
from membership.models import CustomUser, StripeCustomer
from utils.stripe_utils import StripeUtils
-from utils.forms import BillingAddressForm
+from utils.forms import BillingAddressForm, PasswordResetRequestForm, SetPasswordForm
from utils.mailer import BaseEmail
from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder
from .forms import HostingUserSignupForm, HostingUserLoginForm
@@ -164,6 +168,71 @@ class SignupView(CreateView):
return HttpResponseRedirect(self.get_success_url())
+class PasswordResetView(FormView):
+ template_name = 'hosting/reset_password.html'
+ form_class = PasswordResetRequestForm
+ success_message = "The link to reset your email has been sent to your email"
+ success_url = reverse_lazy('hosting:login')
+ # form_valid_message = 'Thank you for registering'
+
+ 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 = {
+ 'user': user,
+ 'token': default_token_generator.make_token(user),
+ 'uid': urlsafe_base64_encode(force_bytes(user.pk)),
+ 'site_name': 'ungleich',
+ 'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host())
+
+ }
+ email_data = {
+ 'subject': 'Password Reset',
+ 'to': email,
+ 'context': context,
+ 'template_name': 'password_reset_email',
+ 'template_path': 'emails/'
+ }
+ email = BaseEmail(**email_data)
+ email.send()
+
+ return HttpResponseRedirect(self.get_success_url())
+
+
+class PasswordResetConfirmView(FormView):
+ template_name = 'hosting/confirm_reset_password.html'
+ form_class = SetPasswordForm
+ success_url = reverse_lazy('hosting:login')
+
+ 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 unsuccessful.')
+ return self.form_invalid(form)
+
+ else:
+ messages.error(request, 'The reset password link is no longer valid.')
+ return self.form_invalid(form)
+
+
class NotificationsView(TemplateView):
template_name = 'hosting/notifications.html'
@@ -285,13 +354,16 @@ class PaymentVMView(LoginRequiredMixin, FormView):
# Send notification to ungleich as soon as VM has been booked
# TODO send email using celery
+
context = {
'vm': plan,
- 'order': order
+ 'order': order,
+ 'base_url': "{0}://{1}".format(request.scheme, request.get_host())
+
}
email_data = {
'subject': 'New VM request',
- 'to': 'info@ungleich.ch',
+ 'to': request.user.email,
'context': context,
'template_name': 'new_booked_vm',
'template_path': 'emails/'
@@ -299,11 +371,6 @@ class PaymentVMView(LoginRequiredMixin, FormView):
email = BaseEmail(**email_data)
email.send()
- # request.session.update({
- # 'charge': charge,
- # 'order': order.id,
- # 'billing_address': billing_address.id
- # })
return HttpResponseRedirect(reverse('hosting:orders', kwargs={'pk': order.id}))
else:
return self.form_invalid(form)
@@ -368,7 +435,8 @@ class VirtualMachineView(LoginRequiredMixin, UpdateView):
vm.cancel_plan()
context = {
- 'vm': vm
+ 'vm': vm,
+ 'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host())
}
email_data = {
'subject': 'Virtual machine plan canceled',
diff --git a/ungleich/templates/cms/ungleichch/base_ungleich.html b/ungleich/templates/cms/ungleichch/base_ungleich.html
index 833b2111..6f70a4a8 100644
--- a/ungleich/templates/cms/ungleichch/base_ungleich.html
+++ b/ungleich/templates/cms/ungleichch/base_ungleich.html
@@ -1,4 +1,4 @@
-{% load cms_tags menu_tags sekizai_tags staticfiles bootstrap3 %}
+{% load i18n cms_tags menu_tags sekizai_tags staticfiles bootstrap3 %}
diff --git a/utils/forms.py b/utils/forms.py
index 0e64020a..7af6f99a 100644
--- a/utils/forms.py
+++ b/utils/forms.py
@@ -3,9 +3,52 @@ from .models import ContactMessage, BillingAddress
from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives
from django.utils.translation import ugettext_lazy as _
+from membership.models import CustomUser
# from utils.fields import CountryField
+class PasswordResetRequestForm(forms.Form):
+ email = forms.CharField(widget=forms.EmailInput())
+
+ class Meta:
+ fields = ['email']
+
+ def clean_email(self):
+ email = self.cleaned_data.get('email')
+ try:
+ CustomUser.objects.get(email=email)
+ return email
+ except CustomUser.DoesNotExist:
+ raise forms.ValidationError("User does not exist")
+ else:
+ return email
+
+
+class SetPasswordForm(forms.Form):
+ """
+ A form that lets a user change set their password without entering the old
+ password
+ """
+ error_messages = {
+ 'password_mismatch': ("The two password fields didn't match."),
+ }
+ new_password1 = forms.CharField(label=("New password"),
+ widget=forms.PasswordInput)
+ new_password2 = forms.CharField(label=("New password confirmation"),
+ widget=forms.PasswordInput)
+
+ def clean_new_password2(self):
+ password1 = self.cleaned_data.get('new_password1')
+ password2 = self.cleaned_data.get('new_password2')
+ if password1 and password2:
+ if password1 != password2:
+ raise forms.ValidationError(
+ self.error_messages['password_mismatch'],
+ code='password_mismatch',)
+ return password2
+
+
+
class BillingAddressForm(forms.ModelForm):
token = forms.CharField(widget=forms.HiddenInput())
diff --git a/utils/mailer.py b/utils/mailer.py
index 130b74ee..0afa60b7 100644
--- a/utils/mailer.py
+++ b/utils/mailer.py
@@ -21,7 +21,7 @@ class BaseEmail(object):
self.email = EmailMultiAlternatives(self.subject, text_content)
self.email.attach_alternative(html_content, "text/html")
- self.email.to = ['info@digitalglarus.ch']
+ self.email.to = ['levinoelvm@gmail.com']
def send(self):
self.email.send()