User Registration & Email Authantication

Basic user registration system and email authantication.

Change-Id: Iaa4266edaf78b5c42c4aafc0de2d1f11f9f6c4f5
This commit is contained in:
Paarhati Ozkasgarli 2016-12-04 20:54:21 +00:00
parent 3da226dce3
commit d3fa9b79b4
21 changed files with 475 additions and 18 deletions

View File

@ -0,0 +1,36 @@
import re
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django import forms
class UserRegisterForm(forms.Form):
email = forms.EmailField(label='Email')
password1 = forms.CharField(
label='Password',
widget=forms.PasswordInput(),
)
password2 = forms.CharField(
label='Password (Again)',
widget=forms.PasswordInput(),
)
tos = forms.BooleanField(
required=True,
error_messages={'required': 'You must accept TOS.'}
)
def clean_email(self):
email = self.cleaned_data['email']
try:
User.objects.get(email=email)
except ObjectDoesNotExist:
return email
raise forms.ValidationError('Email address is not available.')
def clean_password2(self):
if 'password1' in self.cleaned_data:
password1 = self.cleaned_data['password1']
password2 = self.cleaned_data['password2']
if password1 == password2:
return password2
raise forms.ValidationError('Password do not match.')

View File

@ -1,5 +1,4 @@
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include, url
from django.contrib.auth import views as auth_views
from . import views
@ -8,4 +7,6 @@ urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^login/$', auth_views.login, {'template_name': 'authcp/login.html'}, name='login'),
url(r'^logout/$', auth_views.logout, name='logout'),
url(r'^register/$', views.register_user, name='register'),
url(r'^register-success/$', views.register_success, name='register-success'),
]

View File

@ -1,6 +1,82 @@
from django.shortcuts import render
import random, hashlib, datetime
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.mail import EmailMultiAlternatives
from django.template import Context
from django.template.loader import render_to_string
from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import User
from .forms import UserRegisterForm
from user_profile.models import Profile
# email sending function
def send_email(con,subject,email_to,email_from):
c = Context(con)
text_content = render_to_string('mail/user_register_welcome.txt', c)
html_content = render_to_string('mail/user_register_welcome.html', c)
email = EmailMultiAlternatives(subject,text_content,email_from)
email.attach_alternative(html_content, "text/html")
email.to = [email_to]
email.send()
def index(request):
return render(request, "authcp/index.html", {})
def register_user(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
u=User.objects.create_user(
form.cleaned_data['email'],
form.cleaned_data['email'],
form.cleaned_data['password2'],
)
u.is_active=False
u.save()
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
usernamesalt=form.cleaned_data['email']
profile=Profile.objects.get(user_id=u.id)
profile.activation_key=hashlib.sha1(salt+usernamesalt).hexdigest()
profile.key_expires=datetime.datetime.strftime(datetime.datetime.now() + datetime.timedelta(days=2),
"%Y-%m-%d %H:%M:%S")
profile.save()
send_email({'u': u, 'profil': profile},
'Welcome to our cloud',
u.email,
settings.DEFAULT_EMAIL_FROM,
)
return render(request,
'authcp/success.html',
{'u': u, 'profil': profile})
else:
print(form.errors)
else:
form = UserRegisterForm()
return render(request, 'authcp/register.html', {'form': form})
def register_success(request):
return render(request, 'authcp/success.html', {})
def activation(request, key):
activation_expired=False
already_active=False
profile=get_object_or_404(Profile, activation_key=key)
if profile.user.is_active == False:
if timezone.now() > profile.key_expires:
# Display: offer the user to send a new activation link
activation_expired=True
id_user=profile.user.id
# Activation successful
else:
profile.user.is_active=True
profile.user.save()
# If user is already active, simply display error message
else:
# Display : error message
already_active=True
return render(request, 'authcp/activation.html', locals())

View File

@ -27,7 +27,7 @@ DEBUG = True
ALLOWED_HOSTS = [
'dash-stack',
'198.211.127.189',
'127.0.0.1',
]
# login url
@ -39,6 +39,9 @@ LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/auth/login/'
# user profile
AUTH_PROFILE_MODULE = 'user_profile.Profile'
# Application definition
INSTALLED_APPS = [
@ -82,6 +85,7 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django_settings_export.settings_export',
],
},
},
@ -152,4 +156,21 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
STATIC_URL = '/static/'
STATIC_URL = '/static/'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# Host for sending e-mail.
EMAIL_HOST = 'localhost'
# Port for sending e-mail.
EMAIL_PORT = 25
# Optional SMTP authentication information for EMAIL_HOST.
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
DEFAULT_EMAIL_FROM = 'admin@dash-stack.org'
# fullt qualified hostname or domain. Ex <http://domain.tld/>
SITE_ROOT_URL = 'http://198.211.127.189/'

View File

@ -3,3 +3,4 @@ Django==1.10.3
mysqlclient==1.3.9
oslo.i18n==3.10.0
requests==2.12.1
django-settings-export==1.2.1

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,22 @@
{% extends "base_headless.html" %}
{% block title %}<title>dash-stack | You have been activated </title>{% endblock title %}
{% block content %}
<div class="register-box">
<div class="register-logo">
<a href="/"><b> - </b>stack</a>
</div>
<div class="login-box-body">
<p class="lead">
Your email address has authanticated and
your user has been activated.
</p>
<a href="/" class="text-center">Let's go back to home page.</a><br />
<a href="/auth/login/" class="text-center">Take me to login page.</a>
</div>
</div>
{% endblock content %}

View File

@ -1,8 +1,9 @@
{% extends "base_headless.html" %}
{% block auth %}
{% block title %}<title>dash-stack | Log in</title>{% endblock title %}
{% block content %}
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<a href="{{ SITE_URL }}"><b> - </b>stack</a>
@ -12,11 +13,14 @@
<p class="login-box-msg">Sign in to start your session</p>
<form action="/auth/login/" method="POST">
{% csrf_token %}
<p class="text-red"> {{ form.non_field_errors.as_text }} </p>
<div class="form-group has-feedback">
<span class="text-red"> {{ form.errors.username.as_text }} </span>
<input type="email" name="username" class="form-control" placeholder="Email">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<span class="text-red"> {{ form.errors.password.as_text }} </span>
<input type="password" name="password" class="form-control" placeholder="Password">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
@ -24,7 +28,7 @@
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox"> Remember Me
<input name="remember_me" type="checkbox"> Remember Me
</label>
</div>
</div>
@ -46,10 +50,10 @@
<!-- /.social-auth-links -->
<a href="#">I forgot my password</a><br>
<a href="register.html" class="text-center">Register a new membership</a>
<a href="/auth/register" class="text-center">Register a new membership</a>
</div>
<!-- /.login-box-body -->
</div>
<!-- /.login-box -->
{% endblock auth %}
{% endblock content %}

View File

@ -0,0 +1,62 @@
{% extends "base_headless.html" %}
{% block title %}<title>dash-stack | Register </title>{% endblock title %}
{% block content %}
<div class="register-box">
<div class="register-logo">
<a href="{{ SITE_URL }}"><b> - </b>stack</a>
</div>
<div class="register-box-body">
<p class="login-box-msg">Register a new membership</p>
<form action="/auth/register/" method="POST">
<span class="text-red"> {{ form.errors.email.as_text }} </span>
<span class="text-red"> {{ form.errors.username.as_text }} </span>
<div class="form-group has-feedback">
<input name="email" type="email" class="form-control" placeholder="Email">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<span class="text-red"> {{ form.errors.password1.as_text }} </span>
<div class="form-group has-feedback">
<input name="password1" type="password" class="form-control" placeholder="Password">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<span class="text-red"> {{ form.errors.password2.as_text }} </span>
<div class="form-group has-feedback">
<input name="password2" type="password" class="form-control" placeholder="Retype password">
<span class="glyphicon glyphicon-log-in form-control-feedback"></span>
</div>
<div class="row">
<span class="text-red" style="margin-left: 15px;"> {{ form.errors.tos.as_text }} </span>
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input name="tos" type="checkbox"> I agree to the <a href="#">terms</a>
</label>
</div>
</div>
<!-- /.col -->
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">Register</button>
</div>
<!-- /.col -->
</div>
{% csrf_token %}
</form>
<div class="social-auth-links text-center">
<p>- OR -</p>
<a href="#" class="btn btn-block btn-social btn-facebook btn-flat"><i class="fa fa-facebook"></i> Sign up using
Facebook</a>
<a href="#" class="btn btn-block btn-social btn-google btn-flat"><i class="fa fa-google-plus"></i> Sign up using
Google+</a>
</div>
<a href="/auth/login" class="text-center">I already have a membership</a>
</div>
<!-- /.form-box -->
</div>
<!-- /.register-box -->
{% endblock content %}

View File

@ -0,0 +1,25 @@
{% extends "base_headless.html" %}
{% block title %}<title>dash-stack | Register </title>{% endblock title %}
{% block content %}
<div class="register-box">
<div class="register-logo">
<a href="/"><b> - </b>stack</a>
</div>
{{ u.get_profile.activation_key }} <br>
{{ profile }}
<div class="login-box-body">
<p class="lead">
Thank you for registering a new account with us.
Please check your email for information.
</p>
<a href="/" class="text-center">Let's go back to home page.</a><br />
<a href="/auth/login/" class="text-center">Take me to login page.</a>
</div>
</div>
{% endblock content %}

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 2 | Log in</title>
{% block title %}<title>AdminLTE 2 | Log in</title>{% endblock title %}
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.6 -->
@ -24,9 +24,10 @@
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
{% block auth %}
<body class="hold-transition login-page">
{% block content %}
{% endblock auth %}
{% endblock content %}
<!-- jQuery 2.2.3 -->
<script src="/static/AdminLTE/plugins/jQuery/jquery-2.2.3.min.js"></script>

View File

@ -0,0 +1,20 @@
<html>
<head></head>
<body>
<p>Hello,</p>
<p>Welcome to our cloud platform.</p>
<h3>Activate your email:</h3>
Please click on following link to activate your account:
<p>
<a href="{{ settings.SITE_ROOT_URL }}{{ profile.activation_key }}">
{{ profile.activation_key }}
</a>
</p>
</body>
</html>

View File

@ -0,0 +1,6 @@
Hello,
Welcome to our cloud platform.
Activare your email:

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-09 21:25
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('user_profile', '0002_auto_20161201_2120'),
]
operations = [
migrations.AddField(
model_name='profile',
name='activation_key',
field=models.CharField(default='', max_length=64),
),
migrations.AddField(
model_name='profile',
name='key_expires',
field=models.DateTimeField(default=django.utils.timezone.now),
preserve_default=False,
),
]

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-10 18:57
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('user_profile', '0003_auto_20161209_2125'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='user',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-10 19:14
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('user_profile', '0004_auto_20161210_1857'),
]
operations = [
migrations.AlterModelOptions(
name='profile',
options={'ordering': ('user',), 'verbose_name': 'Profile', 'verbose_name_plural': 'Profiles'},
),
migrations.AlterField(
model_name='profile',
name='activation_key',
field=models.CharField(max_length=64, null=True),
),
migrations.AlterField(
model_name='profile',
name='key_expires',
field=models.DateTimeField(null=True),
),
migrations.AlterField(
model_name='profile',
name='provider_password',
field=models.CharField(max_length=50, null=True),
),
migrations.AlterField(
model_name='profile',
name='selected_provider',
field=models.IntegerField(null=True),
),
migrations.AlterField(
model_name='profile',
name='user',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL, verbose_name='user'),
preserve_default=False,
),
]

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-10 19:15
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('user_profile', '0005_auto_20161210_1914'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='key_expires',
field=models.DateTimeField(default=django.utils.timezone.now),
preserve_default=False,
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-10 19:16
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user_profile', '0006_auto_20161210_1915'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='key_expires',
field=models.DateTimeField(null=True),
),
]

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-12-10 19:17
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('user_profile', '0007_auto_20161210_1916'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='user',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL, verbose_name='user'),
),
]

View File

@ -1,14 +1,35 @@
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.dispatch import receiver
from django.db.models.signals import post_save
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE
settings.AUTH_USER_MODEL,
related_name='profile',
verbose_name=('user'),
null=True,
blank=True,
)
avatar = models.FileField(upload_to='static/avatar/%Y-%m-%d')
provider_password = models.CharField(max_length=50)
selected_provider = models.IntegerField()
provider_password = models.CharField(max_length=50,null=True)
selected_provider = models.IntegerField(null=True)
activation_key = models.CharField(max_length=64,null=True)
key_expires = models.DateTimeField(null=True)
class Meta:
verbose_name=('Profile')
verbose_name_plural=('Profiles')
ordering=('user',)
def __str__(self):
return self.user.username
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_profile_for_new_user(sender, created, instance, **kwargs):
if created:
profile = Profile(user=instance)
profile.save()