diff --git a/.env b/.env index 516bcd21..b417a490 100644 --- a/.env +++ b/.env @@ -10,4 +10,4 @@ WO_DEBUG=NO WO_DEV=NO WO_BROKER=redis://broker WO_DEFAULT_NODES=1 -WO_EXTERNAL_AUTH_ENDPOINT= +WO_SETTINGS= diff --git a/app/api/admin.py b/app/api/admin.py index 2de55e4d..15e136a2 100644 --- a/app/api/admin.py +++ b/app/api/admin.py @@ -58,6 +58,7 @@ class ProfileSerializer(serializers.ModelSerializer): read_only_fields = ('user', ) class AdminProfileViewSet(viewsets.ModelViewSet): + pagination_class = None serializer_class = ProfileSerializer permission_classes = [IsAdminUser] lookup_field = 'user' diff --git a/app/api/externalauth.py b/app/api/externalauth.py index dcc96a60..8a77c71a 100644 --- a/app/api/externalauth.py +++ b/app/api/externalauth.py @@ -36,3 +36,32 @@ class ExternalTokenAuth(APIView): return Response({'error': res.get('message', 'Invalid external server response')}) except Exception as e: return Response({'error': str(e)}) + +# TODO: move to simple http server +# class TestExternalAuth(APIView): +# permission_classes = (permissions.AllowAny,) +# parser_classes = (parsers.JSONParser, parsers.FormParser,) + +# def post(self, request): +# print("YO!!!") +# if settings.EXTERNAL_AUTH_ENDPOINT == '': +# return Response({'message': 'Disabled'}) + +# username = request.data.get("username") +# password = request.data.get("password") + +# print("HERE", username) + +# if username == "extuser1" and password == "test1234": +# return Response({ +# 'user_id': 100, +# 'username': 'extuser1', +# 'maxQuota': 500, +# 'token': 'test', +# 'node': { +# 'hostname': 'localhost', +# 'port': 4444 +# } +# }) +# else: +# return Response({'message': "Invalid credentials"}) \ No newline at end of file diff --git a/app/tests/test_api_admin.py b/app/tests/test_api_admin.py index 7ba0fa28..7a0d1f7f 100644 --- a/app/tests/test_api_admin.py +++ b/app/tests/test_api_admin.py @@ -1,3 +1,4 @@ +import time from django.contrib.auth.models import User, Group from rest_framework import status from rest_framework.test import APIClient @@ -202,3 +203,57 @@ class TestApi(BootTestCase): res = client.delete('/api/admin/groups/{}/'.format(group.id)) self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + def test_profile(self): + client = APIClient() + client.login(username="testuser", password="test1234") + + user = User.objects.get(username="testuser") + + # Cannot list profiles (not admin) + res = client.get('/api/admin/profiles/') + self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + + res = client.get('/api/admin/profiles/%s/' % user.id) + self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + + # Cannot update quota deadlines + res = client.post('/api/admin/profiles/%s/update_quota_deadline/' % user.id, data={'hours': 1}) + self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + + # Admin can + client.login(username="testsuperuser", password="test1234") + + res = client.get('/api/admin/profiles/') + self.assertEqual(res.status_code, status.HTTP_200_OK) + self.assertTrue(len(res.data) > 0) + + res = client.get('/api/admin/profiles/%s/' % user.id) + self.assertEqual(res.status_code, status.HTTP_200_OK) + self.assertTrue('quota' in res.data) + self.assertTrue('user' in res.data) + + # User is the primary key (not profile id) + self.assertEqual(res.data['user'], user.id) + + # There should be no quota by default + self.assertEqual(res.data['quota'], -1) + + # Try updating + user.profile.quota = 10 + user.save() + res = client.get('/api/admin/profiles/%s/' % user.id) + self.assertEqual(res.data['quota'], 10) + + # Update quota deadlines + + # Miss parameters + res = client.post('/api/admin/profiles/%s/update_quota_deadline/' % user.id) + self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST) + + res = client.post('/api/admin/profiles/%s/update_quota_deadline/' % user.id, data={'hours': 48}) + self.assertEqual(res.status_code, status.HTTP_200_OK) + self.assertTrue('deadline' in res.data and res.data['deadline'] > time.time() + 47*60*60) + + res = client.post('/api/admin/profiles/%s/update_quota_deadline/' % user.id, data={'hours': 0}) + self.assertEqual(res.status_code, status.HTTP_200_OK) + self.assertTrue(abs(user.profile.get_quota_deadline() - time.time()) < 10) diff --git a/app/tests/test_external_auth.py b/app/tests/test_external_auth.py new file mode 100644 index 00000000..90dcda3f --- /dev/null +++ b/app/tests/test_external_auth.py @@ -0,0 +1,68 @@ +from django.contrib.auth.models import User, Group +from rest_framework import status +from rest_framework.test import APIClient + +from .classes import BootTestCase +from webodm import settings + +class TestAuth(BootTestCase): + def setUp(self): + pass + + def tearDown(self): + pass + + def test_ext_auth(self): + client = APIClient() + + # Disable + settings.EXTERNAL_AUTH_ENDPOINT = '' + + # Try to log-in + user = client.login(username='extuser1', password='test1234') + self.assertFalse(user) + + # Enable + settings.EXTERNAL_AUTH_ENDPOINT = 'http://0.0.0.0:5555' + + # TODO: start simplehttp auth server + + user = client.login(username='extuser1', password='test1234') + # self.assertEqual(user.username, 'extuser1') + # self.assertEqual(user.id, 100) + + + # client.login(username="testuser", password="test1234") + + # user = User.objects.get(username="testuser") + + # # Cannot list profiles (not admin) + # res = client.get('/api/admin/profiles/') + # self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + + # res = client.get('/api/admin/profiles/%s/' % user.id) + # self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + + # # Cannot update quota deadlines + # res = client.post('/api/admin/profiles/%s/update_quota_deadline/' % user.id, data={'hours': 1}) + # self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN) + + # # Admin can + # client.login(username="testsuperuser", password="test1234") + + # res = client.get('/api/admin/profiles/') + # self.assertEqual(res.status_code, status.HTTP_200_OK) + # self.assertTrue(len(res.data) > 0) + + # res = client.get('/api/admin/profiles/%s/' % user.id) + # self.assertEqual(res.status_code, status.HTTP_200_OK) + # self.assertTrue('quota' in res.data) + # self.assertTrue('user' in res.data) + + # # User is the primary key (not profile id) + # self.assertEqual(res.data['user'], user.id) + + # # There should be no quota by default + # self.assertEqual(res.data['quota'], -1) + + \ No newline at end of file diff --git a/webodm/settings.py b/webodm/settings.py index a09aba70..74f79cf0 100644 --- a/webodm/settings.py +++ b/webodm/settings.py @@ -401,6 +401,7 @@ QUOTA_EXCEEDED_GRACE_PERIOD = 8 if TESTING or FLUSHING: CELERY_TASK_ALWAYS_EAGER = True + EXTERNAL_AUTH_ENDPOINT = '/_test-external-auth' try: from .local_settings import *