diff --git a/markdownblog/markdownblog/settings.py b/markdownblog/markdownblog/settings.py index fce21f7..dafa80c 100644 --- a/markdownblog/markdownblog/settings.py +++ b/markdownblog/markdownblog/settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.0/ref/settings/ """ import os from pathlib import Path +from authlib.integrations.django_client import OAuth # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -147,3 +148,20 @@ MFA_ISSUER_NAME = 'MDBlog' # Configure mail here 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 + } + diff --git a/markdownblog/markdownblog/static/login.css b/markdownblog/markdownblog/static/login.css new file mode 100644 index 0000000..6490462 --- /dev/null +++ b/markdownblog/markdownblog/static/login.css @@ -0,0 +1,9 @@ +.round-corner { + border-radius: 5px; +} + +.oauth-option { + background-color: #35aca1; + font-size: 1.1em; + color: #ffffff; +} \ No newline at end of file diff --git a/markdownblog/markdownblog/templates/base/base.html b/markdownblog/markdownblog/templates/base/base.html index 10dce4c..de6ddbb 100644 --- a/markdownblog/markdownblog/templates/base/base.html +++ b/markdownblog/markdownblog/templates/base/base.html @@ -61,7 +61,8 @@
  • admin_panel_settingsAdmin panel
  • -
  • +
  • vpn_keyManage 2FA
  • logoutLogout
  • @@ -100,6 +101,10 @@ document.addEventListener('DOMContentLoaded', function () { const elems = document.querySelectorAll('.sidenav'); M.Sidenav.init(elems); + + if ("{{ error }}" !== "") { + M.toast({html: '{{ error }}'}); + } }); {% block scripts %}{% endblock %} diff --git a/markdownblog/markdownblog/templates/registration/login.html b/markdownblog/markdownblog/templates/registration/login.html index 66af360..75ef8be 100644 --- a/markdownblog/markdownblog/templates/registration/login.html +++ b/markdownblog/markdownblog/templates/registration/login.html @@ -1,14 +1,39 @@ {% extends 'base/base.html' %} +{% load static %} {% block title %} Log-in {% endblock %} {% block content %} -
    + +
    {% csrf_token %} {{ form.as_p }} -
    + {% for auth_method in AUTHLIB_OAUTH_CLIENTS %} + + {% endfor %}
    + {% endblock %} \ No newline at end of file diff --git a/markdownblog/markdownblog/urls.py b/markdownblog/markdownblog/urls.py index 3bf1972..459e7f6 100644 --- a/markdownblog/markdownblog/urls.py +++ b/markdownblog/markdownblog/urls.py @@ -1,11 +1,13 @@ from django.contrib import admin from django.urls import path, include +from markdownblog.views import login_view import django_2fa.urls urlpatterns = [ path('', include('blog.urls')), path('admin/', admin.site.urls), + path('accounts/login/', login_view), path('accounts/', include('django.contrib.auth.urls')), path('accounts/2fa/', include(django_2fa.urls)), ] diff --git a/markdownblog/markdownblog/views.py b/markdownblog/markdownblog/views.py new file mode 100644 index 0000000..2c64880 --- /dev/null +++ b/markdownblog/markdownblog/views.py @@ -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) diff --git a/markdownblog/requirements.txt b/markdownblog/requirements.txt index 4fe3b49..96ce682 100644 --- a/markdownblog/requirements.txt +++ b/markdownblog/requirements.txt @@ -7,4 +7,6 @@ pygments==2.12.0 django-2fa==0.9.0 django-extensions==3.1.5 Werkzeug==2.1.2 -pyOpenSSL==22.0.0 \ No newline at end of file +pyOpenSSL==22.0.0 +authlib==1.2.0 +requests==2.28.1 \ No newline at end of file