예제 #1
0
    def phone(self, request, format=None):
        """
        Check if the phone number is allowed to access and return some user data
        to caller.

        call with something like this
        http POST http://127.0.0.1:8000/api/v1/access/phone/ deviceid=asdf payload=0440431918

        returns 200 ok with some user data if everything is fine and 4XX for other situations

        users with enough power will also get a list of all users with door access with this endpoint
        """

        # TODO: Generate log entry for phone events also!

        inserializer = AccessDataSerializer(data=request.data)
        inserializer.is_valid(raise_exception=True)

        # check that we know which device this is
        deviceqs = AccessDevice.objects.all()
        deviceid = inserializer.validated_data.get("deviceid")
        device = get_object_or_404(deviceqs, deviceid=deviceid)
        logging.debug(f"found device {device}")

        # phone number comes in payload, but it is in a wrong format
        # the number will most probably start with 00 instead of +

        number = inserializer.validated_data.get("payload")
        number = normalize_number(number)
        qs = CustomUser.objects.filter(phone=number)

        # nothing found, 480
        if qs.count() == 0:
            return Response(status=480)

        # multiple users found. this cannot work...
        # phone number is going to get unique constraint. When that happens
        # this can be removed completely
        if qs.count() != 1:
            logger.error(
                f"Found multiple users with number: {number} this should not happen"
            )
            return Response(status=status.HTTP_409_CONFLICT)

        # our user
        user = qs.first()

        # user does not have access rights
        if not user.has_door_access():
            door_access_denied.send(sender=self.__class__,
                                    user=user,
                                    method="phone")
            return Response(status=481)

        outserializer = UserAccessSerializer(user)
        return Response(outserializer.data)
예제 #2
0
    def nfc(self, request, format=None):
        """
        NFC card access
        """
        logentry = DeviceAccessLogEntry()
        inserializer = AccessDataSerializer(data=request.data)
        inserializer.is_valid(raise_exception=True)

        deviceqs = AccessDevice.objects.all()
        deviceid = inserializer.validated_data.get("deviceid")
        device = get_object_or_404(deviceqs, deviceid=deviceid)
        logging.debug(f"found device {device}")

        cardid = inserializer.validated_data.get("payload")
        qs = NFCCard.objects.filter(cardid=cardid)

        logentry.device = device
        logentry.payload = cardid

        # 0 = success, any other = failure
        response_status = 0

        if qs.count() == 0:
            response_status = 480
        else:
            logentry.nfccard = qs.first()

            # our user
            user = qs.first().user

            # user does not have access rights
            if not user.has_door_access():
                user.log("Door access denied with NFC")
                door_access_denied.send(sender=self.__class__,
                                        user=user,
                                        method="nfc")
                response_status = 481

        logentry.granted = response_status == 0

        logentry.save()

        if response_status == 0:
            user.log("Door opened with NFC")
            outserializer = UserAccessSerializer(user)
            return Response(outserializer.data)

        if response_status == 481:
            outserializer = UserAccessSerializer(user)
            return Response(outserializer.data, status=response_status)

        return Response(status=response_status)
예제 #3
0
    def phone(self, request, format=None):
        """
        Check if the phone number is allowed to access and return some user data
        to caller.

        call with something like this
        http POST http://127.0.0.1:8000/api/v1/access/phone/ deviceid=asdf payload=0440431918

        returns 200 ok with some user data if everything is fine and 4XX for other situations

        users with enough power will also get a list of all users with door access with this endpoint
        """

        inserializer = AccessDataSerializer(data=request.data)
        inserializer.is_valid(raise_exception=True)

        # check that we know which device this is
        deviceqs = AccessDevice.objects.all()
        deviceid = inserializer.validated_data.get("deviceid")
        device = get_object_or_404(deviceqs, deviceid=deviceid)
        logging.debug(f"found device {device}")

        # phone number comes in payload, but it is in a wrong format
        # the number will most probably start with 00 instead of +

        number = inserializer.validated_data.get("payload")
        number = normalize_number(number)
        qs = CustomUser.objects.filter(phone=number)

        # nothing found, 480
        if qs.count() == 0:
            return Response(status=480)

        # our user
        user = qs.first()

        # user does not have access rights
        if not user.has_door_access():
            user.log("Door access denied with phone")
            door_access_denied.send(sender=self.__class__,
                                    user=user,
                                    method="phone")
            outserializer = UserAccessSerializer(user)
            return Response(outserializer.data, status=481)

        user.log("Door opened with phone")
        outserializer = UserAccessSerializer(user)
        return Response(outserializer.data)
예제 #4
0
    def mxid(self, request, format=None):
        """
        Matrix mxid access
        """
        logentry = DeviceAccessLogEntry()
        inserializer = AccessDataSerializer(data=request.data)
        inserializer.is_valid(raise_exception=True)

        deviceqs = AccessDevice.objects.all()
        deviceid = inserializer.validated_data.get("deviceid")
        device = get_object_or_404(deviceqs, deviceid=deviceid)
        logging.debug(f"found device {device}")

        mxid = inserializer.validated_data.get("payload")
        users = CustomUser.objects.filter(mxid=mxid)

        logentry.device = device
        logentry.payload = mxid

        # 0 = success, any other = failure
        response_status = 0

        if users.count() != 1:
            response_status = 480
        else:
            user = users.first()

            # user does not have access rights
            if not user.has_door_access():
                door_access_denied.send(sender=self.__class__,
                                        user=user,
                                        method="mxid")
                response_status = 481

        logentry.granted = response_status == 0
        logentry.save()

        if response_status == 0:
            outserializer = UserAccessSerializer(user)
            return Response(outserializer.data)

        if response_status == 481:
            outserializer = UserAccessSerializer(user)
            return Response(outserializer.data, status=response_status)

        return Response(status=response_status)