Compare commits

...

7 Commits

Author SHA1 Message Date
9d8476ebb8 fix: import logout in login.py 2023-11-03 21:33:48 +01:00
AdrienLSH
16c47b47cf doc: switch to django branch 2023-10-31 21:38:34 +01:00
827743bb96 doc: add installation man 2023-10-31 21:26:17 +01:00
a0c0d813b6 register: use ModelForm, and print all errors 2023-10-31 21:14:24 +01:00
54cc1b1705 profiles: init 2023-10-29 21:09:38 +01:00
246213c5b8 core: add anotation type 2023-10-29 21:00:18 +01:00
e253631f09 core: reformat file tree 2023-10-25 16:50:05 +02:00
61 changed files with 472 additions and 452 deletions

View File

@ -1,4 +1,4 @@
.env
*.pyc
db.sqlite3
**/migrations/*
**/migrations/**

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# BACKEND
## Installation
- Clone the project:
``` bash
git clone https://git.chauvet.pro/michel/ft_transcendence
cd ft_transcendence
git switch django
```
- Create python virtual environnement.
``` bash
python3 -m venv .env
```
- Source the environnement.
``` bash
source .env/bin/activate
```
- Install the requirements
``` bash
pip install -r requirements.txt
```
- Start the developpement server
```
python manage.py runserver 0.0.0.0:8000
```

View File

@ -0,0 +1,10 @@
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from ..status_code import *
class ChangePasswordForm(forms.Form):
new_password = forms.CharField(required=True, error_messages = {
'required': PASSWORD_MISSING,
})

15
accounts/forms/login.py Normal file
View File

@ -0,0 +1,15 @@
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.db.models.query import QuerySet
from django.core.exceptions import ValidationError
from ..status_code import *
class LoginForm(forms.Form):
username = forms.CharField(required=True, error_messages={
'required': USERNAME_MISSING,
})
password = forms.CharField(required=True, error_messages = {
'required': PASSWORD_MISSING,
})

View File

@ -0,0 +1,22 @@
from django.forms import ModelForm
from django.contrib.auth.models import User
from ..status_code import *
class RegisterForm(ModelForm):
class Meta:
model = User
fields = ['username', 'password']
error_messages = {
'username': {
'max_length': USERNAME_TOO_LONG,
'min_length': USERNAME_TOO_SHORT,
'required': USERNAME_MISSING,
'unique': USERNAME_ALREADY_USED,
},
'password': {
'max_length': PASSWORD_TOO_LONG,
'min_length': PASSWORD_TOO_SHORT,
'required': PASSWORD_MISSING,
}
}

18
accounts/status_code.py Normal file
View File

@ -0,0 +1,18 @@
USERNAME_TOO_LONG: str = "error: username too long"
USERNAME_TOO_SHORT: str = "error: username too short"
USERNAME_MISSING: str = "error: username is missing"
PASSWORD_TOO_LONG: str = "error: password too long"
PASSWORD_TOO_SHORT: str = "error: password too short"
PASSWORD_MISSING: str = "error: password is missing"
USERNAME_ALREADY_USED: str = "error: username already used"
USER_ALREADY_LOGGED: str = "error: user already logged"
USER_INVALID: str = "error: username or password invalid"
USER_ADDED: str = "ok: user added"
USER_DELETED: str = "ok: account has been deleted"
USER_LOGGED: str = "ok: account valid"
USER_PASSWORD_UPDATED: str = "ok: password has been updated"
USER_LOGOUT: str = "ok: user logout"
METHOD_INVALID: str = "error: method invalid"

View File

@ -0,0 +1,7 @@
<html>
<form method='post'>
{% csrf_token %}
{{form.as_p}}
<input type='submit'>
</form>
</html>

View File

@ -1,7 +1,7 @@
<html>
<form method='post'>
{% csrf_token %}
{{ form }}
{{ form.as_p }}
<input type='submit'>
</form>
</html>

View File

@ -1,7 +1,7 @@
<html>
<form method='post'>
{% csrf_token %}
{{ form }}
{{ form.as_p }}
<input type='submit'>
</form>
</html>

View File

@ -0,0 +1,33 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.http import HttpResponse
from django.contrib.auth.models import User
import uuid
from ..status_code import *
class ChangePasswordTest(TestCase):
def setUp(self):
self.client = Client()
self.url = "/api/accounts/change_password"
self.username: str = str(uuid.uuid4())
self.password: str = str(uuid.uuid4())
self.new_password: str = str(uuid.uuid4())
User.objects.create_user(username = self.username, password = self.password)
def test_normal(self):
self.client.login(username = self.username, password = self.password)
response: HttpResponse = self.client.post(self.url, {"new_password": self.new_password})
response_text: str = response.content.decode('utf-8')
self.assertEqual(response_text, USER_PASSWORD_UPDATED)
def test_nologged(self):
response: HttpResponse = self.client.post(self.url, {"new_password": self.new_password})
response_text: str = response.content.decode('utf-8')
self.assertEqual(response_text, '')

34
accounts/tests/delete.py Normal file
View File

@ -0,0 +1,34 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.http import HttpResponse
from django.contrib.auth.models import User
import uuid
from ..status_code import *
class DeleteTest(TestCase):
def setUp(self):
self.client = Client()
self.url = "/api/accounts/delete"
self.username: str = str(uuid.uuid4())
self.password: str = str(uuid.uuid4())
user: User = User.objects.create_user(username=self.username, password=self.password)
self.client.login(username=self.username, password=self.password)
def test_normal_delete(self):
response: HttpResponse = self.client.post(self.url)
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, USER_DELETED)
def test_no_logged(self):
self.client.logout()
response: HttpResponse = self.client.post(self.url)
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, '')

56
accounts/tests/login.py Normal file
View File

@ -0,0 +1,56 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.contrib.auth.models import User
from django.http import HttpResponse
import uuid
from ..status_code import *
class LoginTest(TestCase):
def setUp(self):
self.client = Client()
self.url = "/api/accounts/login"
self.username: str = str(uuid.uuid4())
self.password: str = str(uuid.uuid4())
User.objects.create_user(username=self.username, password=self.password)
def test_normal_login(self):
#User(username=self.username, password=self.password).save()
response: HttpResponse = self.client.post(self.url, {'username': self.username, 'password': self.password})
response_text = response.content.decode('utf-8')
self.assertEqual(response_text, USER_LOGGED)
def test_invalid_username(self):
response: HttpResponse = self.client.post(self.url, {"username": self.password, "password": self.password})
errors: dict = eval(response.content)
errors_expected: dict = {'user': [USER_INVALID]}
self.assertEqual(errors, errors_expected)
def test_invalid_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.username})
errors: dict = eval(response.content)
errors_expected: dict = {'user': [USER_INVALID]}
self.assertEqual(errors, errors_expected)
def test_invalid_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
errors: dict = eval(response.content)
errors_expected: dict = {'username': [USERNAME_MISSING]}
self.assertEqual(errors, errors_expected)
def test_invalid_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
errors: dict = eval(response.content)
errors_expected: dict = {'password': [PASSWORD_MISSING]}
self.assertEqual(errors, errors_expected)
def test_invalid_no_password_no_username(self):
response: HttpResponse = self.client.post(self.url, {})
errors: dict = eval(response.content)
errors_expected: dict = {'username': [USERNAME_MISSING], 'password': [PASSWORD_MISSING]}
self.assertEqual(errors, errors_expected)

View File

@ -0,0 +1,54 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.contrib.auth.models import User
from django.http import HttpResponse
import uuid
from ..status_code import *
class RegisterTest(TestCase):
def setUp(self):
self.client = Client()
self.url: str = "/api/accounts/register"
self.username: str = str(uuid.uuid4())
self.password: str = str(uuid.uuid4())
def test_normal_register(self):
response: HttpResponse = self.client.post(self.url, {'username': self.username, 'password': self.password})
response_text: str = response.content.decode('utf-8')
self.assertEqual(USER_ADDED, response_text)
def test_incomplet_form_no_username_no_password(self):
response: HttpResponse = self.client.post(self.url)
errors: dict = eval(response.content)
errors_expected: dict = {'username': [USERNAME_MISSING], 'password': [PASSWORD_MISSING]}
self.assertEqual(errors, errors_expected)
def test_incomplet_form_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
errors: dict = eval(response.content)
errors_expected: dict = {'password': [PASSWORD_MISSING]}
self.assertEqual(errors, errors_expected)
def test_incomplet_form_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
errors: dict = eval(response.content)
errors_expected: dict = {}
self.assertEqual(errors, errors_expected)
def test_incomplet_form_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
errors: dict = eval(response.content)
errors_expected: dict = {'username': [USERNAME_MISSING]}
self.assertEqual(errors, errors_expected)
def test_already_registered(self):
User(username=self.username, password=self.password).save()
response: HttpResponse = self.client.post(self.url, {'username': self.username, 'password': self.password})
errors: dict = eval(response.content)
errors_expected: dict = {'username': [USERNAME_ALREADY_USED]}
self.assertEqual(errors, errors_expected)

View File

@ -1,9 +1,10 @@
from django.urls import path
from .views import login, register, delete, change_password
from .views import login, logout, register, delete, change_password
urlpatterns = [
path("login", login.LoginView.as_view(), name="login"),
path("logout", logout.LogoutView.as_view(), name="logout"),
path("register", register.RegisterView.as_view(), name="register"),
path("delete", delete.DeleteView.as_view(), name="delete"),
path("change_password", change_password.ChangePasswordView.as_view(), name="change_password"),

View File

@ -0,0 +1,29 @@
from django.shortcuts import render
from django.views import View
from django.http import JsonResponse, HttpResponse, HttpRequest
from django.contrib.auth.models import User
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from ..forms.change_password import ChangePasswordForm
from ..status_code import *
class ChangePasswordView(View):
def get(self, request: HttpRequest):
return render(request, "change_password.html", ChangePasswordForm)
@method_decorator(login_required, name='dispatch')
def post(self, request: HttpRequest):
form: ChangePasswordForm = ChangePasswordForm(request.POST)
if not form.is_valid():
return JsonResponse(form.errors)
new_password: str = form.cleaned_data['new_password']
user: User = request.user
user.set_password(new_password)
user.save()
return HttpResponse(USER_PASSWORD_UPDATED)

19
accounts/views/delete.py Normal file
View File

@ -0,0 +1,19 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from ..status_code import *
class DeleteView(View):
@method_decorator(login_required, name='dispatch')
def get(self, request: HttpRequest):
return HttpResponse(METHOD_INVALID)
@method_decorator(login_required, name='dispatch')
def post(self, request: HttpRequest):
request.user.delete()
return HttpResponse(USER_DELETED)

31
accounts/views/login.py Normal file
View File

@ -0,0 +1,31 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest, JsonResponse
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.db.models.query import QuerySet
from ..status_code import *
from ..forms.login import LoginForm
class LoginView(View):
def get(self, request: HttpRequest):
if request.user.is_authenticated:
logout(request)
return render(request, "login.html", {"form": LoginForm})
def post(self, request: HttpRequest):
if request.user.is_authenticated:
logout(request)
form: LoginForm = LoginForm(request.POST)
if not form.is_valid():
return JsonResponse(form.errors)
user: User = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
if user is None:
return JsonResponse({'user': [USER_INVALID]})
login(request, user)
return HttpResponse(USER_LOGGED)

15
accounts/views/logout.py Normal file
View File

@ -0,0 +1,15 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest
from django.contrib.auth import logout
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from ..status_code import *
class LogoutView(View):
@method_decorator(login_required, name='dispatch')
def get(self, request: HttpRequest):
logout(request)
return HttpResponse(USER_LOGOUT)

View File

@ -0,0 +1,32 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest, JsonResponse
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.db.models.query import QuerySet
from django.contrib.auth.decorators import user_passes_test
from ..status_code import *
from ..forms.register import RegisterForm
class RegisterView(View):
def get(self, request: HttpRequest):
if request.user.is_authenticated:
logout(request)
return render(request, 'register.html', {'form': RegisterForm})
def post(self, request: HttpRequest):
if request.user.is_authenticated:
logout(request)
form: RegisterForm = RegisterForm(request.POST)
if not form.is_valid():
return JsonResponse(form.errors)
user: User = User.objects.create_user(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
login(request, user)
return HttpResponse(USER_ADDED)

View File

@ -1,7 +0,0 @@
from django import forms
from ..settings import *
class ChangePasswordForm(forms.Form):
username = forms.CharField(label="username", max_length=USERNAME_MAX_SIZE, min_length=USERNAME_MIN_SIZE, required=True)
current_password = forms.CharField(label="current_password", max_length=PASSWORD_MAX_SIZE, min_length=PASSWORD_MIN_SIZE, required=True)
new_password = forms.CharField(label="new_password", max_length=PASSWORD_MAX_SIZE, min_length=PASSWORD_MIN_SIZE, required=True)

View File

@ -1,6 +0,0 @@
from django import forms
from ..settings import *
class DeleteForm(forms.Form):
username = forms.CharField(label="username", max_length=USERNAME_MAX_SIZE, min_length=USERNAME_MIN_SIZE, required=True)
password = forms.CharField(label="password", max_length=PASSWORD_MAX_SIZE, min_length=PASSWORD_MIN_SIZE, required=True)

View File

@ -1,6 +0,0 @@
from django import forms
from ..settings import *
class LoginForm(forms.Form):
username = forms.CharField(label="username", max_length=USERNAME_MAX_SIZE, min_length=USERNAME_MIN_SIZE, required=True)
password = forms.CharField(label="password", max_length=PASSWORD_MAX_SIZE, min_length=PASSWORD_MIN_SIZE, required=True)

View File

@ -1,6 +0,0 @@
from django import forms
from ..settings import *
class RegisterForm(forms.Form):
username = forms.CharField(label="username", max_length=USERNAME_MAX_SIZE, min_length=USERNAME_MIN_SIZE, required=True)
password = forms.CharField(label="password", max_length=PASSWORD_MAX_SIZE, min_length=PASSWORD_MIN_SIZE, required=True)

View File

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View File

@ -1,4 +0,0 @@
PASSWORD_MIN_SIZE = 3
PASSWORD_MAX_SIZE = 128
USERNAME_MIN_SIZE = 3
USERNAME_MAX_SIZE = 40

View File

@ -1,9 +0,0 @@
INVALID_USERNAME: str = "error: username invalid"
INVALID_PASSWORD: str = "error: password invalid"
INVALID_USERNAME_PASSWORD: str = "error: username or password invalid"
USERNAME_ALREADY_USED: str = "error: username already used"
USER_ADDED: str = "ok: user added"
USER_DELETED: str = "ok: account has been deleted"
USER_VALID: str = "ok: account valid"
PASSWORD_UPDATED: str = "ok: password has been updated"

View File

@ -1,9 +0,0 @@
<html>
<form method='post'>
{% csrf_token %}
<input type="text" name="username" placeholder="username">
<input type="text" name="current_password" placeholder="current_password">
<input type="text" name="new_password" placeholder="new_password">
<input type='submit'>
</form>
</html>

View File

@ -1,76 +0,0 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.http import HttpResponse
import uuid
from ..status_code import *
from ..settings import *
class ChangePasswordTest(TestCase):
def setUp(self):
self.client = Client()
self.url = "/api/accounts/change_password"
self.username: str = str(uuid.uuid4())[:USERNAME_MAX_SIZE]
self.password: str = str(uuid.uuid4())[:PASSWORD_MAX_SIZE]
self.new_password: str = str(uuid.uuid4())[:PASSWORD_MAX_SIZE]
self.client.post("/api/accounts/register", {"username": self.username, "password": self.password})
def test_normal_login(self):
response: HttpResponse = self.client.post("/api/accounts/login", {"username": self.username, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, USER_VALID)
def test_invalid_username(self):
response: HttpResponse = self.client.post(self.url, {"username": self.password, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password_no_username(self):
response: HttpResponse = self.client.post(self.url, {})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_no_new_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "current_password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_new_password_to_short(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "current_password": self.password, "new_password": "a" * (PASSWORD_MIN_SIZE - (PASSWORD_MIN_SIZE > 0))})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_new_password_to_long(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "current_password": self.password, "new_password": "a" * (PASSWORD_MAX_SIZE + 1)})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_normal_change_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "current_password": self.password, "new_password": self.new_password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, PASSWORD_UPDATED)

View File

@ -1,55 +0,0 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.http import HttpResponse
import uuid
from ..status_code import *
from ..settings import *
class DeleteTest(TestCase):
def setUp(self):
self.client = Client()
self.url = "/api/accounts/delete"
self.username: str = str(uuid.uuid4())[:USERNAME_MAX_SIZE]
self.password: str = str(uuid.uuid4())[:PASSWORD_MAX_SIZE]
self.client.post("/api/accounts/register", {"username": self.username, "password": self.password})
def test_invalid_username(self):
response: HttpResponse = self.client.post(self.url, {"username": self.password, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password_no_username(self):
response: HttpResponse = self.client.post(self.url, {})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_normal_delete(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, USER_DELETED)

View File

@ -1,50 +0,0 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.http import HttpResponse
import uuid
from ..status_code import *
from ..settings import *
class LoginTest(TestCase):
def setUp(self):
self.client = Client()
self.url = "/api/accounts/login"
self.username: str = str(uuid.uuid4())[:USERNAME_MAX_SIZE]
self.password: str = str(uuid.uuid4())[:PASSWORD_MAX_SIZE]
self.client.post("/api/accounts/register", {"username": self.username, "password": self.password})
def test_normal_login(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, USER_VALID)
def test_invalid_username(self):
response: HttpResponse = self.client.post(self.url, {"username": self.password, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_invalid_no_password_no_username(self):
response: HttpResponse = self.client.post(self.url, {})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)

View File

@ -1,69 +0,0 @@
from django.test import TestCase
# Create your tests here.
from django.test.client import Client
from django.http import HttpResponse
import uuid
from ..status_code import *
from ..settings import *
class RegisterTest(TestCase):
def setUp(self):
self.client = Client()
self.url: str = "/api/accounts/register"
self.username: str = str(uuid.uuid4())[:USERNAME_MAX_SIZE]
self.password: str = str(uuid.uuid4())[:PASSWORD_MAX_SIZE]
def test_incomplet_form_no_username_no_password(self):
response: HttpResponse = self.client.post(self.url)
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_incomplet_form_no_password(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_incomplet_form_no_username(self):
response: HttpResponse = self.client.post(self.url, {"password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, "error: username invalid")
def test_incomplet_form_no_username(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_normal_register(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, USER_ADDED)
def test_username_too_short(self):
response: HttpResponse = self.client.post(self.url, {"username": "a" * (USERNAME_MIN_SIZE - (USERNAME_MIN_SIZE > 0)), "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_username_too_long(self):
response: HttpResponse = self.client.post(self.url, {"username": "a" * (USERNAME_MAX_SIZE + 1), "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_password_too_short(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": "a" * (PASSWORD_MIN_SIZE - (PASSWORD_MIN_SIZE > 0))})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_password_too_long(self):
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": "a" * (PASSWORD_MAX_SIZE + 1)})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, INVALID_USERNAME_PASSWORD)
def test_already_registered(self):
self.client.post(self.url, {"username": self.username, "password": self.password})
response: HttpResponse = self.client.post(self.url, {"username": self.username, "password": self.password})
response_text: str = response.content.decode("utf-8")
self.assertEqual(response_text, USERNAME_ALREADY_USED)

View File

@ -1,36 +0,0 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest
from django.contrib.auth.models import User
from django.db.models.query import QuerySet
from ..status_code import *
from ..settings import *
from ..forms.change_password import ChangePasswordForm
class ChangePasswordView(View):
def get(self, request: HttpRequest):
return render(request, "change_password.html")
def post(self, request: HttpRequest):
form: ChangePasswordForm = ChangePasswordForm(request.POST)
if not form.is_valid():
return HttpResponse(INVALID_USERNAME_PASSWORD)
username: str = form.cleaned_data['username']
current_password: str = form.cleaned_data['current_password']
new_password: str = form.cleaned_data['new_password']
query: QuerySet = User.objects.filter(username=username)
if (not query.exists()):
return HttpResponse(INVALID_USERNAME_PASSWORD)
user: User = User.objects.get(username=username)
if (not user.check_password(current_password)):
return HttpResponse(INVALID_USERNAME_PASSWORD)
user.set_password(new_password)
user.save()
return HttpResponse(PASSWORD_UPDATED)

View File

@ -1,35 +0,0 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest
from django.contrib.auth.models import User
from django.db.models.query import QuerySet
from ..status_code import *
from ..settings import *
from ..forms.delete import DeleteForm
class DeleteView(View):
def get(self, request: HttpRequest):
return render(request, "delete.html", {"form": DeleteForm})
def post(self, request: HttpRequest):
form: DeleteForm = DeleteForm(request.POST)
if (not form.is_valid()):
return HttpResponse(INVALID_USERNAME_PASSWORD)
username: str = form.cleaned_data['username']
password: str = form.cleaned_data['password']
query: QuerySet = User.objects.filter(username=username)
if (not query.exists()):
return HttpResponse(INVALID_USERNAME_PASSWORD)
user: User = User.objects.get(username=username)
if (not user.check_password(password)):
return HttpResponse(INVALID_USERNAME_PASSWORD)
user.delete()
return HttpResponse(USER_DELETED)

View File

@ -1,31 +0,0 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.db.models.query import QuerySet
from ..status_code import *
from ..settings import *
from ..forms.login import LoginForm
class LoginView(View):
def get(self, request):
return render(request, "login.html", {"form": LoginForm})
def post(self, request):
form: LoginForm = LoginForm(request.POST)
if not form.is_valid():
return HttpResponse(INVALID_USERNAME_PASSWORD)
username: str = form.cleaned_data["username"]
password: str = form.cleaned_data["password"]
query: QuerySet = User.objects.filter(username=username)
if (not query.exists()):
return HttpResponse(INVALID_USERNAME_PASSWORD)
user: User = User.objects.get(username=username)
if (not user.check_password(password)):
return HttpResponse(INVALID_USERNAME_PASSWORD)
return HttpResponse(USER_VALID)

View File

@ -1,29 +0,0 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest
from django.contrib.auth.models import User
from django.db.models.query import QuerySet
from ..status_code import *
from ..settings import *
from ..forms.register import RegisterForm
class RegisterView(View):
def get(self, request: HttpRequest):
return render(request, "register.html", {"form": RegisterForm})
def post(self, request: HttpRequest):
form: RegisterForm = RegisterForm(request.POST)
if not form.is_valid():
return HttpResponse(INVALID_USERNAME_PASSWORD)
username: str = form.cleaned_data["username"]
password: str = form.cleaned_data["password"]
if User.objects.filter(username=username).exists():
return HttpResponse(USERNAME_ALREADY_USED)
user = User.objects.create_user(username, password=password)
user.save()
return HttpResponse(USER_ADDED)

View File

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,7 +0,0 @@
from django.urls import path
from . import views
urlpatterns = [
path("<str:uuid>", views.ProfilePage.as_view(), name="profile_page"),
]

View File

@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.

View File

@ -1,3 +1,6 @@
from django.contrib import admin
from .models import Profile
# Register your models here.
admin.site.register(Profile)

16
profiles/models.py Normal file
View File

@ -0,0 +1,16 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=40)
@receiver(post_save, sender=User)
def on_user_created(sender, instance, created, **kwargs):
if created:
profile: Profile = Profile.objects.create(pk = instance.pk, user = instance)
profile.save()

1
profiles/status_code.py Normal file
View File

@ -0,0 +1 @@
PROFILE_NOT_FOUND = "Profile Not Found"

17
profiles/tests.py Normal file
View File

@ -0,0 +1,17 @@
from django.test import TestCase
from django.http import HttpResponse, HttpRequest
from django.contrib.auth.models import User
# Create your tests here.
class ProfileTest(TestCase):
def setUp(self):
self.user: User = User.objects.create(username='bozo', password='password')
self.user.save()
self.expected_response = {"username": "bozo",
"title": ""}
def test_profile_create_on_user_created(self):
response: HttpResponse = self.client.get(f"/api/profiles/{self.user.pk}")
response_dict: dict = eval(response.content)
self.assertEqual(self.expected_response, response_dict)

7
profiles/urls.py Normal file
View File

@ -0,0 +1,7 @@
from django.urls import path
from . import views
urlpatterns = [
path("<int:id>", views.ProfilePage.as_view(), name="profile_page"),
]

21
profiles/views.py Normal file
View File

@ -0,0 +1,21 @@
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, HttpRequest
from django.contrib.auth.models import User
from django.http import JsonResponse
from .status_code import *
from .models import Profile
# Create your views here.
class ProfilePage(View):
def get(self, request: HttpRequest, id: int):
query: QuerySet = Profile.objects.filter(pk=id)
if (not query.exists()):
return HttpResponse(PROFILE_NOT_FOUND)
profile: Profile = Profile.objects.get(pk=id)
return JsonResponse({'username': profile.user.username,
'title': profile.title})

View File

@ -20,5 +20,5 @@ from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/accounts/', include('accounts.urls')),
path('api/profiles/', include('accounts.urls')),
path('api/profiles/', include('profiles.urls')),
]