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…
	
	Add table
		Add a link
		
	
		Reference in a new issue