diff --git a/accounts/templates/accounts/register.html b/accounts/templates/accounts/register.html
new file mode 100644
index 0000000..7a58c5e
--- /dev/null
+++ b/accounts/templates/accounts/register.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+ Registration
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/accounts/tests.py b/accounts/tests.py
index 406b5dd..2d290cc 100644
--- a/accounts/tests.py
+++ b/accounts/tests.py
@@ -1,6 +1,7 @@
# Create your tests here.
# Copyright © 2022 Aravinth Manivannan
+# Copyright © 2022 Alan Alexander Thomas
#
# This program is free software: you can redistribute it and/or modify
# 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):
t.password = "asdklfja;ldkfja;df"
- t.username = username
- t.email = f"{t.username}@example.org"
+ t.email = f"{username}@vitap.ac.in"
t.user = get_user_model().objects.create(
- username=t.username,
+ username=username,
email=t.email,
)
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):
payload = {
- "login": t.username,
+ "login": t.email,
"password": t.password,
}
resp = c.post(reverse("accounts.login"), payload)
@@ -102,3 +102,51 @@ class CreateOidCApplicaiton(TestCase):
self.assertEqual(app.client_type, "confidential")
self.assertEqual(app.authorization_grant_type, "authorization-code")
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
+ )
diff --git a/accounts/urls.py b/accounts/urls.py
new file mode 100644
index 0000000..16592e4
--- /dev/null
+++ b/accounts/urls.py
@@ -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"),
+]
diff --git a/accounts/views.py b/accounts/views.py
index 91ea44a..53e0ce7 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -1,3 +1,97 @@
+# Copyright © 2022 Alan Alexander Thomas
+
+# 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 .
+
+from multiprocessing import get_context
from django.shortcuts import render
# 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.")
diff --git a/requirements.txt b/requirements.txt
index d0903de..03ccf88 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
asgiref==3.5.2
astroid==2.11.7
+backports.zoneinfo==0.2.1
black==22.6.0
certifi==2022.6.15
cffi==1.15.1
@@ -29,7 +30,9 @@ pylint==2.14.5
pynvim==0.4.3
requests==2.28.1
sqlparse==0.4.2
+tblib==1.7.0
tomli==2.0.1
tomlkit==0.11.4
+typing_extensions==4.3.0
urllib3==1.26.11
wrapt==1.14.1
diff --git a/sso/urls.py b/sso/urls.py
index 0b2bdcb..44fe01e 100644
--- a/sso/urls.py
+++ b/sso/urls.py
@@ -19,4 +19,5 @@ from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
+ path("accounts/", include("accounts.urls")),
]