diff options
-rw-r--r-- | module/remote/JSONClient.py | 8 | ||||
-rw-r--r-- | module/remote/WSClient.py | 32 | ||||
-rw-r--r-- | module/remote/create_ttypes.py | 6 | ||||
-rw-r--r-- | module/remote/json_converter.py | 2 | ||||
-rw-r--r-- | module/remote/pyload.thrift | 7 | ||||
-rw-r--r-- | module/remote/ttypes.py | 6 | ||||
-rw-r--r-- | module/remote/wsbackend/ApiHandler.py | 2 | ||||
-rw-r--r-- | tests/api/test_JSONBackend.py | 6 | ||||
-rw-r--r-- | tests/api/test_WebSocketAPI.py | 33 |
9 files changed, 88 insertions, 14 deletions
diff --git a/module/remote/JSONClient.py b/module/remote/JSONClient.py index 52b712c81..9f678f5bd 100644 --- a/module/remote/JSONClient.py +++ b/module/remote/JSONClient.py @@ -1,10 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from json_converter import loads, dumps from urllib import urlopen, urlencode from httplib import UNAUTHORIZED, FORBIDDEN +from json_converter import loads, dumps +from ttypes import Unauthorized, Forbidden + class JSONClient: URL = "http://localhost:8001/api" @@ -19,9 +21,9 @@ class JSONClient: if ret.code == 500: raise Exception("Remote Exception") if ret.code == UNAUTHORIZED: - raise Exception("Unauthorized") + raise Unauthorized() if ret.code == FORBIDDEN: - raise Exception("Forbidden") + raise Forbidden() return ret.read() def login(self, username, password): diff --git a/module/remote/WSClient.py b/module/remote/WSClient.py index c06bab661..23b5fc3ca 100644 --- a/module/remote/WSClient.py +++ b/module/remote/WSClient.py @@ -1,8 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from json_converter import loads, dumps from websocket import create_connection +from httplib import UNAUTHORIZED, FORBIDDEN + +from json_converter import loads, dumps +from ttypes import Unauthorized, Forbidden class WSClient: URL = "ws://localhost:7227/api" @@ -11,21 +14,34 @@ class WSClient: self.url = url or self.URL self.ws = None - def login(self, username, password): + def connect(self): self.ws = create_connection(self.URL) - return self.call("login", username, password) - def logout(self): - self.call("logout") + def close(self): self.ws.close() + def login(self, username, password): + if not self.ws: self.connect() + return self.call("login", username, password) + def call(self, func, *args, **kwargs): - self.ws.send(dumps([func, args, kwargs])) + if not self.ws: + raise Exception("Not Connected") + + if kwargs: + self.ws.send(dumps([func, args, kwargs])) + else: # omit kwargs + self.ws.send(dumps([func, args])) + code, result = loads(self.ws.recv()) if code == 404: raise AttributeError("Unknown Method") - elif code == 505: - raise Exception("Remote Exception") + elif code == 500: + raise Exception("Remote Exception: %s" % result) + elif code == UNAUTHORIZED: + raise Unauthorized() + elif code == FORBIDDEN: + raise Forbidden() return result diff --git a/module/remote/create_ttypes.py b/module/remote/create_ttypes.py index ab74a3441..fc4d75d32 100644 --- a/module/remote/create_ttypes.py +++ b/module/remote/create_ttypes.py @@ -111,6 +111,12 @@ from ttypes import *\n name = klass.__name__ base = "Exception" if issubclass(klass, ttypes.TExceptionBase) else "BaseObject" f.write("class %s(%s):\n" % (name, base)) + + # No attributes, don't write further info + if not klass.__slots__: + f.write("\tpass\n\n") + continue + f.write("\t__slots__ = %s\n\n" % klass.__slots__) dev.write("\t'%s' : [" % name) diff --git a/module/remote/json_converter.py b/module/remote/json_converter.py index ea76842a6..76a0d5935 100644 --- a/module/remote/json_converter.py +++ b/module/remote/json_converter.py @@ -29,6 +29,8 @@ def convert_obj(dct): del dct['@class'] return cls(**dct) + return dct + def dumps(*args, **kwargs): kwargs['cls'] = BaseEncoder return json.dumps(*args, **kwargs) diff --git a/module/remote/pyload.thrift b/module/remote/pyload.thrift index ea2aa7347..902c01534 100644 --- a/module/remote/pyload.thrift +++ b/module/remote/pyload.thrift @@ -314,6 +314,13 @@ exception ServiceException { 1: string msg } +exception Unauthorized { +} + +exception Forbidden { +} + + service Pyload { /////////////////////// diff --git a/module/remote/ttypes.py b/module/remote/ttypes.py index ecff45170..0412c3709 100644 --- a/module/remote/ttypes.py +++ b/module/remote/ttypes.py @@ -198,6 +198,9 @@ class FileInfo(BaseObject): self.fileorder = fileorder self.download = download +class Forbidden(Exception): + pass + class InteractionTask(BaseObject): __slots__ = ['iid', 'input', 'data', 'output', 'default_value', 'title', 'description', 'plugin'] @@ -310,6 +313,9 @@ class TreeCollection(BaseObject): self.files = files self.packages = packages +class Unauthorized(Exception): + pass + class UserData(BaseObject): __slots__ = ['uid', 'name', 'email', 'role', 'permission', 'folder', 'traffic', 'dllimit', 'dlquota', 'hddquota', 'user', 'templateName'] diff --git a/module/remote/wsbackend/ApiHandler.py b/module/remote/wsbackend/ApiHandler.py index e8ba80982..52dd05b9f 100644 --- a/module/remote/wsbackend/ApiHandler.py +++ b/module/remote/wsbackend/ApiHandler.py @@ -59,7 +59,7 @@ class ApiHandler(AbstractHandler): return self.send_result(req, self.OK, True) else: - return self.send_result(req, self.FORBIDDEN, "Forbidden") + return self.send_result(req, self.OK, False) elif func == 'logout': req.api = None diff --git a/tests/api/test_JSONBackend.py b/tests/api/test_JSONBackend.py index a3805497b..8d3373f65 100644 --- a/tests/api/test_JSONBackend.py +++ b/tests/api/test_JSONBackend.py @@ -2,6 +2,7 @@ from nose.tools import raises +from module.remote.ttypes import Forbidden from module.remote.JSONClient import JSONClient class TestJSONBackend: @@ -18,10 +19,11 @@ class TestJSONBackend: ret = self.client.login("WrongUser", "wrongpw") assert ret == False - @raises(Exception) + @raises(Forbidden) def test_access(self): self.client.getServerVersion() - @raises(Exception) + @raises(AttributeError) def test_unknown_method(self): + self.client.login("User", "test") self.client.sdfdsg() diff --git a/tests/api/test_WebSocketAPI.py b/tests/api/test_WebSocketAPI.py new file mode 100644 index 000000000..ac22d044e --- /dev/null +++ b/tests/api/test_WebSocketAPI.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +from nose.tools import raises + +from module.remote.ttypes import Forbidden +from module.remote.WSClient import WSClient + +class TestWebSocketAPI: + + def setUp(self): + self.client = WSClient() + self.client.connect() + + def tearDown(self): + self.client.close() + + def test_login(self): + self.client.login("User", "test") + self.client.getServerVersion() + self.client.logout() + + def test_wronglogin(self): + ret = self.client.login("WrongUser", "wrongpw") + assert ret == False + + @raises(Forbidden) + def test_access(self): + self.client.getServerVersion() + + @raises(AttributeError) + def test_unknown_method(self): + self.client.login("User", "test") + self.client.sdfdsg() |