Skip to content
Merged
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
2 changes: 1 addition & 1 deletion pyobs_archive/api/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


class QueryConfig(AppConfig):
name = 'pyobs_archive.archive'
name = 'pyobs_archive.api'
2 changes: 1 addition & 1 deletion pyobs_archive/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def get_info(self):
info['related_frames'] = [f.id for f in self.related.all()]

# add url
info['url'] = urljoin(settings.ROOT_URL, 'frames/%d/download/' % self.id)
info['url'] = 'frames/%d/download/' % self.id

# finished
return info
Expand Down
48 changes: 10 additions & 38 deletions pyobs_archive/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
from astropy.io import fits
from django.conf import settings
from django.db.models import F
from rest_framework import exceptions
from rest_framework.decorators import permission_classes, authentication_classes, api_view
from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import permission_classes, api_view
from rest_framework.permissions import IsAdminUser, IsAuthenticated

from pyobs_archive.api.models import Frame
Expand All @@ -22,23 +20,6 @@
log = logging.getLogger(__name__)


# define classes for authentication
if settings.TOKEN_AUTH is None:
AUTH_CLASSES = []
POST_AUTH_CLASSES = []
AUTHENTICATED = []
else:
class PostAuthentication(settings.TOKEN_AUTH):
def authenticate(self, request):
if 'auth_token' not in request.POST:
raise exceptions.AuthenticationFailed('Missing token.')
token = request.POST['auth_token']
return self.authenticate_credentials(token)
AUTH_CLASSES = [settings.TOKEN_AUTH]
POST_AUTH_CLASSES = [PostAuthentication]
AUTHENTICATED = [IsAuthenticated]


def _frame(frame_id):
# get frame
try:
Expand All @@ -55,7 +36,6 @@ def _frame(frame_id):


@api_view(['POST'])
@authentication_classes(AUTH_CLASSES)
@permission_classes([IsAdminUser])
def create_view(request):
# loop all incoming files
Expand All @@ -78,7 +58,6 @@ def create_view(request):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes([IsAdminUser])
def delete_view(request, frame_id):
# get frame and filename
Expand Down Expand Up @@ -165,8 +144,7 @@ def filter_frames(data, request):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def frames_view(request):
# get offset and limit
offset = request.GET.get('offset', default=None)
Expand Down Expand Up @@ -195,8 +173,7 @@ def frames_view(request):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def aggregate_view(request):
# get response
data = Frame.objects
Expand Down Expand Up @@ -227,17 +204,15 @@ def aggregate_view(request):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def frame_view(request, frame_id):
# get data
frame, filename = _frame(frame_id)
return JsonResponse(frame.get_info())


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def download_view(request, frame_id):
# get frame and filename
frame, filename = _frame(frame_id)
Expand All @@ -251,8 +226,7 @@ def download_view(request, frame_id):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def related_view(request, frame_id):
# get frame
frame, filename = _frame(frame_id)
Expand All @@ -263,8 +237,7 @@ def related_view(request, frame_id):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def headers_view(request, frame_id):
# get frame and filename
frame, filename = _frame(frame_id)
Expand All @@ -278,6 +251,7 @@ def headers_view(request, frame_id):


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def preview_view(request, frame_id):
import matplotlib
matplotlib.use('Agg')
Expand Down Expand Up @@ -317,8 +291,7 @@ def preview_view(request, frame_id):


@api_view(['POST'])
@authentication_classes(POST_AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def zip_view(request):
# get archive root
root = settings.ARCHIVE_ROOT
Expand All @@ -345,8 +318,7 @@ def zip_view(request):


@api_view(['GET'])
@authentication_classes(AUTH_CLASSES)
@permission_classes(AUTHENTICATED)
@permission_classes([IsAuthenticated])
def catalog_view(request, frame_id):
# get frame and filename
frame, filename = _frame(frame_id)
Expand Down
3 changes: 3 additions & 0 deletions pyobs_archive/authentication/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions pyobs_archive/authentication/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class AuthenticationConfig(AppConfig):
name = 'pyobs_archive.authentication'
60 changes: 0 additions & 60 deletions pyobs_archive/authentication/authentication.py

This file was deleted.

72 changes: 72 additions & 0 deletions pyobs_archive/authentication/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from django.contrib.auth.models import User
from pyobs_archive.authentication.models import Profile
from django.conf import settings
from rest_framework import authentication, exceptions
import requests


class OAuth2Backend(object):
"""
Authenticate against the Oauth backend, using
grant_type: password
"""

def authenticate(self, request, username=None, password=None):
if username == 'eng':
return None # disable eng account
response = requests.post(
settings.OAUTH_CLIENT['TOKEN_URL'],
data={
'grant_type': 'password',
'username': username,
'password': password,
'client_id': settings.OAUTH_CLIENT['CLIENT_ID'],
'client_secret': settings.OAUTH_CLIENT['CLIENT_SECRET']
}
)
if response.status_code == 200:
user, _ = User.objects.get_or_create(username=username)
Profile.objects.update_or_create(
user=user,
defaults={
'access_token': response.json()['access_token'],
'refresh_token': response.json()['refresh_token']
}
)
return user
return None

def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None


class BearerAuthentication(authentication.BaseAuthentication):
"""
Allows users to authenticate using the bearer token recieved from
the odin auth server
"""
def authenticate(self, request):
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
if 'Bearer' not in auth_header:
return None

bearer = auth_header.split('Bearer')[1].strip()
response = requests.get(
settings.OAUTH_CLIENT['PROFILE_URL'],
headers={'Authorization': 'Bearer {}'.format(bearer)}
)

if not response.status_code == 200:
raise exceptions.AuthenticationFailed('No Such User')

user, _ = User.objects.get_or_create(username=response.json()['email'])
Profile.objects.update_or_create(
user=user,
defaults={
'access_token': bearer,
}
)
return (user, None)
26 changes: 26 additions & 0 deletions pyobs_archive/authentication/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 3.2.4 on 2021-06-16 09:37

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('access_token', models.CharField(default='', max_length=255)),
('refresh_token', models.CharField(default='', max_length=255)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
Empty file.
21 changes: 21 additions & 0 deletions pyobs_archive/authentication/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
import logging

logger = logging.getLogger()


class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
access_token = models.CharField(max_length=255, default='')
refresh_token = models.CharField(max_length=255, default='')


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
44 changes: 0 additions & 44 deletions pyobs_archive/authentication/serializers.py

This file was deleted.

3 changes: 3 additions & 0 deletions pyobs_archive/authentication/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
Loading