use env variable for cache duration + limit API to logged in user only

This commit is contained in:
2024-05-17 19:24:28 +02:00
parent 4c39fed29b
commit ba6f877b4b
9 changed files with 31 additions and 13 deletions

View File

@@ -23,3 +23,4 @@ CSRF_TRUSTED_ORIGINS=
OIDC_RP_CLIENT_ID= OIDC_RP_CLIENT_ID=
OIDC_WELLKNOWN= OIDC_WELLKNOWN=
OIDC_CACHE_USERINFO=

View File

@@ -13,6 +13,7 @@ COPY --chown=appuser:appuser marbas /app/marbas
COPY --chown=appuser:appuser sde /app/sde COPY --chown=appuser:appuser sde /app/sde
COPY --chown=appuser:appuser api /app/api COPY --chown=appuser:appuser api /app/api
COPY --chown=appuser:appuser authentication /app/authentication COPY --chown=appuser:appuser authentication /app/authentication
COPY --chown=appuser:appuser static /app/static
USER appuser USER appuser
CMD ["uvicorn", "marbas.asgi:application", "--host", "0.0.0.0", "--port", "8000"] CMD ["uvicorn", "marbas.asgi:application", "--host", "0.0.0.0", "--port", "8000"]

View File

@@ -23,7 +23,6 @@ class AcquisitionSerializer(serializers.ModelSerializer):
class TypeTrackingSerializer(serializers.ModelSerializer): class TypeTrackingSerializer(serializers.ModelSerializer):
type = sde_serializers.SDETypeSerializer()
class Meta: class Meta:
model = models.TypeTracking model = models.TypeTracking
fields = '__all__' fields = '__all__'

View File

@@ -4,14 +4,23 @@ from django.db.models import Q
from django.contrib.auth import models as auth_models from django.contrib.auth import models as auth_models
from django.core.cache import cache from django.core.cache import cache
from rest_framework import viewsets, permissions, settings from rest_framework import viewsets, permissions, settings
from rest_framework.decorators import api_view from rest_framework.decorators import api_view, action
from rest_framework.response import Response from rest_framework.response import Response
from api import serializers, models from api import serializers, models
from sde import serializers as sde_serializers, models as sde_models from sde import serializers as sde_serializers, models as sde_models
class UserViewSet(viewsets.ModelViewSet): class LoggedUserOnly:
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
return self.queryset.filter(user=self.request.user)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
class UserViewSet(viewsets.ReadOnlyModelViewSet):
""" """
API endpoint that allows users to be viewed or edited. API endpoint that allows users to be viewed or edited.
""" """
@@ -20,7 +29,8 @@ class UserViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated] permission_classes = [permissions.IsAuthenticated]
class GroupViewSet(viewsets.ModelViewSet):
class GroupViewSet(viewsets.ReadOnlyModelViewSet):
""" """
API endpoint that allows groups to be viewed or edited. API endpoint that allows groups to be viewed or edited.
""" """
@@ -29,22 +39,20 @@ class GroupViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated] permission_classes = [permissions.IsAuthenticated]
class AcquisitionViewSet(viewsets.ModelViewSet): class AcquisitionViewSet(LoggedUserOnly, viewsets.ModelViewSet):
""" """
API endpoint that allows acquisitions to be viewed or edited. API endpoint that allows acquisitions to be viewed or edited.
""" """
queryset = models.Acquisition.objects.all().order_by('-date') queryset = models.Acquisition.objects.all().order_by('-date')
serializer_class = serializers.AcquisitionSerializer serializer_class = serializers.AcquisitionSerializer
permission_classes = [permissions.IsAuthenticated]
class TypeTrackingViewSet(viewsets.ModelViewSet): class TypeTrackingViewSet(LoggedUserOnly, viewsets.ModelViewSet):
""" """
API endpoint that allows types tracking to be viewed or edited. API endpoint that allows types tracking to be viewed or edited.
""" """
queryset = models.TypeTracking.objects.all() queryset = models.TypeTracking.objects.all()
serializer_class = serializers.TypeTrackingSerializer serializer_class = serializers.TypeTrackingSerializer
permission_classes = [permissions.IsAuthenticated]
@api_view(['POST']) @api_view(['POST'])

View File

@@ -5,6 +5,7 @@ from django.http import JsonResponse
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend from django.contrib.auth.backends import ModelBackend
from django.conf import settings
from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import AuthenticationFailed
@@ -23,7 +24,7 @@ class CustomOIDCBackend(OIDCAuthenticationBackend):
"""Hack to use the same auth as DRF""" """Hack to use the same auth as DRF"""
back = OIDCAuthentication() back = OIDCAuthentication()
try: try:
u, tok = back.authenticate(request) u, tok = back.authenticate(request) or (None, None)
except AuthenticationFailed: except AuthenticationFailed:
u = None u = None
return u return u
@@ -34,7 +35,7 @@ class CustomOIDCBackend(OIDCAuthenticationBackend):
print("no cache found for userinfo-{access_token} yet.") print("no cache found for userinfo-{access_token} yet.")
userinfo = super().get_userinfo(access_token, id_token, payload) userinfo = super().get_userinfo(access_token, id_token, payload)
if userinfo: if userinfo:
cache.set(f'userinfo-{access_token}', userinfo, timeout=60*60*24) cache.set(f'userinfo-{access_token}', userinfo, timeout=settings.OIDC_CACHE_USERINFO)
return userinfo return userinfo
def update_user(self, user, claims): # TODO: update groups? def update_user(self, user, claims): # TODO: update groups?

View File

View File

@@ -13,6 +13,7 @@ services:
- ./sde:/app/sde - ./sde:/app/sde
- ./authentication:/app/authentication - ./authentication:/app/authentication
- ./manage.py:/app/manage.py - ./manage.py:/app/manage.py
- ./static:/app/static
command: sh -c "python manage.py makemigrations && python manage.py migrate" command: sh -c "python manage.py makemigrations && python manage.py migrate"
depends_on: depends_on:
db: db:
@@ -32,6 +33,7 @@ services:
- ./authentication:/app/authentication - ./authentication:/app/authentication
- ./manage.py:/app/manage.py - ./manage.py:/app/manage.py
- ./static_eve:/app/static_eve - ./static_eve:/app/static_eve
- ./static:/app/static
command: ["uvicorn", "marbas.asgi:application", "--host", "0.0.0.0", "--port", "8000", "--reload"] command: ["uvicorn", "marbas.asgi:application", "--host", "0.0.0.0", "--port", "8000", "--reload"]
healthcheck: healthcheck:
test: python manage.py health_check test: python manage.py health_check

View File

@@ -45,7 +45,7 @@ REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
'DEFAULT_AUTHENTICATION_CLASSES': [ 'DEFAULT_AUTHENTICATION_CLASSES': [
'mozilla_django_oidc.contrib.drf.OIDCAuthentication', 'mozilla_django_oidc.contrib.drf.OIDCAuthentication',
# 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.SessionAuthentication',
], ],
} }
@@ -162,6 +162,7 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/ # https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_ROOT = 'static/'
STATIC_URL = 'static/' STATIC_URL = 'static/'
# Default primary key field type # Default primary key field type
@@ -184,3 +185,4 @@ if WN := os.getenv("OIDC_WELLKNOWN"):
OIDC_OP_AUTHORIZATION_ENDPOINT = oauth_conf["authorization_endpoint"] OIDC_OP_AUTHORIZATION_ENDPOINT = oauth_conf["authorization_endpoint"]
OIDC_OP_TOKEN_ENDPOINT = oauth_conf["token_endpoint"] OIDC_OP_TOKEN_ENDPOINT = oauth_conf["token_endpoint"]
OIDC_OP_USER_ENDPOINT = oauth_conf["userinfo_endpoint"] OIDC_OP_USER_ENDPOINT = oauth_conf["userinfo_endpoint"]
OIDC_CACHE_USERINFO = os.getenv("OIDC_CACHE_USERINFO")

View File

@@ -15,6 +15,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.urls import include, path from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from rest_framework.schemas import get_schema_view from rest_framework.schemas import get_schema_view
from django.views.generic import TemplateView from django.views.generic import TemplateView
@@ -23,6 +26,7 @@ urlpatterns = [
path('api/', include("api.urls")), path('api/', include("api.urls")),
path('sde/', include("sde.urls")), path('sde/', include("sde.urls")),
path('auth/', include("authentication.urls")), path('auth/', include("authentication.urls")),
path('admin/', admin.site.urls),
path('sso/', include('esi.urls', namespace='esi')), path('sso/', include('esi.urls', namespace='esi')),
path('openapi/', get_schema_view( path('openapi/', get_schema_view(
title="marbas", title="marbas",
@@ -38,4 +42,4 @@ urlpatterns = [
extra_context={'schema_url': 'openapi-schema'} extra_context={'schema_url': 'openapi-schema'}
), name='redoc'), ), name='redoc'),
path('ht/', include('health_check.urls')), path('ht/', include('health_check.urls')),
] ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)