This commit is contained in:
j3d1 2023-12-13 08:09:29 +01:00
parent 8d55b00027
commit ea27165e25
13 changed files with 162 additions and 34 deletions

View 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)

View file

@ -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)

View file

@ -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)

View file

@ -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]})

View file

@ -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'

View file

@ -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]})

View file

@ -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:

View file

@ -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]})

View file

@ -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)

View file

@ -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]})

View file

@ -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]})

View file

@ -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

View file

@ -20,11 +20,20 @@ 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); const message = `
}); <h3>Access denied.</h3>
<p>
axios.interceptors.response.use(response => response, error => { 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.log('error interceptor fired');
console.error(error); // todo: toast error console.error(error); // todo: toast error
console.log(Object.entries(error)); console.log(Object.entries(error));
@ -45,6 +54,7 @@ axios.interceptors.response.use(response => response, error => {
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}) {
try {
const {data} = await axios.get(`/2/${getters.getEventSlug}/items/`); const {data} = await axios.get(`/2/${getters.getEventSlug}/items/`);
commit('replaceLoadedItems', data); 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);