From 030abcc9598b65308a50764f3f8a7f0a21ab4593 Mon Sep 17 00:00:00 2001 From: Chih Cheng Liang Date: Thu, 1 Aug 2019 17:55:15 +0800 Subject: [PATCH 1/4] add vscode --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index ee759a4..a12c166 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,6 @@ venv.bak/ # pycharm .idea/ + +# vscode +.vscode/ \ No newline at end of file From a86f010c95e08d8b301575257d51d4805f5f974b Mon Sep 17 00:00:00 2001 From: Chih Cheng Liang Date: Thu, 1 Aug 2019 19:12:11 +0800 Subject: [PATCH 2/4] add typing to security --- .../connection/raw_connection_interface.py | 10 +++++- libp2p/security/insecure_security.py | 31 ++++++++++++++----- libp2p/security/secure_conn_interface.py | 9 ++++-- libp2p/security/secure_transport_interface.py | 13 ++++++-- libp2p/security/security_multistream.py | 30 +++++++++++++++--- libp2p/security/simple_security.py | 31 ++++++++++++++----- libp2p/security/typing.py | 4 +++ 7 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 libp2p/security/typing.py diff --git a/libp2p/network/connection/raw_connection_interface.py b/libp2p/network/connection/raw_connection_interface.py index 2b20607..5814c44 100644 --- a/libp2p/network/connection/raw_connection_interface.py +++ b/libp2p/network/connection/raw_connection_interface.py @@ -1,4 +1,4 @@ -from abc import ABC +from abc import ABC, abstractmethod # pylint: disable=too-few-public-methods @@ -7,3 +7,11 @@ class IRawConnection(ABC): """ A Raw Connection provides a Reader and a Writer """ + + @abstractmethod + async def write(self, data: bytes) -> None: + pass + + @abstractmethod + async def read(self) -> bytes: + pass diff --git a/libp2p/security/insecure_security.py b/libp2p/security/insecure_security.py index d20d29b..af648b0 100644 --- a/libp2p/security/insecure_security.py +++ b/libp2p/security/insecure_security.py @@ -1,12 +1,22 @@ from libp2p.security.secure_transport_interface import ISecureTransport from libp2p.security.secure_conn_interface import ISecureConn +from typing import TYPE_CHECKING, Dict, Any, cast + +if TYPE_CHECKING: + from .secure_conn_interface import ISecureConn + from libp2p.network.connection.raw_connection_interface import IRawConnection + from libp2p.peer.id import ID + from .typing import TSecurityDetails + class InsecureTransport(ISecureTransport): - def __init__(self, transport_id): + transport_id: int + + def __init__(self, transport_id: int) -> None: self.transport_id = transport_id - async def secure_inbound(self, conn): + async def secure_inbound(self, conn: "IRawConnection") -> ISecureConn: """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are not the initiator) @@ -15,7 +25,9 @@ class InsecureTransport(ISecureTransport): insecure_conn = InsecureConn(conn, self.transport_id) return insecure_conn - async def secure_outbound(self, conn, peer_id): + async def secure_outbound( + self, conn: "IRawConnection", peer_id: "ID" + ) -> ISecureConn: """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are the initiator) @@ -26,18 +38,21 @@ class InsecureTransport(ISecureTransport): class InsecureConn(ISecureConn): - def __init__(self, conn, conn_id): + conn: "IRawConnection" + details: "TSecurityDetails" + + def __init__(self, conn: "IRawConnection", conn_id: int) -> None: self.conn = conn - self.details = {} + self.details = cast("TSecurityDetails", {}) self.details["id"] = conn_id - def get_conn(self): + def get_conn(self) -> "ISecureConn": """ :return: connection object that has been made secure """ - return self.conn + return cast("ISecureConn", self.conn) - def get_security_details(self): + def get_security_details(self) -> "TSecurityDetails": """ :return: map containing details about the connections security """ diff --git a/libp2p/security/secure_conn_interface.py b/libp2p/security/secure_conn_interface.py index c71a54a..5864bd9 100644 --- a/libp2p/security/secure_conn_interface.py +++ b/libp2p/security/secure_conn_interface.py @@ -1,5 +1,10 @@ from abc import ABC, abstractmethod +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .typing import TSecurityDetails + # pylint: disable=W0105 """ @@ -12,13 +17,13 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa class ISecureConn(ABC): @abstractmethod - def get_conn(self): + def get_conn(self) -> "ISecureConn": """ :return: connection object that has been made secure """ @abstractmethod - def get_security_details(self): + def get_security_details(self) -> "TSecurityDetails": """ :return: map containing details about the connections security """ diff --git a/libp2p/security/secure_transport_interface.py b/libp2p/security/secure_transport_interface.py index 8209643..99a3936 100644 --- a/libp2p/security/secure_transport_interface.py +++ b/libp2p/security/secure_transport_interface.py @@ -1,5 +1,12 @@ from abc import ABC, abstractmethod +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .secure_conn_interface import ISecureConn + from libp2p.network.connection.raw_connection_interface import IRawConnection + from libp2p.peer.id import ID + # pylint: disable=W0105 """ @@ -12,7 +19,7 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa class ISecureTransport(ABC): @abstractmethod - async def secure_inbound(self, conn): + async def secure_inbound(self, conn: "IRawConnection") -> "ISecureConn": """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are not the initiator) @@ -20,7 +27,9 @@ class ISecureTransport(ABC): """ @abstractmethod - async def secure_outbound(self, conn, peer_id): + async def secure_outbound( + self, conn: "IRawConnection", peer_id: "ID" + ) -> "ISecureConn": """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are the initiator) diff --git a/libp2p/security/security_multistream.py b/libp2p/security/security_multistream.py index 7b07b8b..2f5648b 100644 --- a/libp2p/security/security_multistream.py +++ b/libp2p/security/security_multistream.py @@ -2,6 +2,18 @@ from abc import ABC from libp2p.protocol_muxer.multiselect_client import MultiselectClient from libp2p.protocol_muxer.multiselect import Multiselect +from typing import TYPE_CHECKING, NewType, Dict + +if TYPE_CHECKING: + from libp2p.network.connection.raw_connection_interface import IRawConnection + from libp2p.peer.id import ID + from .typing import TSecurityDetails + from .secure_conn_interface import ISecureConn + from .secure_transport_interface import ISecureTransport + + +TProtocol = NewType("TProtocol", str) + # pylint: disable=W0105 """ @@ -13,7 +25,11 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa class SecurityMultistream(ABC): - def __init__(self): + transports: Dict[TProtocol, "ISecureTransport"] + multiselect: "Multiselect" + multiselect_client: "MultiselectClient" + + def __init__(self) -> None: # Map protocol to secure transport self.transports = {} @@ -23,7 +39,7 @@ class SecurityMultistream(ABC): # Create multiselect client self.multiselect_client = MultiselectClient() - def add_transport(self, protocol, transport): + def add_transport(self, protocol: TProtocol, transport: "ISecureTransport") -> None: # Associate protocol with transport self.transports[protocol] = transport @@ -32,7 +48,7 @@ class SecurityMultistream(ABC): # we only care about selecting the protocol, not any handler function self.multiselect.add_handler(protocol, None) - async def secure_inbound(self, conn): + async def secure_inbound(self, conn: "IRawConnection") -> "ISecureConn": """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are not the initiator) @@ -47,7 +63,9 @@ class SecurityMultistream(ABC): return secure_conn - async def secure_outbound(self, conn, peer_id): + async def secure_outbound( + self, conn: "IRawConnection", peer_id: "ID" + ) -> "ISecureConn": """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are the initiator) @@ -62,7 +80,9 @@ class SecurityMultistream(ABC): return secure_conn - async def select_transport(self, conn, initiator): + async def select_transport( + self, conn: "IRawConnection", initiator: bool + ) -> "ISecureTransport": """ Select a transport that both us and the node on the other end of conn support and agree on diff --git a/libp2p/security/simple_security.py b/libp2p/security/simple_security.py index 1860860..f5df0b1 100644 --- a/libp2p/security/simple_security.py +++ b/libp2p/security/simple_security.py @@ -2,12 +2,21 @@ import asyncio from libp2p.security.secure_transport_interface import ISecureTransport from libp2p.security.secure_conn_interface import ISecureConn +from typing import TYPE_CHECKING, cast + +if TYPE_CHECKING: + from libp2p.network.connection.raw_connection_interface import IRawConnection + from libp2p.peer.id import ID + from .typing import TSecurityDetails + class SimpleSecurityTransport(ISecureTransport): - def __init__(self, key_phrase): + key_phrase: str + + def __init__(self, key_phrase: str) -> None: self.key_phrase = key_phrase - async def secure_inbound(self, conn): + async def secure_inbound(self, conn: "IRawConnection") -> "ISecureConn": """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are not the initiator) @@ -24,7 +33,9 @@ class SimpleSecurityTransport(ISecureTransport): secure_conn = SimpleSecureConn(conn, self.key_phrase) return secure_conn - async def secure_outbound(self, conn, peer_id): + async def secure_outbound( + self, conn: "IRawConnection", peer_id: "ID" + ) -> "ISecureConn": """ Secure the connection, either locally or by communicating with opposing node via conn, for an inbound connection (i.e. we are the initiator) @@ -47,18 +58,22 @@ class SimpleSecurityTransport(ISecureTransport): class SimpleSecureConn(ISecureConn): - def __init__(self, conn, key_phrase): + conn: "IRawConnection" + key_phrase: str + details: "TSecurityDetails" + + def __init__(self, conn: "IRawConnection", key_phrase: str) -> None: self.conn = conn - self.details = {} + self.details = cast("TSecurityDetails", {}) self.details["key_phrase"] = key_phrase - def get_conn(self): + def get_conn(self) -> "ISecureConn": """ :return: connection object that has been made secure """ - return self.conn + return cast("ISecureConn", self.conn) - def get_security_details(self): + def get_security_details(self) -> "TSecurityDetails": """ :return: map containing details about the connections security """ diff --git a/libp2p/security/typing.py b/libp2p/security/typing.py new file mode 100644 index 0000000..8ef11f7 --- /dev/null +++ b/libp2p/security/typing.py @@ -0,0 +1,4 @@ +from typing import TypeVar, Dict, Any, NewType + + +TSecurityDetails = NewType("TSecurityDetails", Dict[str, Any]) \ No newline at end of file From e731f77f2d2f72b69abb82af6e5497eaeb8db0dd Mon Sep 17 00:00:00 2001 From: Chih Cheng Liang Date: Thu, 1 Aug 2019 19:13:06 +0800 Subject: [PATCH 3/4] minor --- .gitignore | 2 +- libp2p/security/typing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a12c166..6aef4dd 100644 --- a/.gitignore +++ b/.gitignore @@ -107,4 +107,4 @@ venv.bak/ .idea/ # vscode -.vscode/ \ No newline at end of file +.vscode/ diff --git a/libp2p/security/typing.py b/libp2p/security/typing.py index 8ef11f7..b2d3f4c 100644 --- a/libp2p/security/typing.py +++ b/libp2p/security/typing.py @@ -1,4 +1,4 @@ from typing import TypeVar, Dict, Any, NewType -TSecurityDetails = NewType("TSecurityDetails", Dict[str, Any]) \ No newline at end of file +TSecurityDetails = NewType("TSecurityDetails", Dict[str, Any]) From 10a8347c6a2ce6f89aec7d63cbdc927c65d7e50a Mon Sep 17 00:00:00 2001 From: Chih Cheng Liang Date: Fri, 2 Aug 2019 14:12:59 +0800 Subject: [PATCH 4/4] PR feedback --- libp2p/security/insecure_security.py | 12 ++++++------ libp2p/security/secure_conn_interface.py | 5 +++-- libp2p/security/simple_security.py | 4 ++-- libp2p/security/typing.py | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libp2p/security/insecure_security.py b/libp2p/security/insecure_security.py index af648b0..959ea78 100644 --- a/libp2p/security/insecure_security.py +++ b/libp2p/security/insecure_security.py @@ -4,16 +4,16 @@ from libp2p.security.secure_conn_interface import ISecureConn from typing import TYPE_CHECKING, Dict, Any, cast if TYPE_CHECKING: - from .secure_conn_interface import ISecureConn from libp2p.network.connection.raw_connection_interface import IRawConnection from libp2p.peer.id import ID + from .secure_conn_interface import ISecureConn from .typing import TSecurityDetails class InsecureTransport(ISecureTransport): - transport_id: int + transport_id: str - def __init__(self, transport_id: int) -> None: + def __init__(self, transport_id: str) -> None: self.transport_id = transport_id async def secure_inbound(self, conn: "IRawConnection") -> ISecureConn: @@ -41,16 +41,16 @@ class InsecureConn(ISecureConn): conn: "IRawConnection" details: "TSecurityDetails" - def __init__(self, conn: "IRawConnection", conn_id: int) -> None: + def __init__(self, conn: "IRawConnection", conn_id: str) -> None: self.conn = conn self.details = cast("TSecurityDetails", {}) self.details["id"] = conn_id - def get_conn(self) -> "ISecureConn": + def get_conn(self) -> "IRawConnection": """ :return: connection object that has been made secure """ - return cast("ISecureConn", self.conn) + return self.conn def get_security_details(self) -> "TSecurityDetails": """ diff --git a/libp2p/security/secure_conn_interface.py b/libp2p/security/secure_conn_interface.py index 5864bd9..f5de4cd 100644 --- a/libp2p/security/secure_conn_interface.py +++ b/libp2p/security/secure_conn_interface.py @@ -3,6 +3,7 @@ from abc import ABC, abstractmethod from typing import TYPE_CHECKING if TYPE_CHECKING: + from libp2p.network.connection.raw_connection_interface import IRawConnection from .typing import TSecurityDetails # pylint: disable=W0105 @@ -17,9 +18,9 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa class ISecureConn(ABC): @abstractmethod - def get_conn(self) -> "ISecureConn": + def get_conn(self) -> "IRawConnection": """ - :return: connection object that has been made secure + :return: the underlying raw connection """ @abstractmethod diff --git a/libp2p/security/simple_security.py b/libp2p/security/simple_security.py index f5df0b1..07a0129 100644 --- a/libp2p/security/simple_security.py +++ b/libp2p/security/simple_security.py @@ -67,11 +67,11 @@ class SimpleSecureConn(ISecureConn): self.details = cast("TSecurityDetails", {}) self.details["key_phrase"] = key_phrase - def get_conn(self) -> "ISecureConn": + def get_conn(self) -> "IRawConnection": """ :return: connection object that has been made secure """ - return cast("ISecureConn", self.conn) + return self.conn def get_security_details(self) -> "TSecurityDetails": """ diff --git a/libp2p/security/typing.py b/libp2p/security/typing.py index b2d3f4c..9832fbe 100644 --- a/libp2p/security/typing.py +++ b/libp2p/security/typing.py @@ -1,4 +1,4 @@ from typing import TypeVar, Dict, Any, NewType -TSecurityDetails = NewType("TSecurityDetails", Dict[str, Any]) +TSecurityDetails = NewType("TSecurityDetails", Dict[str, str])