Basic auth system

This commit is contained in:
Skia 2015-11-18 17:09:06 +01:00
parent 5bd40b2ec4
commit 619e27eb52
11 changed files with 232 additions and 57 deletions

View File

@ -1,4 +1,8 @@
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django import forms
from django.contrib.auth import logout, login, authenticate
import logging
from .models import User from .models import User
class RegisteringForm(UserCreationForm): class RegisteringForm(UserCreationForm):
@ -6,4 +10,36 @@ class RegisteringForm(UserCreationForm):
required_css_class = 'required' required_css_class = 'required'
class Meta: class Meta:
model = User model = User
fields = ('username', 'email',) fields = ('first_name', 'last_name', 'email')
def save(self, commit=True):
user = super(RegisteringForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.generate_username()
if commit:
user.save()
return user
class LoginForm(AuthenticationForm):
def login(self):
u = authenticate(username=self.request.POST['username'],
password=self.request.POST['password'])
if u is not None:
if u.is_active:
login(self.request, u)
logging.debug("Logging in "+u)
else:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='inactive',
params={'username': self.username_field.verbose_name},
)
else:
logging.debug("Login failed")
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name},
)

View File

@ -2,9 +2,9 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import django.utils.timezone
import django.core.validators import django.core.validators
import django.contrib.auth.models import django.contrib.auth.models
import django.utils.timezone
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -17,25 +17,25 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='User', name='User',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True, serialize=False)), ('id', models.AutoField(primary_key=True, auto_created=True, verbose_name='ID', serialize=False)),
('password', models.CharField(max_length=128, verbose_name='password')), ('password', models.CharField(verbose_name='password', max_length=128)),
('last_login', models.DateTimeField(blank=True, verbose_name='last login', null=True)), ('last_login', models.DateTimeField(null=True, blank=True, verbose_name='last login')),
('is_superuser', models.BooleanField(verbose_name='superuser status', default=False, help_text='Designates that this user has all permissions without explicitly assigning them.')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], verbose_name='username', max_length=30, error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.')), ('username', models.CharField(validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], help_text='Required. 254 characters or fewer. Letters, digits and @/./+/-/_ only.', error_messages={'unique': 'A user with that username already exists.'}, verbose_name='username', unique=True, max_length=254)),
('first_name', models.CharField(max_length=30, blank=True, verbose_name='first name')), ('first_name', models.CharField(verbose_name='first name', max_length=30)),
('last_name', models.CharField(max_length=30, blank=True, verbose_name='last name')), ('last_name', models.CharField(verbose_name='last name', max_length=30)),
('email', models.EmailField(max_length=254, blank=True, verbose_name='email address')), ('email', models.EmailField(verbose_name='email address', unique=True, max_length=254)),
('is_staff', models.BooleanField(verbose_name='staff status', default=False, help_text='Designates whether the user can log into this admin site.')), ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(verbose_name='active', default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.')), ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(verbose_name='date joined', default=django.utils.timezone.now)), ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('nick_name', models.CharField(max_length=30)), ('date_of_birth', models.DateTimeField(verbose_name='date of birth')),
('groups', models.ManyToManyField(related_query_name='user', related_name='user_set', verbose_name='groups', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.')), ('nick_name', models.CharField(blank=True, max_length=30)),
('user_permissions', models.ManyToManyField(related_query_name='user', related_name='user_set', verbose_name='user permissions', to='auth.Permission', blank=True, help_text='Specific permissions for this user.')), ('groups', models.ManyToManyField(related_query_name='user', help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', blank=True, to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(related_query_name='user', help_text='Specific permissions for this user.', related_name='user_set', blank=True, to='auth.Permission', verbose_name='user permissions')),
], ],
options={ options={
'verbose_name': 'user',
'verbose_name_plural': 'users', 'verbose_name_plural': 'users',
'abstract': False, 'verbose_name': 'user',
}, },
managers=[ managers=[
('objects', django.contrib.auth.models.UserManager()), ('objects', django.contrib.auth.models.UserManager()),

View File

@ -1,15 +1,100 @@
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager
from django.utils.translation import ugettext_lazy as _
from django.core import validators
from django.utils import timezone
import logging class User(AbstractBaseUser, PermissionsMixin):
"""
Defines the base user class, useable in every app
logging.basicConfig(level=logging.DEBUG) This is almost the same as the auth module AbstractUser since it inherits from it,
but some fields are required, and the username is generated automatically with the
name of the user (see generate_username()).
class User(AbstractUser): Added field: nick_name
nick_name = models.CharField(max_length=30) Required fields: email, first_name, last_name, date_of_birth
"""
username = models.CharField(
_('username'),
max_length=254,
unique=True,
help_text=_('Required. 254 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[
validators.RegexValidator(
r'^[\w.@+-]+$',
_('Enter a valid username. This value may contain only '
'letters, numbers ' 'and @/./+/-/_ characters.')
),
],
error_messages={
'unique': _("A user with that username already exists."),
},
)
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30)
email = models.EmailField(_('email address'), unique=True)
date_of_birth = models.DateTimeField(_('date of birth'), default="1970-01-01")
nick_name = models.CharField(max_length=30, blank=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'first_name', 'last_name']
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def __str__(self): def __str__(self):
return self.get_username() return self.username
def get_full_name(self):
"""
Returns the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"Returns the short name for the user."
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
"""
Sends an email to this User.
"""
send_mail(subject, message, from_email, [self.email], **kwargs)
def generate_username(self):
"""
Generates a unique username based on the first and last names.
For example: Guy Carlier gives gcarlier, and gcarlier1 if the first one exists
Returns the generated username
"""
user_name = str(self.first_name[0]+self.last_name).lower()
un_set = [u.username for u in User.objects.all()]
if user_name in un_set:
i = 1
while user_name+str(i) in un_set:
i += 1
user_name += str(i)
self.username = user_name
return user_name
class Page: class Page:
pass pass

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}Bienvenue sur le Sith de l'AE!{% endblock %}</title>
</head>
<body>
<header>
{% block header %}
{% if user %}Hello, {{ user.username }}!{% endif %}
<ul>
<li><a href="{% url 'core:register' %}">Register</a></li>
<li><a href="{% url 'core:login' %}">Login</a></li>
<li><a href="{% url 'core:logout' %}">Logout</a></li>
</ul>
{% endblock %}
</header>
<div id="content">
{% block content %}{% endblock %}
</div>
<footer>
{% block footer %}
Site réalisé par des gens biens
{% endblock %}
</footer>
</body>
</html>

View File

@ -0,0 +1 @@
{% extends "sith/base.html" %}

View File

@ -0,0 +1,14 @@
{% extends "core/base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<form action="{% url 'core:login' %}" method="post">
{% csrf_token %}
{{ form }}
<p><input type="submit" value="Login!" /></p>
</form>
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends "core/base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<form action="{% url 'core:register' %}" method="post">
{% csrf_token %}
{{ form }}
<p><input type="submit" value="Register!" /></p>
</form>
{% endblock %}

View File

@ -1,13 +0,0 @@
<h1>Register a user</h1>
{% if username %}
You registered successfully, {{ username }}!
{% endif %}
<form action="{% url 'sith:register' %}" method="post">
{% csrf_token %}
<ul>
{{ form }}
<li><input type="submit" value="Register!" /></li>
</ul>
</form>

View File

@ -3,9 +3,9 @@ from django.conf.urls import url
from . import views from . import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.index, name='core_index'), url(r'^$', views.index, name='index'),
url(r'^login$', views.login, name='login'), url(r'^login$', views.login, name='login'),
url(r'^logout$', views.logout, name='logout'),
url(r'^register$', views.register, name='register'), url(r'^register$', views.register, name='register'),
url(r'^guy$', views.guy, name='guy'),
] ]

View File

@ -1,8 +1,9 @@
from django.shortcuts import render from django.shortcuts import render, redirect
from django.http import HttpResponse from django.http import HttpResponse
from django.contrib.auth import logout as auth_logout
from .models import User from .models import User
from .forms import RegisteringForm from .forms import RegisteringForm, LoginForm
import logging import logging
@ -11,22 +12,30 @@ logging.basicConfig(level=logging.DEBUG)
def index(request): def index(request):
return HttpResponse("Hello, world. You're at the core index.") return HttpResponse("Hello, world. You're at the core index.")
def login(request):
return HttpResponse("Login page")
def register(request): def register(request):
if request.method == 'POST': if request.method == 'POST':
logging.debug("Registering "+request.POST['username'])
form = RegisteringForm(request.POST) form = RegisteringForm(request.POST)
if form.is_valid(): if form.is_valid():
u = User(username=request.POST['username'], password=request.POST['password1'], email="guy@plop.guy") logging.debug("Registering "+form.cleaned_data['first_name']+form.cleaned_data['last_name'])
u.save() u = form.save()
return render(request, "sith/register.html", {'username': u.get_username(),
'form': RegisteringForm().as_ul()})
else:
return render(request, "sith/register.html", {'form': form.as_ul()})
form = RegisteringForm() form = RegisteringForm()
return render(request, "sith/register.html", {'form': form.as_ul()}) else:
form = RegisteringForm()
return render(request, "core/register.html", {'title': 'Register a user', 'form': form.as_p()})
def guy(request): def login(request):
return HttpResponse("Guyuguyguygé") if request.method == 'POST':
try:
form = LoginForm(request)
form.login()
# TODO redirect to profile when done
return redirect('index')
except Exception as e:
logging.debug(e)
else:
form = LoginForm()
return render(request, "core/login.html", {'title': 'Login', 'form': form.as_p()})
def logout(request):
auth_logout(request)
return redirect('core:index')

View File

@ -17,6 +17,6 @@ from django.conf.urls import include, url
from django.contrib import admin from django.contrib import admin
urlpatterns = [ urlpatterns = [
url(r'^', include('core.urls', namespace="sith")), url(r'^', include('core.urls', namespace="core")),
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
] ]