diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index e8bf57c..c6b1025 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -188,6 +188,18 @@ class Usage(models.Model): history = HistoricalRecords(excluded_fields=['num_reports']) +class PinballScore(models.Model): + user = models.ForeignKey(User, related_name='scores', blank=True, null=True, on_delete=models.SET_NULL) + + started_at = models.DateTimeField(auto_now_add=True) + finished_at = models.DateTimeField(null=True) + + game_id = models.IntegerField() + player = models.IntegerField() + score = models.IntegerField() + + # no history + class HistoryIndex(models.Model): content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL) object_id = models.PositiveIntegerField() diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index 6830b71..df2e108 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -1250,6 +1250,54 @@ class ProtocoinViewSet(Base): return Response(res) +class PinballViewSet(Base): + @action(detail=False, methods=['post']) + def score(self, request): + auth_token = request.META.get('HTTP_AUTHORIZATION', '') + if secrets.PINBALL_API_TOKEN and auth_token != 'Bearer ' + secrets.PINBALL_API_TOKEN: + raise exceptions.PermissionDenied() + + card_number = request.data.get('card_number', None) + + if card_number: + card = get_object_or_404(models.Card, card_number=card_number) + user = card.user + else: + user = None + + try: + game_id = int(request.data['game_id']) + except KeyError: + raise exceptions.ValidationError(dict(game_id='This field is required.')) + except ValueError: + raise exceptions.ValidationError(dict(game_id='Invalid number.')) + + try: + player = int(request.data['player']) + except KeyError: + raise exceptions.ValidationError(dict(player='This field is required.')) + except ValueError: + raise exceptions.ValidationError(dict(player='Invalid number.')) + + try: + score = int(request.data['score']) + except KeyError: + raise exceptions.ValidationError(dict(score='This field is required.')) + except ValueError: + raise exceptions.ValidationError(dict(score='Invalid number.')) + + _ = models.PinballScore.objects.update_or_create( + game_id=game_id, + player=player, + defaults=dict( + user=user, + score=score, + finished_at=now(), + ), + ) + + return Response(200) + class RegistrationView(RegisterView): serializer_class = serializers.MyRegisterSerializer diff --git a/apiserver/apiserver/secrets.py.example b/apiserver/apiserver/secrets.py.example index 40ad4be..7cb513f 100644 --- a/apiserver/apiserver/secrets.py.example +++ b/apiserver/apiserver/secrets.py.example @@ -62,6 +62,12 @@ DOOR_API_TOKEN = '' # head /dev/urandom | base32 | head -c 40 VEND_API_TOKEN = '' +# Pinball machine score API token +# Set this to random characters +# For example, use the output of this: +# head /dev/urandom | base32 | head -c 40 +PINBALL_API_TOKEN = '' + # Protospace general info DOOR_CODE = '' WIFI_PASS = '' diff --git a/apiserver/apiserver/urls.py b/apiserver/apiserver/urls.py index 7e71831..fc13f9b 100644 --- a/apiserver/apiserver/urls.py +++ b/apiserver/apiserver/urls.py @@ -19,6 +19,7 @@ router.register(r'members', views.MemberViewSet, basename='members') router.register(r'courses', views.CourseViewSet, basename='course') router.register(r'history', views.HistoryViewSet, basename='history') router.register(r'vetting', views.VettingViewSet, basename='vetting') +router.register(r'pinball', views.PinballViewSet, basename='pinball') router.register(r'sessions', views.SessionViewSet, basename='session') router.register(r'training', views.TrainingViewSet, basename='training') router.register(r'interest', views.InterestViewSet, basename='interest')