|
|
|
@ -5,6 +5,8 @@ import struct |
|
|
|
|
import time |
|
|
|
|
|
|
|
|
|
from django.contrib.auth.models import User |
|
|
|
|
from django.http import HttpResponse |
|
|
|
|
from django.shortcuts import get_object_or_404, get_list_or_404 |
|
|
|
|
|
|
|
|
|
from rest_framework import mixins, permissions, status, viewsets |
|
|
|
|
from rest_framework.authtoken.models import Token |
|
|
|
@ -12,7 +14,7 @@ from rest_framework.decorators import api_view, permission_classes |
|
|
|
|
from rest_framework.response import Response |
|
|
|
|
|
|
|
|
|
from . import models, serializers |
|
|
|
|
from authserver.settings import PROTOSPACE_LOGIN_PAGE |
|
|
|
|
from authserver.settings import PROTOSPACE_LOGIN_PAGE, FIRMWARE_VERSION_MAGIC |
|
|
|
|
|
|
|
|
|
LOG_DIRECTORY = '/var/log/pslockout' |
|
|
|
|
VALID_TIME = 1000000000 |
|
|
|
@ -44,9 +46,11 @@ class ToolViewSet(viewsets.ModelViewSet): |
|
|
|
|
|
|
|
|
|
class ToolDataViewSet(viewsets.ViewSet): |
|
|
|
|
def list(self, request): |
|
|
|
|
objects = models.Category.objects.all().order_by('id') |
|
|
|
|
serializer = serializers.ToolDataSerializer(objects, many=True, context={'request': request}) |
|
|
|
|
return Response({'categories': serializer.data}) |
|
|
|
|
category_objects = models.Category.objects.all().order_by('id') |
|
|
|
|
categories = serializers.CategoryToolSerializer(category_objects, many=True, context={'request': request}) |
|
|
|
|
course_objects = models.Course.objects.all().order_by('id') |
|
|
|
|
courses = serializers.CourseSerializer(course_objects, many=True, context={'request': request}) |
|
|
|
|
return Response({'categories': categories.data, 'courses': courses.data}) |
|
|
|
|
|
|
|
|
|
class ProfileViewSet( |
|
|
|
|
mixins.RetrieveModelMixin, |
|
|
|
@ -64,10 +68,17 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet): |
|
|
|
|
def get_queryset(self): |
|
|
|
|
return User.objects.filter(username=self.request.user) |
|
|
|
|
|
|
|
|
|
@api_view(["POST"]) |
|
|
|
|
class FirmwareViewSet(viewsets.ModelViewSet): |
|
|
|
|
queryset = models.Firmware.objects.all().order_by('-version') |
|
|
|
|
serializer_class = serializers.FirmwareSerializer |
|
|
|
|
permission_classes = (IsLockoutAdmin,) |
|
|
|
|
lookup_field='version' |
|
|
|
|
http_method_names = ['get', 'post', 'head', 'delete', 'options'] |
|
|
|
|
|
|
|
|
|
@api_view(['POST']) |
|
|
|
|
def login(request): |
|
|
|
|
username = request.data.get("username").lower() |
|
|
|
|
password = request.data.get("password") |
|
|
|
|
username = request.data.get('username').lower() |
|
|
|
|
password = request.data.get('password') |
|
|
|
|
if username is None or password is None: |
|
|
|
|
return Response({'error': 'Please provide both username and password'}, |
|
|
|
|
status=status.HTTP_400_BAD_REQUEST) |
|
|
|
@ -90,14 +101,15 @@ def login(request): |
|
|
|
|
|
|
|
|
|
return Response({'token': token.key}, status=status.HTTP_200_OK) |
|
|
|
|
|
|
|
|
|
@api_view(["GET"]) |
|
|
|
|
@api_view(['GET']) |
|
|
|
|
def cards(request, mac): |
|
|
|
|
cards = models.Card.objects.all().filter(profile__courses__tools__mac=mac) |
|
|
|
|
tool = get_object_or_404(models.Tool, mac=mac) |
|
|
|
|
cards = models.Card.objects.all().filter(profile__courses__tools=tool) |
|
|
|
|
card_numbers = [card.number for card in cards] |
|
|
|
|
|
|
|
|
|
return Response(','.join(card_numbers), status=status.HTTP_200_OK) |
|
|
|
|
|
|
|
|
|
@api_view(["PUT"]) |
|
|
|
|
@api_view(['PUT']) |
|
|
|
|
@permission_classes((IsLockoutAdmin,)) |
|
|
|
|
def update_cards(request): |
|
|
|
|
data = request.data |
|
|
|
@ -124,7 +136,7 @@ def update_cards(request): |
|
|
|
|
return Response({'updated': updated_count}, status=status.HTTP_200_OK) |
|
|
|
|
|
|
|
|
|
EVENTS = [ |
|
|
|
|
'LOG_BOOT_UP - Booted up =============================================', |
|
|
|
|
'LOG_BOOT_UP - =========== Booted up, version: ', |
|
|
|
|
'LOG_INIT_COMPLETE - Initialization completed', |
|
|
|
|
'LOG_WIFI_CONNECTED - Wifi connected', |
|
|
|
|
'LOG_WIFI_DISCONNECTED - Wifi disconnected', |
|
|
|
@ -142,14 +154,17 @@ EVENTS = [ |
|
|
|
|
'LOG_CARD_GOOD_READ - Successful read from card: ', |
|
|
|
|
'LOG_CARD_ACCEPTED - Accepted card: ', |
|
|
|
|
'LOG_CARD_DENIED - Denied card: ', |
|
|
|
|
'LOG_UPDATE_FAILED - Firmware update failed, code: ', |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@api_view(["POST"]) |
|
|
|
|
@api_view(['POST']) |
|
|
|
|
def infolog(request, mac): |
|
|
|
|
entries_processed = 0 |
|
|
|
|
oldest_valid_log_time = time.time() |
|
|
|
|
|
|
|
|
|
tool = get_object_or_404(models.Tool, mac=mac) |
|
|
|
|
|
|
|
|
|
encoded_log = request.data.get('log') |
|
|
|
|
if encoded_log: |
|
|
|
|
decoded_log = base64.b64decode(encoded_log) |
|
|
|
@ -178,9 +193,43 @@ def infolog(request, mac): |
|
|
|
|
entries_processed += 1 |
|
|
|
|
log_file.write(entry_string + '\n') |
|
|
|
|
|
|
|
|
|
version = str(get_object_or_404(models.Firmware, tools=tool)) |
|
|
|
|
version_string = '{} {} {}'.format(FIRMWARE_VERSION_MAGIC, version, FIRMWARE_VERSION_MAGIC) |
|
|
|
|
|
|
|
|
|
response_object = { |
|
|
|
|
'unixTime': int(time.time()), |
|
|
|
|
'processed': entries_processed, |
|
|
|
|
'unixTime': int(time.time()), |
|
|
|
|
'version': version_string, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return Response(response_object, status=status.HTTP_200_OK) |
|
|
|
|
|
|
|
|
|
@api_view(['GET']) |
|
|
|
|
def update(request, mac): |
|
|
|
|
tool = get_object_or_404(models.Tool, mac=mac) |
|
|
|
|
firmware = get_object_or_404(models.Firmware, tools=tool) |
|
|
|
|
|
|
|
|
|
response = HttpResponse(firmware.binary, content_type='text/plain') |
|
|
|
|
response['Content-Disposition'] = 'attachment; filename=firmware_{}.bin'.format(firmware.version) |
|
|
|
|
return response |
|
|
|
|
|
|
|
|
|
@api_view(['PUT']) |
|
|
|
|
@permission_classes((permissions.IsAuthenticated,)) |
|
|
|
|
def select_courses(request): |
|
|
|
|
courses = request.data.get('courses') |
|
|
|
|
if courses is None: |
|
|
|
|
return Response({'error': 'Please provide a list of course slugs'}, |
|
|
|
|
status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|
|
|
|
|
|
profile = get_object_or_404(models.Profile, user=request.user) |
|
|
|
|
|
|
|
|
|
if profile.courses.count() or profile.selected_courses: |
|
|
|
|
return Response({'error': 'Please provide a list of course slugs'}, |
|
|
|
|
status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|
|
|
|
|
|
course_objects = get_list_or_404(models.Course, slug__in=courses) |
|
|
|
|
profile.courses.set(course_objects) |
|
|
|
|
profile.selected_courses = True |
|
|
|
|
profile.save() |
|
|
|
|
|
|
|
|
|
return Response({'updated': len(courses)}, status=status.HTTP_200_OK) |
|
|
|
|