diff --git a/CHANGES b/CHANGES index ffbe5f8..d065493 100644 --- a/CHANGES +++ b/CHANGES @@ -8,3 +8,4 @@ Version 0.2.0 - released 03/dd/18 - Try reconnect when connection is closed - Check if is ADB has installed - Try download the ADB if isn't installed + - Support webservice Auth diff --git a/setup.py b/setup.py index 4746533..43b3ae6 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ def readme(): package_data={}, install_requires=[ - 'PedalPi-WebService==0.3.0', + 'PedalPi-WebService==0.4.*', ], classifiers=[ diff --git a/webservice_serial/request_message_processor.py b/webservice_serial/request_message_processor.py index 52fcdea..7513ed6 100644 --- a/webservice_serial/request_message_processor.py +++ b/webservice_serial/request_message_processor.py @@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from tornado.httpclient import HTTPRequest, AsyncHTTPClient +import json +from tornado.httpclient import HTTPRequest, AsyncHTTPClient from webservice_serial.protocol.request_verb import RequestVerb from webservice_serial.protocol.response_message import ResponseMessage from webservice_serial.protocol.response_verb import ResponseVerb @@ -24,11 +25,18 @@ class RequestMessageProcessor(object): :param port: Port that WebService are executing """ - def __init__(self, port, token=None): + def __init__(self, port): self.http_client = AsyncHTTPClient() self.url = 'http://localhost:{}'.format(port) self.processed_listener = lambda message, response: ... - self.token = token + self.token = None + self.auth_listener = lambda response: ... + + def auth(self, username, password): + auth = json.dumps({'username': username, 'password': password}) + + request = HTTPRequest('{}/v1/auth'.format(self.url), method='POST', body=auth) + self.http_client.fetch(request, lambda http_response: self.auth_listener(http_response)) def process(self, message): """ @@ -47,7 +55,7 @@ def process(self, message): @property def headers(self): if self.token is not None: - return {'x-xsrf-token': self.token} + return {'Authorization': 'bearer {}'.format(self.token)} else: return None diff --git a/webservice_serial/target/android/adb.py b/webservice_serial/target/android/adb.py index c1c8a2f..ea39607 100644 --- a/webservice_serial/target/android/adb.py +++ b/webservice_serial/target/android/adb.py @@ -29,7 +29,7 @@ def __init__(self, command="adb", log=None): self.log = log def start(self, port, activity): - #self.execute('shell am start -n {}'.format(activity)) + self.execute('shell am start -n {}'.format(activity)) #self.execute('forward --remove-all') self.execute('forward tcp:{} tcp:{}'.format(port, port)) diff --git a/webservice_serial/target/android/android_display_view.py b/webservice_serial/target/android/android_display_view.py index b265efb..fbe046e 100644 --- a/webservice_serial/target/android/android_display_view.py +++ b/webservice_serial/target/android/android_display_view.py @@ -19,7 +19,7 @@ class AndroidDisplayView(Target): - activity = 'io.github.pedalpi.pedalpi_display/io.github.pedalpi.displayview.activity.ResumeActivity' + activity = 'io.github.pedalpi.displayview/io.github.pedalpi.displayview.activity.resume.ResumeActivity' def __init__(self): super(AndroidDisplayView, self).__init__() @@ -35,7 +35,8 @@ def init(self, application, port): self.adb.start(port, AndroidDisplayView.activity) def close(self): - self.adb.close(self.port) + if self.adb is not None: + self.adb.close(self.port) def _discover_adb_command(self): if Adb.has_installed(): diff --git a/webservice_serial/webservice_serial.py b/webservice_serial/webservice_serial.py index 4562c5c..0010e2d 100644 --- a/webservice_serial/webservice_serial.py +++ b/webservice_serial/webservice_serial.py @@ -12,14 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -from application.component.component import Component -from webservice_serial.protocol.response_verb import ResponseVerb +import json +from application.component.component import Component +from tornado import gen +from tornado.ioloop import IOLoop from webservice_serial.request_message_processor import RequestMessageProcessor from webservice_serial.webservice_serial_client import WebServiceSerialClient from webservice_serial.websocket_client import WebSocketClient - -from time import sleep +from webservice.properties import WSProperties class WebServiceSerial(Component): @@ -44,23 +45,36 @@ def init(self): self._client.disconnected_listener = lambda: self._try_connect(5) self.request_message_processor.processed_listener = self._on_processed + self.request_message_processor.auth_listener = self._on_auth - self._websocket_client.token_defined_listener = self._on_token_defined self._websocket_client.message_listener = self._on_event + self._websocket_client.on_connected_listener = \ + lambda: self._websocket_client.register(self.request_message_processor.token) + + self.request_message_processor.auth(WSProperties.COMPONENT_USERNAME, WSProperties.COMPONENT_PASSWORD) + + def _on_auth(self, response): + """ + :param tornado.httpclient.HTTPResponse response: + :return: + """ + response = json.loads(response.body.decode('utf8')) + self.request_message_processor.token = response['token'] self._websocket_client.connect() self._try_connect() def _try_connect(self, delay=0): + IOLoop.current().spawn_callback(self.__try_connect, delay) + + @gen.coroutine + def __try_connect(self, delay=0): self._log('Trying to connect with {}', self.target.name) self.target.init(self.application, WebServiceSerial.port) - sleep(delay) + yield gen.sleep(delay) self._client.connect() - def _on_token_defined(self, token): - self.request_message_processor.token = token - def close(self): self.request_message_processor.close() self.target.close() diff --git a/webservice_serial/webservice_serial_client.py b/webservice_serial/webservice_serial_client.py index 0af223b..7f2d2fd 100644 --- a/webservice_serial/webservice_serial_client.py +++ b/webservice_serial/webservice_serial_client.py @@ -34,7 +34,7 @@ def __init__(self, address, port, encoding="utf-8"): self.disconnected_listener = lambda: print('Disconnected :(') def connect(self): - IOLoop.current().spawn_callback(lambda: self._connect()) + IOLoop.current().spawn_callback(self._connect) @gen.coroutine def _connect(self): @@ -77,10 +77,13 @@ def _read_data(self): return data def send(self, message): + if self.stream is None: + return + try: text = str(message).encode(self.encoding) self.stream.write(text) - except StreamClosedError as e: + except StreamClosedError: self.disconnected_listener() def close(self): diff --git a/webservice_serial/websocket_client.py b/webservice_serial/websocket_client.py index bc3a7ca..ec3bd68 100644 --- a/webservice_serial/websocket_client.py +++ b/webservice_serial/websocket_client.py @@ -27,8 +27,8 @@ class WebSocketClient(object): def __init__(self, port): self.port = port self.connection = None - self.token_defined_listener = lambda token: ... self.message_listener = lambda message: ... + self.on_connected_listener = lambda: ... @property def url(self): @@ -41,6 +41,7 @@ def connect(self): @gen.coroutine def _connect(self): self.connection = yield websocket_connect(self.url) + self.on_connected_listener() self._await_messages(self.connection) @gen.coroutine @@ -51,12 +52,12 @@ def _await_messages(self, connection): break message = json.loads(msg) - - if message['type'] == 'TOKEN': - self.token_defined_listener(message['value']) - else: - self.message_listener(message) + self.message_listener(message) def close(self): if self.connection is not None: self.connection.close() + + def register(self, token): + data = json.dumps({'register': token}) + self.connection.write_message(data)