Skip to content
Commits on Source (11)
......@@ -3,3 +3,4 @@ venv/
*__pycache__*
.vscode/
fotoblog/.env
fotoblog/media/
from django.contrib import admin
from authentication.models import User
class UserAdmin(admin.ModelAdmin):
pass
admin.site.register(User, UserAdmin)
from django.apps import AppConfig
class AuthenticationConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "authentication"
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import get_user_model
from .models import User
class LoginForm(forms.Form):
username = forms.CharField(max_length=63, label='Nom d’utilisateur')
password = forms.CharField(max_length=63, widget=forms.PasswordInput, label='Mot de passe')
class SignupForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = ('username', 'email', 'first_name', 'last_name', 'role')
class ProfilePictureForm(forms.ModelForm):
class Meta:
model = User
fields = ['profile_photo']
# Generated by Django 4.1.3 on 2022-11-14 12:15
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
]
operations = [
migrations.CreateModel(
name="User",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"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(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=150, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"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(
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(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
(
"profil_photo",
models.ImageField(upload_to="", verbose_name="Photo de profil"),
),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.permission",
verbose_name="user permissions",
),
),
],
options={
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
},
managers=[
("objects", django.contrib.auth.models.UserManager()),
],
),
]
# Generated by Django 4.1.3 on 2022-11-14 12:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentication", "0001_initial"),
]
operations = [
migrations.RemoveField(
model_name="user",
name="profil_photo",
),
migrations.AddField(
model_name="user",
name="profile_photo",
field=models.ImageField(
blank=True,
default=None,
null=True,
upload_to="",
verbose_name="Photo de profil",
),
),
migrations.AddField(
model_name="user",
name="role",
field=models.CharField(
choices=[("CREATOR", "Créateur"), ("SUBSCRIBER", "Abonné")],
default="SUBSCRIBER",
max_length=30,
verbose_name="Rôle",
),
),
]
# Generated by Django 4.1.3 on 2022-11-15 17:02
from django.db import migrations
def create_groups(apps, schema_migration):
User = apps.get_model('authentication', 'User')
Group = apps.get_model('auth', 'Group')
Permission = apps.get_model('auth', 'Permission')
add_photo = Permission.objects.get(codename='add_photo')
change_photo = Permission.objects.get(codename='change_photo')
delete_photo = Permission.objects.get(codename='delete_photo')
view_photo = Permission.objects.get(codename='view_photo')
creator_permissions = [
add_photo,
change_photo,
delete_photo,
view_photo,
]
creators = Group(name='creators')
creators.save()
creators.permissions.set(creator_permissions)
subscribers = Group(name='subscribers')
subscribers.save()
subscribers.permissions.add(view_photo)
for user in User.objects.all():
if user.role == 'CREATOR':
creators.user_set.add(user)
if user.role == 'SUBSCRIBER':
subscribers.user_set.add(user)
class Migration(migrations.Migration):
dependencies = [
("authentication", "0002_remove_user_profil_photo_user_profile_photo_and_more"),
]
operations = [migrations.RunPython(create_groups)]
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
CREATOR = 'CREATOR'
SUBSCRIBER = 'SUBSCRIBER'
ROLE_CHOICES = (
(CREATOR, 'Créateur'),
(SUBSCRIBER, 'Abonné'),
)
profile_photo = models.ImageField(verbose_name='Photo de profil',
null=True,
blank=True,
default=None)
role = models.CharField(max_length=30,
choices=ROLE_CHOICES,
verbose_name='Rôle',
default='SUBSCRIBER')
{% extends 'base.html' %}
{% block title %}Fotoblog - login{% endblock %}
{% block content %}
<h1>Login</h1>
<p>
{% include "messages_notif.html" %}
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Envoyer">
</form>
</p>
<p>Pas encore membre ? <a href="{% url 'signup' %}">Inscrivez-vous maintenant !</a></p>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block title %}Fotoblog - {{ title }}{% endblock %}
{% block content %}
<h1>{{title}}</h1>
<p>
vous êtes bien déconnecté du site {{ site_name }}
{% include "messages_notif.html" %}
</p>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block title %}Fotoblog - Photo de profil{% endblock %}
{% block content %}
<h1>Photo de profil</h1>
<p>
{% include "messages_notif.html" %}
<form method="post" enctype="multipart/form-data">
{{ form.as_p }}
{% csrf_token %}
<button type="submit" >uploader</button>
</form>
</p>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block title %}Fotoblog - Inscription{% endblock %}
{% block content %}
<h1>Inscription</h1>
<p>
{% include "messages_notif.html" %}
{% if form.errors %}
{{ form.errors }}
{% endif %}
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="S'inscrire">
</form>
</p>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block title %}Fotoblog - Changement de mot de passe{% endblock %}
{% block content %}
<h1> Changement de mot de passe</h1>
<p>
{% include "messages_notif.html" %}
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Envoyer">
</form>
</p>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block title %}Fotoblog - Changement de mot de passe effectué{% endblock %}
{% block content %}
<h1> Changement de mot de passe effectué</h1>
<p>
vous venez de changer votre mot de passe
</p>
{% endblock %}
\ No newline at end of file
from django.test import TestCase
# Create your tests here.
from django.core.exceptions import ValidationError
class ContainsLetterValidator:
def validate(self, password, user=None):
if not any(char.isalpha() for char in password):
raise ValidationError(
'Le mot de passe doit contenir une lettre', code='password_no_letters'
)
def get_help_text(self):
return 'Votre mot de passe doit contenir au moins une lettre majuscule ou minuscule.'
class ContainsNumberValidator:
def validate(self, password, user=None):
if not any(char.isdigit() for char in password):
raise ValidationError(
'Le mot de passe doit contenir au moins un chiffre', code='password_no_digits'
)
def get_help_text(self):
return 'Votre mot de passe doit contenir au moins un chiffre.'
from django.shortcuts import render, redirect
from django.conf import settings
from django.contrib import messages
from django.views.generic import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import authenticate, login, logout
from .forms import LoginForm, ProfilePictureForm, SignupForm
class LoginView(View):
context = dict()
template_name = 'authentication/login.html'
form_class = LoginForm
def get(self, request):
self.context['form'] = self.form_class()
return render(request, self.template_name, self.context)
def post(self, request):
self.context['form'] = form = self.form_class(request.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password'],
)
if user is not None:
login(request, user)
messages.add_message(request,
messages.INFO,
f'Bonjour, {user.username}! Vous êtes connecté.')
return redirect('home')
else:
messages.add_message(request,
messages.ERROR,
'Identifiants invalides.')
return render(request, self.template_name, self.context)
def logout_page(request):
logout(request)
return redirect('login')
class SignupView(View):
context = dict()
template_name = 'authentication/signup.html'
form_class = SignupForm
def get(self, request):
self.context['form'] = self.form_class()
return render(request, self.template_name, self.context)
def post(self, request):
self.context['form'] = form = self.form_class(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect(settings.LOGIN_REDIRECT_URL)
return render(request, self.template_name, self.context)
class ProfilePictureView(LoginRequiredMixin, View):
context = dict()
template_name = 'authentication/profile_upload.html'
form_class = ProfilePictureForm
def get(self, request):
self.context['form'] = self.form_class()
return render(request, self.template_name, self.context)
def post(self, request):
self.context['form'] = form = self.form_class(request.POST,
request.FILES,
instance=request.user)
if form.is_valid():
form.save()
messages.add_message(request,
messages.INFO,
'photo ajoutée avec succès')
return redirect('home')
return render(request, self.template_name, self.context)