예제 #1
0
    def handle(self) -> None:
        print("Handling request from handler.")

        socket = self.request
        transceiver = Transceiver(socket)

        msg_bytes = transceiver.receive()

        try:
            request = Message.from_bytes(msg_bytes)
            request_data = request.data()
            print("Client address: {}.".format(socket.getpeername()))
            print("Request data:\n{}.".format(request_data))

            if request_data["type"] == RequestType.LOGIN:
                reply = self.handle_login(request, socket.getpeername()[0])
            else:
                if self.check_client_id(request, socket.getpeername()[0]):
                    request_type = request_data["type"]
                    reply = self.server.router[request_type](self, request)
                else:
                    reply = self.__get_reply_message(False, "Access denied.")
        except:
            reply = self.__get_reply_message(False, "Invalid request.")

        transceiver.send(reply.to_bytes())
예제 #2
0
    def handle_list_booked_appointments(self, request: Message) -> Message:
        client_id = request.data()["client_id"]

        provider_filter = lambda a: True
        ts_filter = lambda slot_info: (slot_info.owner == client_id and
                                       slot_info.state == TimeSlotState.
                                       RESERVED)

        return self._filter_appointments(provider_filter, ts_filter)
예제 #3
0
    def handle_list_available_appointments(self, request: Message):
        provider = request.data()["service_provider"]
        if provider:
            provider_filter = lambda p: p.name() == provider
        else:
            provider_filter = lambda a: True

        ts_filter = lambda slot_info: slot_info.state == TimeSlotState.AVAILABLE

        return self._filter_appointments(provider_filter, ts_filter)
예제 #4
0
    def handle_add_appointment_to_basket(self, request: Message) -> Message:
        request_data = request.data()
        client_id = request_data["client_id"]

        appointment = request_data["appointment"]

        ts_info = self._find_ts_info_for_appointment(appointment)

        if isinstance(ts_info, Message):
            return ts_info

        if ts_info.state == TimeSlotState.AVAILABLE:
            ts_info.state = TimeSlotState.IN_BASKET
            ts_info.owner = client_id
            return self.__get_reply_message(True, "OK.")

        return self.__get_reply_message(False, "Time slot not available.")
예제 #5
0
    def handle_login(self, request: Message, ip_address: str) -> Message:
        request_data = request.data()
        username = request_data["username"]
        password = request_data["password"]

        user_list = list(
            filter(lambda user: user.username == username,
                   self.server.server_state.users))

        if user_list and user_list[0].password == password:
            user = user_list[0]
            self.server.server_state.connected_users[user.user_id] = ip_address
            reply = self.__get_reply_message(True, "Login successful.")
            reply.data()["client_id"] = user.user_id
        else:
            reply = self.__get_reply_message(False,
                                             "Invalid username or password.")

        return reply
예제 #6
0
    def _handle_remove_or_cancel_appointment(
            self, request: Message, expected_state: TimeSlotState) -> Message:
        request_data = request.data()
        client_id = request_data["client_id"]

        appointment = request_data["appointment"]

        ts_info = self._find_ts_info_for_appointment(appointment)

        if isinstance(ts_info, Message):
            return ts_info

        if ts_info.state != expected_state or ts_info.owner != client_id:
            error_msg = ("Appointment not reserved by you"
                         if expected_state == TimeSlotState.RESERVED else
                         "Appointment not in your basket.")
            return self.__get_reply_message(False, error_msg)

        ts_info.state = TimeSlotState.AVAILABLE

        return self.__get_reply_message(True, "OK.")
예제 #7
0
    def handle_confirm_booking(self, request: Message):
        request_data = request.data()
        client_id = request_data["client_id"]

        provider_predicate = lambda a: True
        ts_predicate = lambda ts_info: ts_info.owner == client_id and ts_info.state == TimeSlotState.IN_BASKET
        appointments = self._filter_appointments_list(provider_predicate,
                                                      ts_predicate)

        if not appointments:
            return self.__get_reply_message(False,
                                            "No appointments in basket.")

        for appointment in appointments:
            ts_info = self._find_ts_info_for_appointment(appointment)
            if isinstance(ts_info, Message):
                return ts_info

            ts_info.state = TimeSlotState.RESERVED

        return self.__get_reply_message(True, "OK.")
예제 #8
0
    def check_client_id(self, request: Message, ip_address: str) -> bool:
        client_id = request.data()["client_id"]
        stored_ip = self.server.server_state.connected_users.get(client_id)

        return stored_ip == ip_address
예제 #9
0
 def __get_reply_message(ok: bool, text: str) -> Message:
     msg_dict = {"OK": ok, "text": text}
     return Message(msg_dict)