commit
05b8493fe1
24 changed files with 263 additions and 32 deletions
|
@ -8,6 +8,8 @@ ADMINS = (
|
|||
)
|
||||
# ('Sanghee Kim', 'sanghee.kim@ungleich.ch'),
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
|
||||
#MANAGERS = ADMINS
|
||||
|
||||
REGISTRATION_MESSAGE['message'] = REGISTRATION_MESSAGE['message'].format(host='digitalglarus.ungleich.ch',slug='{slug}')
|
||||
|
|
|
@ -25,7 +25,7 @@ urlpatterns += i18n_patterns('',
|
|||
url(r'^digitalglarus/login/', include(membership_urls)),
|
||||
url(r'^digitalglarus/', include('digitalglarus.urls',
|
||||
namespace="digitalglarus")),
|
||||
url(r'^blog/', include('ungleich.urls', namespace='ungleich')),
|
||||
# url(r'^blog/', include('ungleich.urls', namespace='ungleich')),
|
||||
url(r'^ungleich_page/',
|
||||
include('ungleich_page.urls', namespace='ungleich_page'),
|
||||
name='ungleich_page'),
|
||||
|
|
|
@ -32,10 +32,11 @@ class HostingOrderAdmin(admin.ModelAdmin):
|
|||
|
||||
context = {
|
||||
'order': obj,
|
||||
'vm': obj.vm_plan
|
||||
'vm': obj.vm_plan,
|
||||
'base_url': "{0}://{1}".format(request.scheme, request.get_host())
|
||||
}
|
||||
email_data = {
|
||||
'subject': 'New VM request',
|
||||
'subject': 'Your VM plan has been charged',
|
||||
'to': obj.customer.user.email,
|
||||
'context': context,
|
||||
'template_name': 'vm_charged',
|
||||
|
@ -75,7 +76,8 @@ class VirtualMachinePlanAdmin(admin.ModelAdmin):
|
|||
email = self.email(obj)
|
||||
if 'status' in form.changed_data:
|
||||
context = {
|
||||
'vm': obj
|
||||
'vm': obj,
|
||||
'base_url': "{0}://{1}".format(request.scheme, request.get_host())
|
||||
}
|
||||
email_data = {
|
||||
'subject': 'Your VM has been activated',
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.contrib.auth import authenticate
|
|||
|
||||
from utils.stripe_utils import StripeUtils
|
||||
|
||||
from .models import HostingOrder
|
||||
from .models import HostingOrder, VirtualMachinePlan
|
||||
|
||||
|
||||
class HostingOrderAdminForm(forms.ModelForm):
|
||||
|
@ -17,6 +17,10 @@ class HostingOrderAdminForm(forms.ModelForm):
|
|||
customer = self.cleaned_data.get('customer')
|
||||
vm_plan = self.cleaned_data.get('vm_plan')
|
||||
|
||||
if vm_plan.status == VirtualMachinePlan.CANCELED_STATUS:
|
||||
raise forms.ValidationError("""You can't make a charge over
|
||||
a canceled virtual machine plan""")
|
||||
|
||||
# Make a charge to the customer
|
||||
stripe_utils = StripeUtils()
|
||||
charge_response = stripe_utils.make_charge(customer=customer.stripe_id,
|
||||
|
@ -53,7 +57,7 @@ class HostingUserLoginForm(forms.Form):
|
|||
CustomUser.objects.get(email=email)
|
||||
return email
|
||||
except CustomUser.DoesNotExist:
|
||||
raise forms.ValidationError("User does not exists")
|
||||
raise forms.ValidationError("User does not exist")
|
||||
else:
|
||||
return email
|
||||
|
||||
|
|
|
@ -83,6 +83,12 @@ h6 {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.intro-reset-password {
|
||||
background: url(../img/signup-bg.png) no-repeat center center;
|
||||
background-size: cover;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.intro-message > h1 {
|
||||
margin: 0;
|
||||
font-weight: 400;
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">My Account</center>
|
||||
</v:roundrect>
|
||||
<![endif]--><a href="{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
<![endif]--><a href="{{ base_url }}{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
<td class="free-text" style="border-collapse: collapse; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; color: #777777; text-align: center; line-height: 21px; width: 100% !important; padding: 10px 60px 0px;" align="center">
|
||||
Your virtual machine {{vm.name}} subscription has been charged,
|
||||
<br/>
|
||||
We are going to contact you as soon your virtual machine has been activated.
|
||||
we are going to contact you as soon your virtual machine has been activated.
|
||||
<br/>
|
||||
You can view your invoice clicking on the button below.
|
||||
</td>
|
||||
|
@ -114,7 +114,7 @@
|
|||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">My Account</center>
|
||||
</v:roundrect>
|
||||
<![endif]--><a href="{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
<![endif]--><a href="{{ base_url }}{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
13
hosting/templates/emails/password_reset_email.html
Normal file
13
hosting/templates/emails/password_reset_email.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% load i18n %}{% autoescape off %}
|
||||
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
|
||||
|
||||
{% trans "Please go to the following page and choose a new password:" %}
|
||||
{% block reset_link %}
|
||||
{{ base_url }}{% url 'hosting:reset_password_confirm' uidb64=uid token=token %}
|
||||
{% endblock %}
|
||||
|
||||
{% trans "Thanks for using our site!" %}
|
||||
|
||||
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||
|
||||
{% endautoescape %}
|
13
hosting/templates/emails/password_reset_email.txt
Normal file
13
hosting/templates/emails/password_reset_email.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% load i18n %}{% autoescape off %}
|
||||
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
|
||||
|
||||
{% trans "Please go to the following page and choose a new password:" %}
|
||||
{% block reset_link %}
|
||||
{{ base_url }}{% url 'hosting:reset_password_confirm' uidb64=uid token=token %}
|
||||
{% endblock %}
|
||||
|
||||
{% trans "Thanks for using our site!" %}
|
||||
|
||||
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
|
||||
|
||||
{% endautoescape %}
|
|
@ -110,7 +110,7 @@
|
|||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">My Account</center>
|
||||
</v:roundrect>
|
||||
<![endif]--><a href="{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
<![endif]--><a href="{{ base_url }}{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">My Account</center>
|
||||
</v:roundrect>
|
||||
<![endif]--><a href="{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
<![endif]--><a href="{{ base_url }}{% url 'hosting:orders' order.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">View Invoice</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">My Account</center>
|
||||
</v:roundrect>
|
||||
<![endif]--><a href="{{request.HOS}}{% url 'hosting:virtual_machines' vm.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">VM Dashboard</a>
|
||||
<![endif]--><a href="{{base_url}}{% url 'hosting:virtual_machines' vm.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">VM Dashboard</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<w:anchorlock/>
|
||||
<center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">My Account</center>
|
||||
</v:roundrect>
|
||||
<![endif]--><a href="{{request.HOS}}{% url 'hosting:virtual_machines' vm.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">VM Dashboard</a>
|
||||
<![endif]--><a href="{{base_url}}{% url 'hosting:virtual_machines' vm.id %}" style="border-radius: 5px; color: #ffffff; display: inline-block; font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; font-size: 14px; font-weight: regular; line-height: 45px; text-align: center; text-decoration: none !important; width: 155px; -webkit-text-size-adjust: none; mso-hide: all; background: #ff6f6f;">VM Dashboard</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand topnav" href="{% url 'ungleich_page:landing' %}"><img src="{% static 'hosting/img/logo_black.svg' %}"></a>
|
||||
<a class="navbar-brand topnav" href="{{ request.session.hosting_url}}"><img src="{% static 'hosting/img/logo_black.svg' %}"></a>
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
|
|
38
hosting/templates/hosting/confirm_reset_password.html
Normal file
38
hosting/templates/hosting/confirm_reset_password.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
{% extends "hosting/base_short.html" %}
|
||||
{% load staticfiles bootstrap3%}
|
||||
{% block content %}
|
||||
<div class="intro-auth intro-reset-password">
|
||||
<div class="container">
|
||||
<div class="col-md-4"> </div>
|
||||
<div class="col-md-4">
|
||||
<div class="intro-message">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="list-unstyled">
|
||||
{% for message in messages %}
|
||||
<li>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h2 class="section-heading">Set your new password</h2>
|
||||
|
||||
<form action="" method="post" class="form" novalidate>
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
{% bootstrap_field field show_label=False %}
|
||||
{% endfor %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn btn-default">
|
||||
Reset
|
||||
</button>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
<span>Already have an account ? <a class="unlink" href="{% url 'hosting:login' %}">Log in</a></span>
|
||||
<ul class="list-inline intro-social-buttons">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -6,6 +6,14 @@
|
|||
<div class="container">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="list-unstyled">
|
||||
{% for message in messages %}
|
||||
<li>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% block messages %}
|
||||
{% if request.GET.logged_out %}
|
||||
<div class="alert"> <!-- singular -->
|
||||
|
@ -31,6 +39,8 @@
|
|||
{% endbuttons %}
|
||||
</form>
|
||||
<span>Don't have an account yet ? <a class="unlink" href="{% url 'hosting:signup' %}">Sign up</a></span>
|
||||
<br/>
|
||||
<span> <a class="unlink" href="{% url 'hosting:reset_password' %}">Forgot your password ?</a></span>
|
||||
|
||||
<ul class="list-inline intro-social-buttons">
|
||||
|
||||
|
|
29
hosting/templates/hosting/reset_password.html
Normal file
29
hosting/templates/hosting/reset_password.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
{% extends "hosting/base_short.html" %}
|
||||
{% load staticfiles bootstrap3%}
|
||||
{% block content %}
|
||||
<div class="intro-auth intro-reset-password">
|
||||
<div class="container">
|
||||
<div class="col-md-4"> </div>
|
||||
<div class="col-md-4">
|
||||
<div class="intro-message">
|
||||
<h2 class="section-heading">Reset your password</h2>
|
||||
|
||||
<form action="{% url 'hosting:reset_password' %}" method="post" class="form" novalidate>
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
{% bootstrap_field field show_label=False %}
|
||||
{% endfor %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn btn-default">
|
||||
Reset
|
||||
</button>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
<span>Already have an account ? <a class="unlink" href="{% url 'hosting:login' %}">Log in</a></span>
|
||||
<ul class="list-inline intro-social-buttons">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -3,8 +3,8 @@
|
|||
{% block content %}
|
||||
<div class="intro-auth intro-signup">
|
||||
<div class="container">
|
||||
<div class="col-md-4"> </div>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-4 col-sm-4 col-xs-4"> </div>
|
||||
<div class="col-md-4 col-sm-6 col-xs-6">
|
||||
<div class="intro-message">
|
||||
<h2 class="section-heading">Sign up</h2>
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
|
||||
PasswordResetConfirmView.as_view(), name='reset_password_confirm'),
|
||||
url(r'^logout/?$', 'django.contrib.auth.views.logout',
|
||||
{'next_page': '/hosting/login?logged_out=true'}, name='logout')
|
||||
]
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load cms_tags menu_tags sekizai_tags staticfiles bootstrap3 %}
|
||||
{% load i18n cms_tags menu_tags sekizai_tags staticfiles bootstrap3 %}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue