예제 #1
0
 async def send_text_message(self, message: str):
     await self._recreate_connection()
     await self._send_data(5, Extentions.defstr_to_bytes(message))
     code, data = await self._get_data()
     if code != 5:
         self._raise_customised_exception(Extentions.bytes_to_defstr(data)[0], code)
     Logger.log(f"Message to '{self.client_login}' ({self._host}:{self._port}) was successfully sent.")
예제 #2
0
 async def delete_user(self, login: str, password: str):
     await self._recreate_connection()
     bts_login = Extentions.defstr_to_bytes(login)
     bts_password = Extentions.defstr_to_bytes(password)
     await self._send_data(4, bts_login + bts_password)
     code, data = await self._get_data()
     if code != 2:
         self._raise_customised_exception(Extentions.bytes_to_defstr(data)[0], code)
     Logger.log(f"User '{login}' was successfully deleted.", "client")
예제 #3
0
 async def _recreate_connection(self):
     try:
         await super()._recreate_connection()
         await self._send_data(2, Extentions.defstr_to_bytes(self.login))
         code, data = await self._get_data()
         if code == 2 and (Extentions.bytes_to_defstr(data)[0] == self.client_login or self.login == "guest"):
             Logger.log(f"Connection with '{self.client_login}' ({self._host}:{self._port}) was established.", "client")
             return
     except ClientToServerException as ex:
         raise ex
예제 #4
0
 def _on_receive_callback(data: bytes, contact_login: str,
                          contact_endpoint: str):
     message = Extentions.bytes_to_defstr(data)[0]
     time = datetime.now()
     self._contacts[contact_login, contact_endpoint,
                    time].add_text_message(message, contact_login)
     self.on_receive_callback(contact_login, time, message)
예제 #5
0
async def _send_data(writer: asyncio.StreamWriter,
                     code: int,
                     data: bytes = bytes()):
    data_to_send = Extentions.int_to_bytes(len(data) + 1) + bytes([code
                                                                   ]) + data
    writer.write(data_to_send)
    await writer.drain()
예제 #6
0
    async def _get_data(reader: asyncio.StreamReader, timeout: int=5) -> (int, bytes):

        async def _l_get_data(length: int) -> (bytes):
            data = await asyncio.wait_for(reader.read(length), timeout=timeout)
            if data:
                return data
            else:
                raise ConnectionResetError()

        length, _ = Extentions.bytes_to_int(await _l_get_data(4))
        result = await _l_get_data(length)
        return (result[0], result[1:])
예제 #7
0
    async def _get_data(self, timeout: int=5) -> (int, bytes):
        if (self.__class__ == _IConnection):
            self._raise_not_implemented_error()

        async def _l_get_data(length: int) -> (bytes):
            data = await asyncio.wait_for(self._reader.read(length), timeout=timeout)
            if data:
                return data
            else:
                raise ConnectionResetError()

        length, _ = Extentions.bytes_to_int(await _l_get_data(4))
        result = await _l_get_data(length)
        return (result[0], result[1:])
예제 #8
0
 async def get_IPs(self, logins: List[str]) -> List[Tuple[str, datetime]]:
     await self._recreate_connection()
     data_to_send = Extentions.int_to_bytes(len(logins))
     for login in logins:
         data_to_send += Extentions.defstr_to_bytes(login)
     await self._send_data(3, data_to_send)
     code, data = await self._get_data()
     if code != 3:
         self._raise_customised_exception(Extentions.bytes_to_defstr(data)[0], code)
     result = []
     received_length, data = Extentions.bytes_to_int(data)
     if received_length != len(logins):
         self._raise_customised_exception("IP-update request was failed!", -1)
     for i in range(0, received_length):
         requested_ip, data = Extentions.bytes_to_defstr(data)
         requested_time, data = Extentions.bytes_to_defstr(data)
         if requested_ip == "":
             result.append((None, None))
         else:
             result.append((requested_ip, datetime.strptime(requested_time, "%H:%M:%S.%f %d.%m.%Y")))
     return result
예제 #9
0
 async def get_IPs(self, logins: List[str]) -> List[Tuple[str, datetime]]:
     await self._recreate_connection()
     data = Extentions.int_to_bytes(len(logins))
     for i in range(0, len(logins)):
         data += Extentions.defstr_to_bytes(logins[i])
     await self._send_data(3, data)
     code, data = await self._get_data()
     if code != 3:
         self._raise_customised_exception(Extentions.bytes_to_defstr(data)[0], code)
     result = []
     count, data = Extentions.bytes_to_int(data)
     while count > 0:
         ip, data = Extentions.bytes_to_defstr(data)
         time, data = Extentions.bytes_to_defstr(data)
         if ip == "":
             result.append((None, None))
         else:
             result.append((ip, datetime.strptime(time, "%H:%M:%S.%f %d.%m.%Y")))
         count -= 1
     Logger.log("Requested IPs were received.", "client")
     return result
예제 #10
0
def main():
    sock: socket = socket()
    sock.connect(("192.168.43.168", 3501))
    Logger.log("Connection with localhost:3501 was established.", "test_client")
    _send_data(sock, 0)
    Logger.log("Ping was successfully sent.", "test_client")
    code, _ = _get_gata(sock)
    if code != 0:
        raise TestClientException("Ping wasn't received!")
    Logger.log("Ping was successfully received.", "test_client")

    return

    for i in range(0, 5):
        bts_login = Extentions.defstr_to_bytes(f"TestUser{i}")
        bts_password = Extentions.defstr_to_bytes(f"{i + 1}{i}{ (i - 1) * 2}")
        _send_data(sock, 1, bts_login + bts_password)
        Logger.log(f"Trying to register TestUser{i}...", "test_client")
        code, received_data = _get_gata(sock)
        if code != 1:
            raise TestClientException(f"TestUser{i} wasn't registered!\n{Extentions.bytes_to_defstr(received_data)}")
        Logger.log(f"TestUser{i} was successfully registered.", "test_client")
    bts_login = Extentions.defstr_to_bytes(f"TestUser3")
    bts_password = Extentions.defstr_to_bytes(f"434")
    _send_data(sock, 2, bts_login + bts_password)
    Logger.log("Trying to login as TestUser3...", "test_client")
    code, received_data = _get_gata(sock)
    if code != 2:
        raise TestClientException(f"Login as TestUser3 was failed!\n{Extentions.bytes_to_defstr(received_data)}")
    Logger.log("Login as TestUser3 was successful.", "test_client")
    requesting_logins = Extentions.int_to_bytes(4)
    requesting_logins += Extentions.defstr_to_bytes("TestUser0")
    requesting_logins += Extentions.defstr_to_bytes("TestUser1")
    requesting_logins += Extentions.defstr_to_bytes("TestUser2")
    requesting_logins += Extentions.defstr_to_bytes("TestUser4")
    _send_data(sock, 3, requesting_logins)
    Logger.log("IPs was requested.", "test_client")
    code, received_data = _get_gata(sock)
    if code != 3:
        raise TestClientException(f"IP-update request failed!")
    ips_count, received_data = Extentions.bytes_to_int(received_data)
    ips_list = ["Following IPs was received:"]
    while ips_count > 0:
        requested_ip, received_data = Extentions.bytes_to_defstr(received_data)
        ips_list.append(f"TestUser{4 - ips_count} : {requested_ip}")
        ips_count -= 1
    Logger.log("\n".join(ips_list), "test_client")
    _send_data(sock, 4, Extentions.defstr_to_bytes("434"))
    Logger.log("Trying to delete TestUser3...", "test_client")
    code, received_data = _get_gata(sock)
    if code != 4:
        raise TestClientException(f"Deleting TestUser3 was failed!\n{Extentions.bytes_to_defstr(received_data)}")
    Logger.log("TestUser3 was successfully deleted.", "test_client")
    _send_data(sock, 3, Extentions.int_to_bytes(1) + Extentions.defstr_to_bytes("TestUser3"))
    _, received_data = _get_gata(sock)
    Logger.log("TestUser3's IP : " + Extentions.bytes_to_defstr(received_data[4:])[0], "test_client")
    sock.close()
    Logger.log("Test successfully ended.", "test_client")
예제 #11
0
def _send_data(sock: socket, code: int, data: bytes = bytes()):
    data_to_send = Extentions.int_to_bytes(len(data) + 1) + bytes([code]) + data
    sock.send(data_to_send)
예제 #12
0
def _get_gata(sock: socket) -> (int, bytes):
    length, _ = Extentions.bytes_to_int(sock.recv(4))
    result = sock.recv(length)
    return (result[0], result[1:])
예제 #13
0
 async def _on_connect(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
     timeout = 5
     client_login = None
     client_endpoint = writer.get_extra_info("peername")
     client_ip = client_endpoint[0]
     client_port = client_endpoint[1]
     Logger.log(f"Accepted connection from {client_ip}:{client_port}.", "client")
     while True:
         try:
             code, data = await self._get_data(reader, timeout)
             if code == 0:   # Ping
                 await self._send_data(writer, 0)
                 Logger.log(f"Ping was sent to {client_ip}:{client_port}.", "client")
             elif code == 2:   # Login
                 received_login, data = Extentions.bytes_to_defstr(data)
                 if len(data) == 0:
                     preferred_port = "3502"
                 else:
                     preferred_port, _ = Extentions.bytes_to_defstr(data)
                 if received_login == "server":
                     await self._send_data(writer, 252, Extentions.defstr_to_bytes("'server' is service login!"))
                     continue
                 client_login = received_login
                 self.update_ip_callback(client_login, client_ip + ":" + preferred_port)
                 await self._send_data(writer, 2, Extentions.defstr_to_bytes(self.login))
                 timeout = 60
                 Logger.log(f"Login {client_ip}:{client_port} as '{client_login}' was confirmed.")
             elif code == 3:   # IP updating request
                 login_count, data = Extentions.bytes_to_int(data)
                 ips = Extentions.int_to_bytes(login_count)
                 while login_count > 0:
                     requested_login, data = Extentions.bytes_to_defstr(data)
                     if requested_login == "server":
                         if self._server_endpoint == []:
                             requested_ip = ""
                             requested_time = ""
                         else:
                             requested_ip, requested_time = self._server_endpoint
                             requested_time = requested_time.strftime("%H:%M:%S.%f %d.%m.%Y")
                         requested_line = (Extentions.defstr_to_bytes(requested_ip) +
                                           Extentions.defstr_to_bytes(requested_time))
                         ips += requested_line
                     elif requested_login == self.login:
                         requested_ip = socket.gethostbyname(socket.gethostname())
                         requested_time = datetime.now().strftime("%H:%M:%S.%f %d.%m.%Y")
                         requested_line = (Extentions.defstr_to_bytes(requested_ip) +
                                           Extentions.defstr_to_bytes(requested_time))
                         ips += requested_line
                     else:
                         tmp = self._database.search_ip_and_last_time(requested_login)
                         if tmp[0] == "0.0.0.0":
                             requested_ip = ""
                             requested_time = ""
                         else:
                             requested_ip, requested_time = tmp
                             requested_time = requested_time.strftime("%H:%M:%S.%f %d.%m.%Y")
                         requested_line = (Extentions.defstr_to_bytes(requested_ip) +
                                           Extentions.defstr_to_bytes(requested_time))
                         ips += requested_line
                     login_count -= 1
                 await self._send_data(writer, 3, ips)
                 Logger.log(f"Requested IPs was sent to {client_ip}:{client_port}.")
             elif code == 5:   # Text message
                 if client_login is not None and client_login != "guest":
                     self.on_receive_msg_callback(data, client_login, client_ip + ":" + preferred_port)
                     await self._send_data(writer, 5)
                     Logger.log(f"Message from '{client_login}' ({client_ip}:{client_port}) was recieved.")
                 else:
                     await self._send_data(writer, 253, Extentions.defstr_to_bytes("You should login first."))
             elif code == 6:   # File message
                 pass   # TODO: Add handling file messages
             else:
                 msg, _ = Extentions.bytes_to_str(Extentions.int_to_bytes(code) + data)
                 Logger.log(f"Following message was resieved from {client_ip}:{client_port}:\n{msg}", "client")
         except ConnectionResetError:
             Logger.log(f"Connection from {client_ip}:{client_port} closed by peer.", "client")
             break
         except TimeoutError:
             Logger.log(f"Connection from {client_ip}:{client_port} closed by timeout.", "client")
             break
     writer.close()
예제 #14
0
 async def _send_data(self, code: int, data: bytes=bytes()):
     if (self.__class__ == _IConnection):
         self._raise_not_implemented_error()
     data_to_send = Extentions.int_to_bytes(len(data) + 1) + bytes([code]) + data
     self._writer.write(data_to_send)
     await self._writer.drain()
예제 #15
0
async def _on_connect(reader: asyncio.StreamReader,
                      writer: asyncio.StreamWriter):
    timeout = 5
    login = None
    client_endpoint = writer.get_extra_info("peername")
    client_ip = client_endpoint[0]
    if client_ip == "127.0.0.1":
        client_ip = socket.gethostbyname(socket.gethostname())
    client_port = client_endpoint[1]
    Logger.log(f"Accepted connection from {client_ip}:{client_port}.")
    while True:
        try:
            code, data = await _get_data(reader, timeout)
            if code == 0:  # Ping
                await _send_data(writer, 0)
                Logger.log(f"Ping was sent to {client_ip}:{client_port}.")
            elif code == 1:  # Registration
                received_login, data = Extentions.bytes_to_defstr(data)
                if received_login == "server" or received_login == "guest":
                    await _send_data(
                        writer, 252,
                        Extentions.defstr_to_bytes(
                            "'server' is service login!"))
                    continue
                login = received_login
                pass_hash, data = Extentions.bytes_to_defstr(data)
                if data == bytes():
                    preferred_port = "3502"
                else:
                    preferred_port, _ = Extentions.bytes_to_defstr(data)
                Logger.log(
                    f"Registration {client_ip}:{client_port} as '{login}'...")
                if (_database.search_ip_and_last_time(login)[0] != "0.0.0.0"):
                    await _send_data(
                        writer, 254,
                        Extentions.defstr_to_bytes(
                            "This login is already registered."))
                    Logger.log(
                        f"Registration {client_ip}:{client_port} as '{login}' was refused."
                    )
                    continue
                _database.add_client(login, pass_hash,
                                     client_ip + ":" + preferred_port)
                pass_hash = None
                await _send_data(writer, 1)
                Logger.log(
                    f"Registration {client_ip}:{client_port} as '{login}' was confirmed."
                )
                timeout = 60
            elif code == 2:  # Login
                received_login, data = Extentions.bytes_to_defstr(data)
                if received_login == "server" or received_login == "guest":
                    await _send_data(
                        writer, 252,
                        Extentions.defstr_to_bytes(
                            "'server' is service login!"))
                    continue
                login = received_login
                pass_hash, data = Extentions.bytes_to_defstr(data)
                if data == bytes():
                    preferred_port = "3502"
                else:
                    preferred_port, _ = Extentions.bytes_to_defstr(data)
                Logger.log(f"Login {client_ip}:{client_port} as '{login}'...")
                if (_database.search_password(login) != pass_hash):
                    await _send_data(
                        writer, 255,
                        Extentions.defstr_to_bytes("Password is incorrect."))
                    Logger.log(
                        f"Login {client_ip}:{client_port} as '{login}' was refused."
                    )
                    continue
                pass_hash = ""
                await _send_data(writer, 2)
                Logger.log(
                    f"Login {client_ip}:{client_port} as '{login}' was confirmed."
                )
                timeout = 60
                _database.update_ip(login, client_ip + ":" + preferred_port)
            elif code == 3:  # IP updating request
                Logger.log(f"IPs was requested by {client_ip}:{client_port}")
                login_count, data = Extentions.bytes_to_int(data)
                ips = Extentions.int_to_bytes(login_count)
                while login_count > 0:
                    requested_login, data = Extentions.bytes_to_defstr(data)
                    tmp = _database.search_ip_and_last_time(requested_login)
                    if tmp[0] == "0.0.0.0":
                        requested_ip = ""
                        requested_time = ""
                    else:
                        requested_ip, requested_time = tmp
                        requested_time = requested_time.strftime(
                            "%H:%M:%S.%f %d.%m.%Y")
                    requested_line = (
                        Extentions.defstr_to_bytes(requested_ip) +
                        Extentions.defstr_to_bytes(requested_time))
                    ips += requested_line
                    login_count -= 1
                await _send_data(writer, 3, ips)
                Logger.log(
                    f"Requested IPs was sent to {client_ip}:{client_port}.")
            elif code == 4:  # Delete user request
                if login is None:
                    await _send_data(
                        writer, 253,
                        Extentions.defstr_to_bytes("You should login first."))
                else:
                    pass_hash, _ = Extentions.bytes_to_defstr(data)
                    Logger.log(
                        f"Deleting of '{login}' was requested by {client_ip}:{client_port}..."
                    )
                    if (_database.search_password(login) != pass_hash):
                        await _send_data(
                            writer, 255,
                            Extentions.defstr_to_bytes(
                                "Password is incorrect."))
                        Logger.log(
                            f"Deleting of '{login}' requested by {client_ip}:{client_port} was refused."
                        )
                        continue
                    _database.del_client(login)
                    Logger.log(
                        f"Deleting of '{login}' requested by {client_ip}:{client_port} was confirmed."
                    )
                    await _send_data(writer, 4)
                    timeout = 5
                    login = ""
                    pass_hash = ""
            else:
                msg, _ = Extentions.bytes_to_str(
                    Extentions.int_to_bytes(code) + data)
                Logger.log(
                    f"Following message was resieved from {client_ip}:{client_port}:\n{msg}"
                )
        except ConnectionResetError:
            Logger.log(
                f"Connection from {client_ip}:{client_port} closed by peer.")
            break
        except TimeoutError:
            Logger.log(
                f"Connection from {client_ip}:{client_port} closed by timeout."
            )
            break
    writer.close()