feat: login and tests
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
77b01cec1c
commit
bffba7ec30
6 changed files with 162 additions and 12 deletions
46
accounts/templates/accounts/login.html
Normal file
46
accounts/templates/accounts/login.html
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{% comment %} Login Page {% endcomment %}
|
||||||
|
|
||||||
|
{% block login %}
|
||||||
|
<h2>Log In</h2>
|
||||||
|
<form method="post" action="">
|
||||||
|
{% csrf_token %} {{ form.as_p }}
|
||||||
|
<label class="form__label" for="email">Email</label><br/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="email"
|
||||||
|
name="email"
|
||||||
|
autofocus
|
||||||
|
required/><br/><br/>
|
||||||
|
|
||||||
|
<label class="form__label" for="pwd">Password</label><br/>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
required
|
||||||
|
id="password"
|
||||||
|
name="password"/><br/><br/>
|
||||||
|
<button type="submit">Log In</button>
|
||||||
|
<input type="hidden" name="next" value="{{ next }}">
|
||||||
|
{% for message in messages %}
|
||||||
|
<p id="messages">{{message}}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</form>
|
||||||
|
{% comment %} <div class="form-group">
|
||||||
|
<label for="exampleInputEmail1">Email address</label>
|
||||||
|
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
|
||||||
|
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="exampleInputPassword1">Password</label>
|
||||||
|
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
<div class="form-group form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" id="exampleCheck1">
|
||||||
|
<label class="form-check-label" for="exampleCheck1">Check me out</label>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button> {% endcomment %}
|
||||||
|
|
||||||
|
<p class="form__alt-action">
|
||||||
|
New to Mystiq?
|
||||||
|
<a href="{% url 'accounts:register' %}">Create an account</a>
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
|
@ -82,7 +82,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container signin">
|
<div class="container signin">
|
||||||
<p>Already have an account? <a href="#">Sign in</a>.</p>
|
<p>Already have an account? <a href="{% url 'accounts:login' %}">Sign in</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
|
1
accounts/templates/accounts/success.html
Normal file
1
accounts/templates/accounts/success.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<b> Login Successful! <b>
|
|
@ -48,10 +48,11 @@ 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.email,
|
"email": t.email,
|
||||||
"password": t.password,
|
"password": t.password,
|
||||||
}
|
}
|
||||||
resp = c.post(reverse("accounts.login"), payload)
|
resp = c.post(reverse("accounts:login"), payload)
|
||||||
|
print(resp.content)
|
||||||
t.assertEqual(resp.status_code, 302)
|
t.assertEqual(resp.status_code, 302)
|
||||||
t.assertEqual(resp.headers["location"], reverse(redirect_to))
|
t.assertEqual(resp.headers["location"], reverse(redirect_to))
|
||||||
|
|
||||||
|
@ -150,3 +151,34 @@ class RegistrationTest(TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
b"We do not provide services for this domain yet." in resp.content, True
|
b"We do not provide services for this domain yet." in resp.content, True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Login Tests
|
||||||
|
|
||||||
|
|
||||||
|
class LoginTest(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.username = "register_user"
|
||||||
|
self.password = "2i3j4;1qlk2asdf"
|
||||||
|
self.email = "register_user@vitap.ac.in"
|
||||||
|
register_util(t=self, username=self.username)
|
||||||
|
|
||||||
|
def test_register_template_works(self):
|
||||||
|
"""
|
||||||
|
Tests if register template renders
|
||||||
|
"""
|
||||||
|
resp = self.client.get(reverse("accounts:login"))
|
||||||
|
self.assertEqual(b"Log" in resp.content, True)
|
||||||
|
|
||||||
|
def test_login_works(self):
|
||||||
|
"""
|
||||||
|
Tests if login works
|
||||||
|
"""
|
||||||
|
c = Client()
|
||||||
|
payload = {
|
||||||
|
"email": self.email,
|
||||||
|
"password": self.password,
|
||||||
|
}
|
||||||
|
resp = c.post(reverse("accounts:login"), payload)
|
||||||
|
self.assertEqual(resp.status_code, 302)
|
||||||
|
self.assertEqual(resp.headers["location"], reverse("accounts:success_page"))
|
||||||
|
|
|
@ -22,4 +22,7 @@ app_name = "accounts"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", views.index, name="accounts.index"),
|
path("", views.index, name="accounts.index"),
|
||||||
path("register/", views.register, name="register"),
|
path("register/", views.register, name="register"),
|
||||||
|
path("login/", views.login_user, name="login"),
|
||||||
|
path("success/", views.success_page, name="success_page"),
|
||||||
|
# path("accounts/login/", default_login_url, name="accounts.default_login_url"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from audioop import reverse
|
||||||
from multiprocessing import get_context
|
from multiprocessing import get_context
|
||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
from re import template
|
from re import template
|
||||||
|
@ -26,6 +26,9 @@ from django.contrib.auth import authenticate, login, logout, get_user_model
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.views.decorators.csrf import csrf_protect
|
from django.views.decorators.csrf import csrf_protect
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
@ -35,6 +38,65 @@ def index(request):
|
||||||
return HttpResponse("Hello World.")
|
return HttpResponse("Hello World.")
|
||||||
|
|
||||||
|
|
||||||
|
# @csrf_protect
|
||||||
|
# def login(request):
|
||||||
|
# return render(request, 'accounts/login.html')
|
||||||
|
|
||||||
|
|
||||||
|
# login page
|
||||||
|
@csrf_protect
|
||||||
|
def login_user(request):
|
||||||
|
def default_login_ctx():
|
||||||
|
return {
|
||||||
|
"title": "Login",
|
||||||
|
"footer": footer_ctx(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
email = request.POST["email"]
|
||||||
|
password = request.POST["password"]
|
||||||
|
# domain_check = email.split("@")
|
||||||
|
# check user exists
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
if not User.objects.filter(email=email).exists():
|
||||||
|
messages.info(request, "Username OR password is incorrect")
|
||||||
|
return redirect(reverse("accounts:login"))
|
||||||
|
|
||||||
|
username = User.objects.get(email=email).username
|
||||||
|
user = authenticate(request, username=username, password=password)
|
||||||
|
|
||||||
|
if user is not None:
|
||||||
|
login(request, user)
|
||||||
|
# Redirect to a success page.
|
||||||
|
print(reverse("accounts:success_page"))
|
||||||
|
if "next" in request.POST:
|
||||||
|
next = request.POST["next"]
|
||||||
|
if len(next) > 0:
|
||||||
|
return redirect(next)
|
||||||
|
return redirect(reverse("accounts:success_page"))
|
||||||
|
else:
|
||||||
|
# Return an 'invalid login' error message.
|
||||||
|
messages.info(request, "Username OR password is incorrect")
|
||||||
|
return redirect(reverse("accounts:login"))
|
||||||
|
else:
|
||||||
|
context = {}
|
||||||
|
if "next" in request.GET:
|
||||||
|
next = request.GET["next"]
|
||||||
|
context["next"] = next
|
||||||
|
return render(request, "accounts/login.html", context=context)
|
||||||
|
|
||||||
|
|
||||||
|
# success page
|
||||||
|
@login_required(login_url="/accounts/login/")
|
||||||
|
@csrf_protect
|
||||||
|
def success_page(request):
|
||||||
|
return render(request, "accounts/success.html")
|
||||||
|
|
||||||
|
|
||||||
|
# user registratoin
|
||||||
|
|
||||||
|
|
||||||
@csrf_protect
|
@csrf_protect
|
||||||
def register(request):
|
def register(request):
|
||||||
# response = "You are at the Registration Page."
|
# response = "You are at the Registration Page."
|
||||||
|
@ -51,6 +113,14 @@ def register(request):
|
||||||
password = request.POST["password"]
|
password = request.POST["password"]
|
||||||
password_confirm = request.POST["password-confirm"]
|
password_confirm = request.POST["password-confirm"]
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
# domain verification
|
# domain verification
|
||||||
domain_check = email.split("@")
|
domain_check = email.split("@")
|
||||||
if domain_check[1] != "vitap.ac.in":
|
if domain_check[1] != "vitap.ac.in":
|
||||||
|
@ -62,19 +132,17 @@ def register(request):
|
||||||
|
|
||||||
# email verification
|
# email verification
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
if User.objects.filter(email=email).exists():
|
if any(
|
||||||
|
[
|
||||||
|
User.objects.filter(email=email).exists(),
|
||||||
|
User.objects.filter(username=domain_check[0]).exists(),
|
||||||
|
]
|
||||||
|
):
|
||||||
context["error"] = {
|
context["error"] = {
|
||||||
"title": "Registration Failed",
|
"title": "Registration Failed",
|
||||||
"reason": "This email is already registered.",
|
"reason": "This email is already registered.",
|
||||||
}
|
}
|
||||||
return render(request, "accounts/register.html", status=400, context=context)
|
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()(
|
user = get_user_model()(
|
||||||
username=domain_check[0],
|
username=domain_check[0],
|
||||||
|
|
Reference in a new issue