Merge remote-tracking branch 'ungleich/master'
This commit is contained in:
		
				commit
				
					
						b782c6212a
					
				
			
		
					 10 changed files with 154 additions and 24 deletions
				
			
		|  | @ -1,4 +1,4 @@ | |||
| Pre-changelog: 1.2.3 2017-09-20 | ||||
| 1.2.3: 2017-09-25 | ||||
|     * #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email | ||||
|     * #3731: [dcl, hosting] Added cdist ssh key handler  | ||||
|     * #3628: [dcl] on hosting, VM is created at credit card info submit | ||||
|  | @ -6,6 +6,7 @@ Pre-changelog: 1.2.3 2017-09-20 | |||
|     * #3786: [hosting] Redesigned the hosting invoice and order-confirmation page | ||||
|     * #3728: [hosting] VM Termination animation added | ||||
|     * #3777: [hosting] Create new VM calculator added like dcl landing | ||||
|     * #3781: [hosting] Resend activation mail | ||||
|     * #3806: [hosting] Fix can not create VMs after password reset | ||||
|     * Feature: [cms, blog] Added /cms prefix for all the django-cms generated urls | ||||
|     * Bugfix: [dcl, hosting] added host to celery error mails | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ msgid "" | |||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2017-09-23 19:00+0530\n" | ||||
| "POT-Creation-Date: 2017-09-24 12:34+0000\n" | ||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
|  | @ -306,6 +306,9 @@ msgstr "Registrieren" | |||
| msgid "Forgot your password ? " | ||||
| msgstr "Passwort vergessen?" | ||||
| 
 | ||||
| msgid "Resend activation link" | ||||
| msgstr "Aktivierungslink noch einmal senden" | ||||
| 
 | ||||
| msgid "Notifications" | ||||
| msgstr "Benachrichtigungen" | ||||
| 
 | ||||
|  |  | |||
|  | @ -44,6 +44,8 @@ | |||
|                         <a class="unlink" href="{% url 'hosting:signup' %}">{% trans "Sign up"%}</a> | ||||
|                         <span class="text"> or </span> | ||||
|                         <a class="unlink" href="{% url 'hosting:reset_password' %}">{% trans "Forgot your password ? "%}</a> | ||||
|                         <span class="text"> or </span><br/> | ||||
|                         <a class="unlink" href="{% url 'hosting:resend_activation_link' %}">{% trans "Resend activation link"%}</a> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|  |  | |||
							
								
								
									
										36
									
								
								hosting/templates/hosting/resend_activation_link.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								hosting/templates/hosting/resend_activation_link.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| {% extends "hosting/base_short.html" %} | ||||
| {% load staticfiles bootstrap3%} | ||||
| {% load i18n %} | ||||
| 
 | ||||
| {% block navbar %} | ||||
|     {% include  'hosting/includes/_navbar_transparent.html' %} | ||||
| {% endblock navbar %} | ||||
| 
 | ||||
| 
 | ||||
| {% block content %} | ||||
| <div class="auth-container"> | ||||
|    <div class="auth-bg"></div> | ||||
|         <div class="auth-center"> | ||||
|             <div class="auth-title"> | ||||
|                 <h2>{% trans "Your VM hosted in Switzerland"%}</h2> | ||||
|             </div> | ||||
|             <div class="auth-content"> | ||||
|                 <div class="intro-message auth-box sign-up"> | ||||
|                     <h2  class="section-heading">{% trans "Resend activation link"%}</h2> | ||||
|                     <form action="{% url 'hosting:resend_activation_link' %}" 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-block btn-success"> | ||||
|                                 {% trans "Submit"%} | ||||
|                             </button> | ||||
|                         {% endbuttons %} | ||||
|                     </form> | ||||
| 
 | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
|  | @ -8,8 +8,7 @@ from .views import ( | |||
|     MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, | ||||
|     HostingPricingView, CreateVirtualMachinesView, HostingBillListView, | ||||
|     HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, | ||||
|     SSHKeyChoiceView, DashboardView, SettingsView) | ||||
| 
 | ||||
|     SSHKeyChoiceView, DashboardView, SettingsView, ResendActivationEmailView) | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|     url(r'index/?$', IndexView.as_view(), name='index'), | ||||
|  | @ -52,6 +51,8 @@ urlpatterns = [ | |||
|     url(r'signup/?$', SignupView.as_view(), name='signup'), | ||||
|     url(r'signup-validate/?$', SignupValidateView.as_view(), | ||||
|         name='signup-validate'), | ||||
|     url(r'resend-activation-link/?$', ResendActivationEmailView.as_view(), | ||||
|         name='resend_activation_link'), | ||||
|     url(r'reset-password/?$', PasswordResetView.as_view(), | ||||
|         name='reset_password'), | ||||
|     url(r'reset-password-confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', | ||||
|  |  | |||
|  | @ -33,12 +33,15 @@ from membership.models import CustomUser, StripeCustomer | |||
| from opennebula_api.models import OpenNebulaManager | ||||
| from opennebula_api.serializers import VirtualMachineSerializer, \ | ||||
|     VirtualMachineTemplateSerializer, VMTemplateSerializer | ||||
| from utils.forms import BillingAddressForm, PasswordResetRequestForm, \ | ||||
|     UserBillingAddressForm | ||||
| from utils.forms import ( | ||||
|     BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm, | ||||
|     ResendActivationEmailForm | ||||
| ) | ||||
| from utils.mailer import BaseEmail | ||||
| from utils.stripe_utils import StripeUtils | ||||
| from utils.views import ( | ||||
|     PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin | ||||
|     PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin, | ||||
|     ResendActivationLinkViewMixin | ||||
| ) | ||||
| from .forms import HostingUserSignupForm, HostingUserLoginForm, \ | ||||
|     UserHostingKeyForm, generate_ssh_key_name | ||||
|  | @ -282,6 +285,14 @@ class SignupValidatedView(SignupValidateView): | |||
|         return context | ||||
| 
 | ||||
| 
 | ||||
| class ResendActivationEmailView(ResendActivationLinkViewMixin): | ||||
|     template_name = 'hosting/resend_activation_link.html' | ||||
|     form_class = ResendActivationEmailForm | ||||
|     success_url = reverse_lazy('hosting:login') | ||||
|     email_template_path = 'datacenterlight/emails/' | ||||
|     email_template_name = 'user_activation' | ||||
| 
 | ||||
| 
 | ||||
| class PasswordResetView(PasswordResetViewMixin): | ||||
|     site = 'dcl' | ||||
|     template_name = 'hosting/reset_password.html' | ||||
|  |  | |||
|  | @ -96,5 +96,4 @@ pyflakes==1.5.0 | |||
| billiard==3.5.0.3 | ||||
| amqp==2.2.1 | ||||
| vine==1.1.4 | ||||
| #git+https://github.com/ungleich/cdist.git#egg=cdist | ||||
| file:///home/app/cdist#egg=cdist | ||||
| cdist==4.7.0 | ||||
|  |  | |||
|  | @ -18,7 +18,8 @@ class SignupFormMixin(forms.ModelForm): | |||
|         model = CustomUser | ||||
|         fields = ['name', 'email', 'password'] | ||||
|         widgets = { | ||||
|             'name': forms.TextInput(attrs={'placeholder': _('Enter your name or company name')}), | ||||
|             'name': forms.TextInput( | ||||
|                 attrs={'placeholder': _('Enter your name or company name')}), | ||||
|         } | ||||
| 
 | ||||
|     def clean_confirm_password(self): | ||||
|  | @ -42,7 +43,7 @@ class LoginFormMixin(forms.Form): | |||
|         is_auth = authenticate(email=email, password=password) | ||||
|         if not is_auth: | ||||
|             raise forms.ValidationError( | ||||
|                 "Your username and/or password were incorrect.") | ||||
|                 _("Your username and/or password were incorrect.")) | ||||
|         return self.cleaned_data | ||||
| 
 | ||||
|     def clean_email(self): | ||||
|  | @ -51,7 +52,24 @@ class LoginFormMixin(forms.Form): | |||
|             CustomUser.objects.get(email=email) | ||||
|             return email | ||||
|         except CustomUser.DoesNotExist: | ||||
|             raise forms.ValidationError("User does not exist") | ||||
|             raise forms.ValidationError(_("User does not exist")) | ||||
| 
 | ||||
| 
 | ||||
| class ResendActivationEmailForm(forms.Form): | ||||
|     email = forms.CharField(widget=forms.EmailInput()) | ||||
| 
 | ||||
|     class Meta: | ||||
|         fields = ['email'] | ||||
| 
 | ||||
|     def clean_email(self): | ||||
|         email = self.cleaned_data.get('email') | ||||
|         try: | ||||
|             c = CustomUser.objects.get(email=email) | ||||
|             if c.validated == 1: | ||||
|                 raise forms.ValidationError(_("The account is already active.")) | ||||
|             return email | ||||
|         except CustomUser.DoesNotExist: | ||||
|             raise forms.ValidationError(_("User does not exist")) | ||||
| 
 | ||||
| 
 | ||||
| class PasswordResetRequestForm(forms.Form): | ||||
|  | @ -66,7 +84,7 @@ class PasswordResetRequestForm(forms.Form): | |||
|             CustomUser.objects.get(email=email) | ||||
|             return email | ||||
|         except CustomUser.DoesNotExist: | ||||
|             raise forms.ValidationError("User does not exist") | ||||
|             raise forms.ValidationError(_("User does not exist")) | ||||
| 
 | ||||
| 
 | ||||
| class SetPasswordForm(forms.Form): | ||||
|  | @ -75,11 +93,11 @@ class SetPasswordForm(forms.Form): | |||
|     password | ||||
|     """ | ||||
|     error_messages = { | ||||
|         'password_mismatch': ("The two password fields didn't match."), | ||||
|         'password_mismatch': _("The two password fields didn't match."), | ||||
|     } | ||||
|     new_password1 = forms.CharField(label=("New password"), | ||||
|     new_password1 = forms.CharField(label=_("New password"), | ||||
|                                     widget=forms.PasswordInput) | ||||
|     new_password2 = forms.CharField(label=("New password confirmation"), | ||||
|     new_password2 = forms.CharField(label=_("New password confirmation"), | ||||
|                                     widget=forms.PasswordInput) | ||||
| 
 | ||||
|     def clean_new_password2(self): | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ msgid "" | |||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2017-09-02 11:50+0000\n" | ||||
| "POT-Creation-Date: 2017-09-25 20:11+0000\n" | ||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
|  | @ -738,6 +738,24 @@ msgstr "" | |||
| msgid "Enter your name or company name" | ||||
| msgstr "Geben Sie Ihren Namen oder der Ihrer Firma ein" | ||||
| 
 | ||||
| msgid "Your username and/or password were incorrect." | ||||
| msgstr "Dein Benutzername und/oder Dein Passwort ist falsch." | ||||
| 
 | ||||
| msgid "User does not exist" | ||||
| msgstr "Der Benutzer existiert nicht" | ||||
| 
 | ||||
| msgid "The account is already active." | ||||
| msgstr "Das Benutzerkonto ist bereits aktiv." | ||||
| 
 | ||||
| msgid "The two password fields didn't match." | ||||
| msgstr "Die beiden Passwörter stimmen nicht überein." | ||||
| 
 | ||||
| msgid "New password" | ||||
| msgstr "Neues Passwort" | ||||
| 
 | ||||
| msgid "New password confirmation" | ||||
| msgstr "Neues Passwort Bestätigung" | ||||
| 
 | ||||
| msgid "Cardholder Name" | ||||
| msgstr "Name des Kartenbesitzer" | ||||
| 
 | ||||
|  | @ -768,8 +786,16 @@ msgstr "Telefon" | |||
| msgid "Message" | ||||
| msgstr "Nachricht" | ||||
| 
 | ||||
| msgid "An email with the activation link has been sent to your email" | ||||
| msgstr "" | ||||
| "Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" | ||||
| 
 | ||||
| msgid "Account Activation" | ||||
| msgstr "Accountaktivierung" | ||||
| 
 | ||||
| msgid "The link to reset your email has been sent to your email" | ||||
| msgstr "Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" | ||||
| msgstr "" | ||||
| "Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet" | ||||
| 
 | ||||
| msgid "Password Reset" | ||||
| msgstr "Passwort zurücksetzen" | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ 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.urlresolvers import reverse_lazy | ||||
| from django.http import HttpResponseRedirect | ||||
| from django.utils.encoding import force_bytes | ||||
| from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode | ||||
|  | @ -63,9 +64,45 @@ class LoginViewMixin(FormView): | |||
|         return super(LoginViewMixin, self).get(request, *args, **kwargs) | ||||
| 
 | ||||
| 
 | ||||
| class ResendActivationLinkViewMixin(FormView): | ||||
|     success_message = _( | ||||
|         "An email with the activation link has been sent to your email") | ||||
| 
 | ||||
|     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): | ||||
|     # template_name = 'hosting/reset_password.html' | ||||
|     # form_class = PasswordResetRequestForm | ||||
|     success_message = _( | ||||
|         "The link to reset your email has been sent to your email") | ||||
|     site = '' | ||||
|  | @ -78,7 +115,6 @@ class PasswordResetViewMixin(FormView): | |||
|             '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 | ||||
| 
 | ||||
|  | @ -104,11 +140,8 @@ class PasswordResetViewMixin(FormView): | |||
| 
 | ||||
| 
 | ||||
| class PasswordResetConfirmViewMixin(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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue