stash
This commit is contained in:
parent
8d55b00027
commit
ea27165e25
13 changed files with 162 additions and 34 deletions
19
core/authentication/admin.py
Normal file
19
core/authentication/admin.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
|
from authentication.models import ExtendedUser, EventPermission, ExtendedAuthToken, AuthTokenEventPermissions
|
||||||
|
|
||||||
|
|
||||||
|
class ExtendedUserAdmin(UserAdmin):
|
||||||
|
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_superuser')
|
||||||
|
search_fields = ('username', 'email', 'first_name', 'last_name')
|
||||||
|
ordering = ('username',)
|
||||||
|
filter_horizontal = ('groups', 'user_permissions', 'permissions')
|
||||||
|
|
||||||
|
def permissions(self, obj):
|
||||||
|
return ', '.join(obj.get_all_permissions())
|
||||||
|
|
||||||
|
|
||||||
|
admin.site.register(ExtendedUser, ExtendedUserAdmin)
|
|
@ -1,5 +1,7 @@
|
||||||
from rest_framework import routers, viewsets, serializers, permissions
|
from rest_framework import routers, viewsets, serializers, permissions
|
||||||
from rest_framework.decorators import api_view, permission_classes, authentication_classes
|
from rest_framework.decorators import api_view, permission_classes, authentication_classes
|
||||||
|
from rest_framework.authtoken.serializers import AuthTokenSerializer
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.contrib.auth import login
|
from django.contrib.auth import login
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
@ -7,7 +9,6 @@ from django.dispatch import receiver
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from knox.models import AuthToken
|
from knox.models import AuthToken
|
||||||
from knox.views import LoginView as KnoxLoginView
|
from knox.views import LoginView as KnoxLoginView
|
||||||
from rest_framework.authtoken.serializers import AuthTokenSerializer
|
|
||||||
|
|
||||||
from authentication.models import ExtendedUser
|
from authentication.models import ExtendedUser
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ class UserViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
|
|
||||||
@api_view(['POST'])
|
@api_view(['POST'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
def selfUser(request):
|
def selfUser(request):
|
||||||
serializer = UserSerializer(request.user)
|
serializer = UserSerializer(request.user)
|
||||||
return Response(serializer.data, status=200)
|
return Response(serializer.data, status=200)
|
||||||
|
|
|
@ -10,6 +10,7 @@ class PermissionsTestCase(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
event1 = Event.objects.create(slug='testevent1', name='testevent1')
|
event1 = Event.objects.create(slug='testevent1', name='testevent1')
|
||||||
event2 = Event.objects.create(slug='testevent2', name='testevent2')
|
event2 = Event.objects.create(slug='testevent2', name='testevent2')
|
||||||
permission1 = Permission.objects.get(codename='view_event')
|
permission1 = Permission.objects.get(codename='view_event')
|
||||||
|
@ -17,6 +18,9 @@ class PermissionsTestCase(TestCase):
|
||||||
EventPermission.objects.create(user=self.user, permission=permission1, event=event2)
|
EventPermission.objects.create(user=self.user, permission=permission1, event=event2)
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
self.newuser = ExtendedUser.objects.create_user('newuser', 'test', 'test')
|
||||||
|
self.newuser_token = AuthToken.objects.create(user=self.newuser)
|
||||||
|
self.newuser_client = Client(headers={'Authorization': 'Token ' + self.newuser_token[1]})
|
||||||
|
|
||||||
def test_user_permissions(self):
|
def test_user_permissions(self):
|
||||||
"""
|
"""
|
||||||
|
@ -24,7 +28,7 @@ class PermissionsTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
response = self.client.get('/api/2/users/')
|
response = self.client.get('/api/2/users/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(len(response.json()), 2)
|
self.assertEqual(len(response.json()), 3)
|
||||||
self.assertEqual(response.json()[0]['username'], 'legacy_user')
|
self.assertEqual(response.json()[0]['username'], 'legacy_user')
|
||||||
self.assertEqual(response.json()[0]['email'], 'mail@localhost')
|
self.assertEqual(response.json()[0]['email'], 'mail@localhost')
|
||||||
self.assertEqual(response.json()[0]['first_name'], '')
|
self.assertEqual(response.json()[0]['first_name'], '')
|
||||||
|
@ -34,3 +38,54 @@ class PermissionsTestCase(TestCase):
|
||||||
self.assertEqual(response.json()[1]['email'], 'test')
|
self.assertEqual(response.json()[1]['email'], 'test')
|
||||||
self.assertEqual(response.json()[1]['first_name'], '')
|
self.assertEqual(response.json()[1]['first_name'], '')
|
||||||
self.assertEqual(response.json()[1]['last_name'], '')
|
self.assertEqual(response.json()[1]['last_name'], '')
|
||||||
|
|
||||||
|
def test_user_permission(self):
|
||||||
|
"""
|
||||||
|
Test that a user can only access their own data.
|
||||||
|
"""
|
||||||
|
#ä['add_logentry', 'change_logentry', 'delete_logentry', 'view_logentry', 'add_group', 'change_group',
|
||||||
|
#ä 'delete_group', 'view_group', 'add_permission', 'change_permission', 'delete_permission', 'view_permission',
|
||||||
|
#ä 'add_authtokeneventpermissions', 'change_authtokeneventpermissions', 'delete_authtokeneventpermissions',
|
||||||
|
#ä 'view_authtokeneventpermissions', 'add_eventpermission', 'change_eventpermission', 'delete_eventpermission',
|
||||||
|
#ä 'view_eventpermission', 'add_extendedauthtoken', 'change_extendedauthtoken', 'delete_extendedauthtoken',
|
||||||
|
#ä 'view_extendedauthtoken', 'add_extendeduser', 'change_extendeduser', 'delete_extendeduser',
|
||||||
|
#ä 'view_extendeduser', 'add_contenttype', 'change_contenttype', 'delete_contenttype', 'view_contenttype',
|
||||||
|
#ä 'add_file', 'change_file', 'delete_file', 'view_file', 'add_container', 'change_container', 'delete_container',
|
||||||
|
#ä 'view_container', 'add_event', 'change_event', 'delete_event', 'view_event', 'add_item', 'change_item',
|
||||||
|
#ä 'delete_item', 'match_item', 'view_item', 'add_authtoken', 'change_authtoken', 'delete_authtoken',
|
||||||
|
#ä 'view_authtoken', 'add_email', 'change_email', 'delete_email', 'view_email', 'add_eventaddress',
|
||||||
|
#ä 'change_eventaddress', 'delete_eventaddress', 'view_eventaddress', 'add_systemevent', 'change_systemevent',
|
||||||
|
#ä 'delete_systemevent', 'view_systemevent', 'add_session', 'change_session', 'delete_session', 'view_session',
|
||||||
|
#ä 'add_comment', 'change_comment', 'delete_comment', 'view_comment', 'add_issuethread', 'change_issuethread',
|
||||||
|
#ä 'delete_issuethread', 'send_mail', 'view_issuethread', 'add_statechange', 'change_statechange',
|
||||||
|
#ä 'delete_statechange', 'view_statechange']
|
||||||
|
|
||||||
|
user = ExtendedUser.objects.create_user('testuser2', 'test', 'test')
|
||||||
|
user.event_permissions.create(permission=Permission.objects.get(codename='view_item'), event=Event.objects.get(slug='testevent1'))
|
||||||
|
user.event_permissions.create(permission=Permission.objects.get(codename='view_item'), event=Event.objects.get(slug='testevent2'))
|
||||||
|
user.event_permissions.create(permission=Permission.objects.get(codename='add_item'), event=Event.objects.get(slug='testevent1'))
|
||||||
|
user.save()
|
||||||
|
print(user.get_all_permissions())
|
||||||
|
#self.assertTrue(user.has_perm('inventory.view_event', Event.objects.get(slug='testevent1')))
|
||||||
|
#self.assertTrue(user.has_perm('inventory.view_event', Event.objects.get(slug='testevent2')))
|
||||||
|
#self.assertFalse(user.has_perm('inventory.add_event', Event.objects.get(slug='testevent1')))
|
||||||
|
#self.assertFalse(user.has_perm('inventory.add_event', Event.objects.get(slug='testevent2')))
|
||||||
|
|
||||||
|
def test_item_api_permissions(self):
|
||||||
|
"""
|
||||||
|
Test that a user can only access their own data.
|
||||||
|
"""
|
||||||
|
response = self.client.get('/api/2/testevent1/items/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertEqual(len(response.json()), 0)
|
||||||
|
|
||||||
|
response = self.client.get('/api/2/testevent2/items/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertEqual(len(response.json()), 0)
|
||||||
|
|
||||||
|
response = self.newuser_client.get('/api/2/testevent1/items/')
|
||||||
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
|
response = self.newuser_client.get('/api/2/testevent2/items/')
|
||||||
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
from knox.models import AuthToken
|
from knox.models import AuthToken
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ class UserApiTest(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
|
|
@ -65,7 +65,8 @@ INSTALLED_APPS = [
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
|
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication',),
|
'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication',),
|
||||||
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
|
'DEFAULT_PERMISSION_CLASSES': (
|
||||||
|
'rest_framework.permissions.IsAuthenticated', 'rest_framework.permissions.DjangoModelPermissions'),
|
||||||
}
|
}
|
||||||
|
|
||||||
AUTH_USER_MODEL = 'authentication.ExtendedUser'
|
AUTH_USER_MODEL = 'authentication.ExtendedUser'
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
from authentication.models import ExtendedUser
|
from authentication.models import ExtendedUser
|
||||||
from files.models import File
|
from files.models import File
|
||||||
|
@ -11,6 +12,7 @@ class FileTestCase(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
@ -38,8 +40,8 @@ class FileTestCase(TestCase):
|
||||||
Item.objects.create(container=self.box, event=self.event, description='1')
|
Item.objects.create(container=self.box, event=self.event, description='1')
|
||||||
item = Item.objects.create(container=self.box, event=self.event, description='2')
|
item = Item.objects.create(container=self.box, event=self.event, description='2')
|
||||||
response = self.client.post('/api/2/files/',
|
response = self.client.post('/api/2/files/',
|
||||||
{'data': "data:text/plain;base64," + base64.b64encode(b"foo").decode('utf-8')},
|
{'data': "data:text/plain;base64," + base64.b64encode(b"foo").decode('utf-8')},
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
self.assertEqual(response.status_code, 201)
|
self.assertEqual(response.status_code, 201)
|
||||||
self.assertEqual(len(response.json()['hash']), 64)
|
self.assertEqual(len(response.json()['hash']), 64)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.urls import path, re_path
|
from django.urls import path, re_path
|
||||||
|
from django.contrib.auth.decorators import permission_required
|
||||||
from rest_framework import routers, viewsets, serializers
|
from rest_framework import routers, viewsets, serializers
|
||||||
from rest_framework.decorators import api_view, permission_classes, authentication_classes
|
from rest_framework.decorators import api_view, permission_classes
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
from files.models import File
|
from files.models import File
|
||||||
from inventory.models import Event, Container, Item
|
from inventory.models import Event, Container, Item
|
||||||
|
@ -37,7 +39,6 @@ class ContainerSerializer(serializers.ModelSerializer):
|
||||||
class ContainerViewSet(viewsets.ModelViewSet):
|
class ContainerViewSet(viewsets.ModelViewSet):
|
||||||
serializer_class = ContainerSerializer
|
serializer_class = ContainerSerializer
|
||||||
queryset = Container.objects.all()
|
queryset = Container.objects.all()
|
||||||
permission_classes = []
|
|
||||||
|
|
||||||
|
|
||||||
class ItemSerializer(serializers.ModelSerializer):
|
class ItemSerializer(serializers.ModelSerializer):
|
||||||
|
@ -95,6 +96,8 @@ class ItemSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
@permission_required('inventory.view_item', raise_exception=True)
|
||||||
def search_items(request, event_slug, query):
|
def search_items(request, event_slug, query):
|
||||||
try:
|
try:
|
||||||
event = Event.objects.get(slug=event_slug)
|
event = Event.objects.get(slug=event_slug)
|
||||||
|
@ -109,12 +112,17 @@ def search_items(request, event_slug, query):
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET', 'POST'])
|
@api_view(['GET', 'POST'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
def item(request, event_slug):
|
def item(request, event_slug):
|
||||||
try:
|
try:
|
||||||
event = Event.objects.get(slug=event_slug)
|
event = Event.objects.get(slug=event_slug)
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
if not request.user.has_event_perm(event, 'inventory.view_item'):
|
||||||
|
return Response(status=403)
|
||||||
return Response(ItemSerializer(Item.objects.filter(event=event), many=True).data)
|
return Response(ItemSerializer(Item.objects.filter(event=event), many=True).data)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
|
if not request.user.has_event_perm(event, 'inventory.add_item'):
|
||||||
|
return Response(status=403)
|
||||||
validated_data = ItemSerializer(data=request.data)
|
validated_data = ItemSerializer(data=request.data)
|
||||||
if validated_data.is_valid():
|
if validated_data.is_valid():
|
||||||
validated_data.save(event=event)
|
validated_data.save(event=event)
|
||||||
|
@ -124,18 +132,25 @@ def item(request, event_slug):
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET', 'PUT', 'DELETE'])
|
@api_view(['GET', 'PUT', 'DELETE'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
def item_by_id(request, event_slug, id):
|
def item_by_id(request, event_slug, id):
|
||||||
try:
|
try:
|
||||||
event = Event.objects.get(slug=event_slug)
|
event = Event.objects.get(slug=event_slug)
|
||||||
item = Item.objects.get(event=event, uid=id)
|
item = Item.objects.get(event=event, uid=id)
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
if not request.user.has_event_perm(event, 'inventory.view_item'):
|
||||||
|
return Response(status=403)
|
||||||
return Response(ItemSerializer(item).data)
|
return Response(ItemSerializer(item).data)
|
||||||
elif request.method == 'PUT':
|
elif request.method == 'PUT':
|
||||||
|
if not request.user.has_event_perm(event, 'inventory.change_item'):
|
||||||
|
return Response(status=403)
|
||||||
validated_data = ItemSerializer(item, data=request.data)
|
validated_data = ItemSerializer(item, data=request.data)
|
||||||
if validated_data.is_valid():
|
if validated_data.is_valid():
|
||||||
validated_data.save()
|
validated_data.save()
|
||||||
return Response(validated_data.data)
|
return Response(validated_data.data)
|
||||||
elif request.method == 'DELETE':
|
elif request.method == 'DELETE':
|
||||||
|
if not request.user.has_event_perm(event, 'inventory.delete_item'):
|
||||||
|
return Response(status=403)
|
||||||
item.delete()
|
item.delete()
|
||||||
return Response(status=204)
|
return Response(status=204)
|
||||||
except Item.DoesNotExist:
|
except Item.DoesNotExist:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
from knox.models import AuthToken
|
from knox.models import AuthToken
|
||||||
|
|
||||||
from authentication.models import ExtendedUser
|
from authentication.models import ExtendedUser
|
||||||
|
@ -9,6 +10,7 @@ class ApiTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
from inventory.models import Container
|
from django.contrib.auth.models import Permission
|
||||||
|
from knox.models import AuthToken
|
||||||
|
|
||||||
client = Client()
|
from authentication.models import ExtendedUser
|
||||||
|
from inventory.models import Container
|
||||||
|
|
||||||
|
|
||||||
class ContainerTestCase(TestCase):
|
class ContainerTestCase(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
|
||||||
def test_empty(self):
|
def test_empty(self):
|
||||||
response = client.get('/api/2/boxes/')
|
response = self.client.get('/api/2/boxes/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.json(), [])
|
self.assertEqual(response.json(), [])
|
||||||
|
|
||||||
def test_members(self):
|
def test_members(self):
|
||||||
Container.objects.create(name='BOX')
|
Container.objects.create(name='BOX')
|
||||||
response = client.get('/api/2/boxes/')
|
response = self.client.get('/api/2/boxes/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(len(response.json()), 1)
|
self.assertEqual(len(response.json()), 1)
|
||||||
self.assertEqual(response.json()[0]['cid'], 1)
|
self.assertEqual(response.json()[0]['cid'], 1)
|
||||||
|
@ -24,12 +32,12 @@ class ContainerTestCase(TestCase):
|
||||||
Container.objects.create(name='BOX 1')
|
Container.objects.create(name='BOX 1')
|
||||||
Container.objects.create(name='BOX 2')
|
Container.objects.create(name='BOX 2')
|
||||||
Container.objects.create(name='BOX 3')
|
Container.objects.create(name='BOX 3')
|
||||||
response = client.get('/api/2/boxes/')
|
response = self.client.get('/api/2/boxes/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(len(response.json()), 3)
|
self.assertEqual(len(response.json()), 3)
|
||||||
|
|
||||||
def test_create_container(self):
|
def test_create_container(self):
|
||||||
response = client.post('/api/2/box/', {'name': 'BOX'})
|
response = self.client.post('/api/2/box/', {'name': 'BOX'})
|
||||||
self.assertEqual(response.status_code, 201)
|
self.assertEqual(response.status_code, 201)
|
||||||
self.assertEqual(response.json()['cid'], 1)
|
self.assertEqual(response.json()['cid'], 1)
|
||||||
self.assertEqual(response.json()['name'], 'BOX')
|
self.assertEqual(response.json()['name'], 'BOX')
|
||||||
|
@ -39,9 +47,8 @@ class ContainerTestCase(TestCase):
|
||||||
self.assertEqual(Container.objects.all()[0].name, 'BOX')
|
self.assertEqual(Container.objects.all()[0].name, 'BOX')
|
||||||
|
|
||||||
def test_update_container(self):
|
def test_update_container(self):
|
||||||
from rest_framework.test import APIClient
|
|
||||||
box = Container.objects.create(name='BOX 1')
|
box = Container.objects.create(name='BOX 1')
|
||||||
response = APIClient().put(f'/api/2/box/{box.cid}/', {'name': 'BOX 2'})
|
response = self.client.put(f'/api/2/box/{box.cid}/', {'name': 'BOX 2'}, content_type='application/json')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.json()['cid'], 1)
|
self.assertEqual(response.json()['cid'], 1)
|
||||||
self.assertEqual(response.json()['name'], 'BOX 2')
|
self.assertEqual(response.json()['name'], 'BOX 2')
|
||||||
|
@ -54,6 +61,6 @@ class ContainerTestCase(TestCase):
|
||||||
box = Container.objects.create(name='BOX 1')
|
box = Container.objects.create(name='BOX 1')
|
||||||
Container.objects.create(name='BOX 2')
|
Container.objects.create(name='BOX 2')
|
||||||
self.assertEqual(len(Container.objects.all()), 2)
|
self.assertEqual(len(Container.objects.all()), 2)
|
||||||
response = client.delete(f'/api/2/box/{box.cid}/')
|
response = self.client.delete(f'/api/2/box/{box.cid}/')
|
||||||
self.assertEqual(response.status_code, 204)
|
self.assertEqual(response.status_code, 204)
|
||||||
self.assertEqual(len(Container.objects.all()), 1)
|
self.assertEqual(len(Container.objects.all()), 1)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
from knox.models import AuthToken
|
from knox.models import AuthToken
|
||||||
|
|
||||||
from authentication.models import ExtendedUser
|
from authentication.models import ExtendedUser
|
||||||
|
@ -13,6 +14,7 @@ class ItemTestCase(TestCase):
|
||||||
self.event = Event.objects.create(slug='EVENT', name='Event')
|
self.event = Event.objects.create(slug='EVENT', name='Event')
|
||||||
self.box = Container.objects.create(name='BOX')
|
self.box = Container.objects.create(name='BOX')
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import inspect
|
import inspect
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from knox.models import AuthToken
|
|
||||||
|
|
||||||
from django.test import TestCase, Client
|
from django.test import TestCase, Client
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
from knox.models import AuthToken
|
||||||
|
|
||||||
from authentication.models import ExtendedUser
|
from authentication.models import ExtendedUser
|
||||||
from core.settings import MAIL_DOMAIN
|
from core.settings import MAIL_DOMAIN
|
||||||
|
@ -28,6 +29,7 @@ class EmailsApiTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
@ -62,6 +64,7 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||||
|
self.user.user_permissions.add(*Permission.objects.all())
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.token = AuthToken.objects.create(user=self.user)
|
self.token = AuthToken.objects.create(user=self.user)
|
||||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from rest_framework.decorators import api_view, permission_classes, authentication_classes
|
from django.contrib.auth.decorators import permission_required
|
||||||
from rest_framework import routers, viewsets, serializers, status
|
from rest_framework import routers, viewsets, serializers, status
|
||||||
|
from rest_framework.decorators import api_view, permission_classes
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from asgiref.sync import async_to_sync
|
from asgiref.sync import async_to_sync
|
||||||
|
|
||||||
|
@ -56,6 +58,8 @@ class IssueViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
|
|
||||||
@api_view(['POST'])
|
@api_view(['POST'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
@permission_required('tickets.add_issuethread', raise_exception=True)
|
||||||
def reply(request, pk):
|
def reply(request, pk):
|
||||||
issue = IssueThread.objects.get(pk=pk)
|
issue = IssueThread.objects.get(pk=pk)
|
||||||
# email = issue.reply(request.data['body']) # TODO evaluate if this is a useful abstraction
|
# email = issue.reply(request.data['body']) # TODO evaluate if this is a useful abstraction
|
||||||
|
|
|
@ -20,17 +20,26 @@ axios.interceptors.response.use(response => response, error => {
|
||||||
return axios.request(error.config);
|
return axios.request(error.config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else
|
} else if (error.response.status === 403) {
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
axios.interceptors.response.use(response => response, error => {
|
|
||||||
console.log('error interceptor fired');
|
|
||||||
console.error(error); // todo: toast error
|
|
||||||
console.log(Object.entries(error));
|
|
||||||
|
|
||||||
if (error.isAxiosError) {
|
|
||||||
const message = `
|
const message = `
|
||||||
|
<h3>Access denied.</h3>
|
||||||
|
<p>
|
||||||
|
url: ${error.config.url}
|
||||||
|
<br>
|
||||||
|
method: ${error.config.method}
|
||||||
|
<br>
|
||||||
|
response-body: ${error.response && error.response.body}
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
store.commit('createToast', {title: 'Error: Access denied', message, color: 'danger'});
|
||||||
|
return Promise.reject(error)
|
||||||
|
} else {
|
||||||
|
console.log('error interceptor fired');
|
||||||
|
console.error(error); // todo: toast error
|
||||||
|
console.log(Object.entries(error));
|
||||||
|
|
||||||
|
if (error.isAxiosError) {
|
||||||
|
const message = `
|
||||||
<h3>A HTTP ${error.config.method} request failed.</h3>
|
<h3>A HTTP ${error.config.method} request failed.</h3>
|
||||||
<p>
|
<p>
|
||||||
url: ${error.config.url}
|
url: ${error.config.url}
|
||||||
|
@ -40,11 +49,12 @@ axios.interceptors.response.use(response => response, error => {
|
||||||
response-body: ${error.response && error.response.body}
|
response-body: ${error.response && error.response.body}
|
||||||
</p>
|
</p>
|
||||||
`;
|
`;
|
||||||
store.commit('createToast', {title: 'Error: HTTP', message, color: 'danger'});
|
store.commit('createToast', {title: 'Error: HTTP', message, color: 'danger'});
|
||||||
} else {
|
} else {
|
||||||
store.commit('createToast', {title: 'Error: Unknown', message: error.toString(), color: 'danger'});
|
store.commit('createToast', {title: 'Error: Unknown', message: error.toString(), color: 'danger'});
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
|
@ -226,8 +236,12 @@ const store = new Vuex.Store({
|
||||||
router.push({path: `/${getters.getEventSlug}/items/`, query: {box}});
|
router.push({path: `/${getters.getEventSlug}/items/`, query: {box}});
|
||||||
},
|
},
|
||||||
async loadEventItems({commit, getters}) {
|
async loadEventItems({commit, getters}) {
|
||||||
const {data} = await axios.get(`/2/${getters.getEventSlug}/items/`);
|
try {
|
||||||
commit('replaceLoadedItems', data);
|
const {data} = await axios.get(`/2/${getters.getEventSlug}/items/`);
|
||||||
|
commit('replaceLoadedItems', data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error loading items");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async searchEventItems({commit, getters}, query) {
|
async searchEventItems({commit, getters}, query) {
|
||||||
const foo = utf8.encode(query);
|
const foo = utf8.encode(query);
|
||||||
|
|
Loading…
Reference in a new issue