Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic OIDC integration with locally setup Authentik #1805

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions wger/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (
HTML,
Button,
ButtonHolder,
Column,
Fieldset,
Expand All @@ -52,6 +53,10 @@
# wger
from wger.core.models import UserProfile

#OIDC
from django.urls import reverse
from django.shortcuts import redirect


class UserLoginForm(AuthenticationForm):
"""
Expand All @@ -67,6 +72,14 @@ def __init__(self, authenticate_on_clean=True, *args, **kwargs):

self.helper = FormHelper()
self.helper.add_input(Submit('submit', _('Login'), css_class='btn-success btn-block'))
self.helper.add_input(
Button(
'authentik_login',
_('Login with Authentik'),
css_class='btn btn-primary btn-block',
onclick=f"window.location.href='{reverse('oidc_authentication_init')}'"
)
)
self.helper.form_class = 'wger-form'
self.helper.layout = Layout(
Row(
Expand All @@ -84,6 +97,7 @@ def clean(self):

See https://github.com/wger-project/wger/issues/1163
"""

if self.authenticate_on_clean:
self.authenticate(self.request)
return self.cleaned_data
Expand Down
2 changes: 0 additions & 2 deletions wger/core/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

{% block template %}



{% if trainer_identity %}
<div class="alert alert-info" style="margin-top: 1em;">
{% blocktranslate with current_user=user|format_username %}You are
Expand Down
7 changes: 6 additions & 1 deletion wger/core/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{% extends "base_wide.html" %}
{% load i18n static wger_extras %}

{% block title %}{% translate "Dashboard" %}{% endblock %}
{% block title %}
{% if user.is_authenticated %}
<p>Welcome, {{ user }}</p>
{% endif %}
{% translate "Dashboard" %}
{% endblock %}

{# #}
{# Header #}
Expand Down
1 change: 0 additions & 1 deletion wger/core/templates/user/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
{% crispy form %}
{% endblock %}


{% block sidebar %}
<h4>{% translate "No account?" %}</h4>
<p>
Expand Down
1 change: 1 addition & 0 deletions wger/core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# You should have received a copy of the GNU Affero General Public License

# Django
from django.contrib import admin
from django.conf.urls import include
from django.contrib.auth import views
from django.urls import (
Expand Down
2 changes: 1 addition & 1 deletion wger/core/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ def trainer_login(request, user_pk):
# authentication backend
if own:
del request.session['trainer.identity']
# django_login(request, user, 'django.contrib.auth.backends.ModelBackend')
django_login(request, user, 'django.contrib.auth.backends.ModelBackend')

if not own:
request.session['trainer.identity'] = orig_user_pk
if request.GET.get('next'):
Expand Down
24 changes: 23 additions & 1 deletion wger/settings_global.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
import sys
from datetime import timedelta

# OIDC
import environ
env = environ.Env()
environ.Env.read_env()

# wger
from wger import get_version
from wger.utils.constants import DOWNLOAD_INGREDIENT_WGER
Expand All @@ -42,6 +47,8 @@
WSGI_APPLICATION = 'wger.wsgi.application'

INSTALLED_APPS = [
'mozilla_django_oidc',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
Expand Down Expand Up @@ -117,6 +124,7 @@
]

MIDDLEWARE = [

# Prometheus
'django_prometheus.middleware.PrometheusBeforeMiddleware',

Expand All @@ -128,6 +136,9 @@
# Django Admin
'django.contrib.auth.middleware.AuthenticationMiddleware',

# middleware involving session and authentication must come first
'mozilla_django_oidc.middleware.SessionRefresh',

# Javascript Header. Sends helper headers for AJAX
'wger.utils.middleware.JavascriptAJAXRedirectionMiddleware',

Expand All @@ -151,9 +162,10 @@
]

AUTHENTICATION_BACKENDS = (
'mozilla_django_oidc.auth.OIDCAuthenticationBackend',
'axes.backends.AxesStandaloneBackend', # should be the first one in the list
'django.contrib.auth.backends.ModelBackend',
'wger.utils.helpers.EmailAuthBackend',
'wger.utils.helpers.EmailAuthBackend'
)

TEMPLATES = [
Expand Down Expand Up @@ -207,6 +219,7 @@
LOGIN_URL = '/user/login'
LOGIN_REDIRECT_URL = '/'


#
# Internationalization
#
Expand Down Expand Up @@ -587,3 +600,12 @@ def email_verified_callback(user):

# Whether the application is being run regularly or during tests
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'

# OIDC
OIDC_RP_CLIENT_ID = env("OIDC_RP_CLIENT_ID")
OIDC_RP_CLIENT_SECRET = env("OIDC_RP_CLIENT_SECRET")
OIDC_OP_AUTHORIZATION_ENDPOINT = env("OIDC_OP_AUTHORIZATION_ENDPOINT")
OIDC_OP_USER_ENDPOINT = env("OIDC_OP_USER_ENDPOINT")
OIDC_OP_TOKEN_ENDPOINT = env("OIDC_OP_TOKEN_ENDPOINT")
OIDC_RP_SIGN_ALGO = env('OIDC_RP_SIGN_ALGO')
OIDC_OP_JWKS_ENDPOINT = env('OIDC_OP_JWKS_ENDPOINT')
5 changes: 4 additions & 1 deletion wger/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.

# Django
from django.contrib import admin
from django.conf import settings
from django.conf.urls import include
from django.conf.urls.i18n import i18n_patterns
Expand Down Expand Up @@ -217,6 +218,8 @@
# The actual URLs
#
urlpatterns = i18n_patterns(
path('oidc/', include('mozilla_django_oidc.urls')),
path('admin/', admin.site.urls),
path('', include(('wger.core.urls', 'core'), namespace='core')),
path('routine/', include(('wger.manager.urls', 'manager'), namespace='manager')),
path('exercise/', include(('wger.exercises.urls', 'exercise'), namespace='exercise')),
Expand Down Expand Up @@ -251,7 +254,7 @@
path('api/v2/', include(router.urls)),
# The api user login
path(
'api/v2/login/', core_api_views.UserAPILoginView.as_view({'post': 'post'}), name='api_user'
'api/v2/ /', core_api_views.UserAPILoginView.as_view({'post': 'post'}), name='api_user'
),
path(
'api/v2/register/',
Expand Down