set up oauth and fixed login flow
This commit is contained in:
parent
b09897a39c
commit
dba4e12032
7 changed files with 90 additions and 4 deletions
|
|
@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from authlib.integrations.django_client import OAuth
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
@ -147,3 +148,20 @@ MFA_ISSUER_NAME = 'MDBlog'
|
||||||
|
|
||||||
# Configure mail here
|
# Configure mail here
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
|
|
||||||
|
AUTHLIB_OAUTH_CLIENTS = {}
|
||||||
|
|
||||||
|
if os.environ['ENABLE_NEXTCLOUD_OAUTH'] == "True":
|
||||||
|
AUTHLIB_OAUTH_CLIENTS['nextcloud'] = {
|
||||||
|
'client_id': os.environ['NC_OAUTH_CLIENT_ID'], # "Client Identifier" in Nextcloud
|
||||||
|
'client_secret': os.environ['NC_OAUTH_CLIENT_SECRET'], # "Secret" in Nextcloud
|
||||||
|
'request_token_url': os.environ['NC_BASE_URL'] + '/index.php/apps/oauth2/api/v1/token',
|
||||||
|
'request_token_params': None,
|
||||||
|
'access_token_url': os.environ['NC_BASE_URL'] + '/index.php/apps/oauth2/api/v1/token',
|
||||||
|
'access_token_params': None,
|
||||||
|
'refresh_token_url': None,
|
||||||
|
'authorize_url': os.environ['NC_BASE_URL'] + '/index.php/apps/oauth2/authorize',
|
||||||
|
'api_base_url': None,
|
||||||
|
'client_kwargs': None
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
markdownblog/markdownblog/static/login.css
Normal file
9
markdownblog/markdownblog/static/login.css
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
.round-corner {
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth-option {
|
||||||
|
background-color: #35aca1;
|
||||||
|
font-size: 1.1em;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
@ -61,7 +61,8 @@
|
||||||
</li>
|
</li>
|
||||||
<li class="no-liststyle"><a class="waves-effect" href="{% url 'admin:index' %}"><i class="material-icons">
|
<li class="no-liststyle"><a class="waves-effect" href="{% url 'admin:index' %}"><i class="material-icons">
|
||||||
admin_panel_settings</i>Admin panel</a></li>
|
admin_panel_settings</i>Admin panel</a></li>
|
||||||
<li class="no-liststyle"><a class="waves-effect" href="{% url 'django_2fa:devices' %}"><i class="material-icons">
|
<li class="no-liststyle"><a class="waves-effect" href="{% url 'django_2fa:devices' %}"><i
|
||||||
|
class="material-icons">
|
||||||
vpn_key</i>Manage 2FA</a></li>
|
vpn_key</i>Manage 2FA</a></li>
|
||||||
<li class="no-liststyle"><a class="waves-effect" href="{% url 'logout' %}"><i
|
<li class="no-liststyle"><a class="waves-effect" href="{% url 'logout' %}"><i
|
||||||
class="material-icons">logout</i>Logout</a></li>
|
class="material-icons">logout</i>Logout</a></li>
|
||||||
|
|
@ -100,6 +101,10 @@
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const elems = document.querySelectorAll('.sidenav');
|
const elems = document.querySelectorAll('.sidenav');
|
||||||
M.Sidenav.init(elems);
|
M.Sidenav.init(elems);
|
||||||
|
|
||||||
|
if ("{{ error }}" !== "") {
|
||||||
|
M.toast({html: '{{ error }}'});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% block scripts %}{% endblock %}
|
{% block scripts %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,39 @@
|
||||||
{% extends 'base/base.html' %}
|
{% extends 'base/base.html' %}
|
||||||
|
{% load static %}
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Log-in
|
Log-in
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col s8 offset-s2">
|
<link rel="stylesheet" href="{% static 'login.css' %}">
|
||||||
|
<div class="col s8 offset-s3">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.as_p }}
|
{{ form.as_p }}
|
||||||
<button type="submit" class="waves-effect waves-light btn">Log In<i class="material-icons right">send</i>
|
<div class="row">
|
||||||
|
<div class="input-field col s6">
|
||||||
|
<input id="username" type="text" class="validate" name="username">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s6">
|
||||||
|
<input id="password" type="password" class="validate" name="password">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="waves-effect waves-light btn">Log In<i
|
||||||
|
class="material-icons right">send</i>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
{% for auth_method in AUTHLIB_OAUTH_CLIENTS %}
|
||||||
|
<div class="row mt-3">
|
||||||
|
<a href="#">
|
||||||
|
<div class="col s6 z-depth-3 round-corner oauth-option">
|
||||||
|
<p class="oauth-option">Log in via {{ auth_method }}</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
from markdownblog.views import login_view
|
||||||
|
|
||||||
import django_2fa.urls
|
import django_2fa.urls
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include('blog.urls')),
|
path('', include('blog.urls')),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('accounts/login/', login_view),
|
||||||
path('accounts/', include('django.contrib.auth.urls')),
|
path('accounts/', include('django.contrib.auth.urls')),
|
||||||
path('accounts/2fa/', include(django_2fa.urls)),
|
path('accounts/2fa/', include(django_2fa.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
25
markdownblog/markdownblog/views.py
Normal file
25
markdownblog/markdownblog/views.py
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.views import LoginView
|
||||||
|
from django.shortcuts import render, redirect
|
||||||
|
from django.contrib.auth import authenticate, login
|
||||||
|
|
||||||
|
|
||||||
|
def login_view(request):
|
||||||
|
context = {'AUTHLIB_OAUTH_CLIENTS': settings.AUTHLIB_OAUTH_CLIENTS, 'form': LoginView.authentication_form}
|
||||||
|
|
||||||
|
# handle user login if standard login is used
|
||||||
|
if request.method == 'POST':
|
||||||
|
if 'username' not in request.POST or 'password' not in request.POST:
|
||||||
|
context['error'] = 'Please enter a username and a password'
|
||||||
|
else:
|
||||||
|
username = request.POST['username']
|
||||||
|
password = request.POST['password']
|
||||||
|
user = authenticate(request, username=username, password=password)
|
||||||
|
|
||||||
|
if user is not None:
|
||||||
|
login(request, user)
|
||||||
|
return redirect(settings.LOGIN_REDIRECT_URL)
|
||||||
|
else:
|
||||||
|
context['error'] = "Invalid credentials"
|
||||||
|
|
||||||
|
return render(request, 'registration/login.html', context)
|
||||||
|
|
@ -7,4 +7,6 @@ pygments==2.12.0
|
||||||
django-2fa==0.9.0
|
django-2fa==0.9.0
|
||||||
django-extensions==3.1.5
|
django-extensions==3.1.5
|
||||||
Werkzeug==2.1.2
|
Werkzeug==2.1.2
|
||||||
pyOpenSSL==22.0.0
|
pyOpenSSL==22.0.0
|
||||||
|
authlib==1.2.0
|
||||||
|
requests==2.28.1
|
||||||
Loading…
Add table
Add a link
Reference in a new issue