Merge pull request 'feat: registration' (#5) from wip-registration into master

Reviewed-on: mystiq/sso#5
This commit is contained in:
Aravinth Manivannan 2022-08-22 19:26:43 +05:30
commit 729447e9d6
6 changed files with 262 additions and 4 deletions

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration</title>
</head>
<body>
<!-- <form action="{% url 'accounts:register' %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ Registration }}</h1></legend>
</fieldset>
<fieldset>
<label for="email">
<b>Email</b>
<input type="text" placeholder="Enter Email" name="email" id="email" required>
</label>
</fieldset>
<fieldset>
<label for="psw">
<b>Password</b>
<input type="password" placeholder="Enter Password" name="psw" id="psw" required>
</label>
</fieldset>
<fieldset>
<label for="cnf-psw">
<b>Password</b>
<input type="password" placeholder="Confirn Password" name="cnf-psw" id="cnf-psw" required>
</label>
</fieldset>
<input type="submit" value="register">
</form> -->
<form action="{% url 'accounts:register' %}" method="post" class="form" accept-charset="utf-8">
{% if error %}
<div class="error__container">
<h3 class="error__title">ERROR: {{ error.title }}</h3>
<p class="error__message">{{ error.reason }}</p>
</div>
{% endif %}
{% csrf_token %}
<div class="container">
<h1>Register</h1>
<p>Welcome to mystiq registration.</p>
<hr>
<label for="email">
<b>Email</b>
<input
type="text"
placeholder="Enter Email"
name="email"
id="email"
required
{% if email %}
value={{ username }}
{% endif %}
>
</label>
<label for="password">
<b>Password</b>
<input type="password" placeholder="Enter Password" name="password" id="password" required>
</label>
<label for="password-confirm">
<b>Confirm Password</b>
<input type="password" placeholder="Confirm Password" name="password-confirm" id="password-confirm" required>
</label>
<hr>
<p>By creating an account you agree to our <a href="#">Terms & Privacy</a>.</p>
<button type="submit" class="form_submit">Register</button>
</div>
<div class="container signin">
<p>Already have an account? <a href="#">Sign in</a>.</p>
</div>
</form>
</body>
</html>

View file

@ -1,6 +1,7 @@
# Create your tests here. # Create your tests here.
# Copyright © 2022 Aravinth Manivannan <realaravinth@batsense.net> # Copyright © 2022 Aravinth Manivannan <realaravinth@batsense.net>
# Copyright © 2022 Alan Alexander Thomas <alan2000alex@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -36,10 +37,9 @@ from oauth2_provider.models import get_application_model
def register_util(t: TestCase, username: str): def register_util(t: TestCase, username: str):
t.password = "asdklfja;ldkfja;df" t.password = "asdklfja;ldkfja;df"
t.username = username t.email = f"{username}@vitap.ac.in"
t.email = f"{t.username}@example.org"
t.user = get_user_model().objects.create( t.user = get_user_model().objects.create(
username=t.username, username=username,
email=t.email, email=t.email,
) )
t.user.set_password(t.password) t.user.set_password(t.password)
@ -48,7 +48,7 @@ def register_util(t: TestCase, username: str):
def login_util(t: TestCase, c: Client, redirect_to: str): def login_util(t: TestCase, c: Client, redirect_to: str):
payload = { payload = {
"login": t.username, "login": t.email,
"password": t.password, "password": t.password,
} }
resp = c.post(reverse("accounts.login"), payload) resp = c.post(reverse("accounts.login"), payload)
@ -102,3 +102,51 @@ class CreateOidCApplicaiton(TestCase):
self.assertEqual(app.client_type, "confidential") self.assertEqual(app.client_type, "confidential")
self.assertEqual(app.authorization_grant_type, "authorization-code") self.assertEqual(app.authorization_grant_type, "authorization-code")
self.assertEqual(app.algorithm, "HS256") self.assertEqual(app.algorithm, "HS256")
class RegistrationTest(TestCase):
def setUp(self):
self.username = "register_user"
self.password = "2i3j4;1qlk2asdf"
self.email = "register_user@vitap.ac.in"
def test_register_template_works(self):
"""
Tests if register template renders
"""
resp = self.client.get(reverse("accounts:register"))
self.assertEqual(b"Register" in resp.content, True)
def test_register_works(self):
"""
Tests if register works
"""
c = Client()
# passwords don't match
msg = {
"password": self.password,
"email": self.email,
"password-confirm": self.email,
}
resp = c.post(reverse("accounts:register"), msg)
self.assertEqual(resp.status_code, 400)
# register user
msg["password-confirm"] = self.password
resp = c.post(reverse("accounts:register"), msg)
self.assertEqual(resp.status_code, 200)
user = get_user_model().objects.get(username=self.username)
# duplicate email
resp = c.post(reverse("accounts:register"), msg)
self.assertEqual(resp.status_code, 400)
self.assertEqual(b"This email is already registered." in resp.content, True)
msg["email"] = "12345@gmail.com"
resp = c.post(reverse("accounts:register"), msg)
self.assertEqual(resp.status_code, 400)
self.assertEqual(
b"We do not provide services for this domain yet." in resp.content, True
)

25
accounts/urls.py Normal file
View file

@ -0,0 +1,25 @@
"""sso URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Exaimples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from . import views
app_name = "accounts"
urlpatterns = [
path("", views.index, name="accounts.index"),
path("register/", views.register, name="register"),
]

View file

@ -1,3 +1,97 @@
# Copyright © 2022 Alan Alexander Thomas <alan2000alex@gmail.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
#
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from multiprocessing import get_context
from django.shortcuts import render from django.shortcuts import render
# Create your views here. # Create your views here.
from re import template
from urllib import response
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.password_validation import validate_password
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.http import HttpResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_protect
from django.core.exceptions import ValidationError
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello World.")
@csrf_protect
def register(request):
# response = "You are at the Registration Page."
get_context = {}
if request.method == "GET":
if "next" in request.GET:
get_context["next"] = request.GET["next"]
return render(request, "accounts/register.html", get_context)
context = {}
# variables
email = request.POST["email"]
password = request.POST["password"]
password_confirm = request.POST["password-confirm"]
# domain verification
domain_check = email.split("@")
if domain_check[1] != "vitap.ac.in":
context["error"] = {
"title": "Registration Failed",
"reason": "We do not provide services for this domain yet.",
}
return render(request, "accounts/register.html", status=400, context=context)
# email verification
User = get_user_model()
if User.objects.filter(email=email).exists():
context["error"] = {
"title": "Registration Failed",
"reason": "This email is already registered.",
}
return render(request, "accounts/register.html", status=400, context=context)
# password matching
if password != password_confirm:
context["error"] = {
"title": "Registration Failed",
"reason": "Passwords do not match.",
}
return render(request, "accounts/register.html", status=400, context=context)
user = get_user_model()(
username=domain_check[0],
email=email,
)
user.set_password(password)
try:
user.full_clean()
validate_password(password, user=user)
except ValidationError as err:
reason = ""
for errors in err:
reason += errors + " "
context["error"] = {"title": "Registration Failed", "reason": reason}
print(reason)
return render(request, "accounts/register.html", status=400, context=context)
user.save()
return HttpResponse("New acc. can be registered.")

View file

@ -29,6 +29,7 @@ pylint==2.14.5
pynvim==0.4.3 pynvim==0.4.3
requests==2.28.1 requests==2.28.1
sqlparse==0.4.2 sqlparse==0.4.2
tblib==1.7.0
tomli==2.0.1 tomli==2.0.1
tomlkit==0.11.4 tomlkit==0.11.4
urllib3==1.26.11 urllib3==1.26.11

View file

@ -19,4 +19,5 @@ from django.urls import path, include
urlpatterns = [ urlpatterns = [
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")), path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
path("accounts/", include("accounts.urls")),
] ]