Mercurial > hg > AuthRPC
changeset 26:346114023528 0.2.0a
Added __getfile__ mechanism
author | Ben Croston <ben@croston.org> |
---|---|
date | Mon, 02 Jan 2012 00:12:41 +0000 |
parents | d86e7357a91b |
children | 689d75bb60c2 |
files | AuthRPC/client/__init__.py AuthRPC/server/__init__.py AuthRPC/tests.py CHANGELOG.txt README.txt setup.py |
diffstat | 6 files changed, 70 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/AuthRPC/client/__init__.py Sun Jan 01 15:59:39 2012 +0000 +++ b/AuthRPC/client/__init__.py Mon Jan 02 00:12:41 2012 +0000 @@ -59,9 +59,13 @@ if self._password is not None: request['password'] = _encrypt_password(self._password) + if request['method'] == '__getfile__': + return self.call(json.dumps(request)) + resp = self.call(json.dumps(request)) if resp is None: raise Exception('Server response is None') + resp = json.loads(resp.decode()) if resp['id'] != request['id']: raise Exception('Inconsistent JSON request id returned') if resp['error'] is not None: @@ -165,7 +169,7 @@ except socket.error: raise NetworkSocketException if response.status == 200: - return json.loads(response.read().decode()) + return response.read() elif response.status == 400: raise BadRequestException(response.read().decode()) elif response.status == 401: @@ -182,10 +186,7 @@ raise Exception('HTTP Status %s'%response.status) def __repr__(self): - return ( - "<ServerProxy for %s%s>" % - (self.__host, self.__handler) - ) + return "<ServerProxy for %s%s>" %(self.__host, self.__handler) __str__ = __repr__ @@ -193,7 +194,6 @@ # magic method dispatcher return _Method(self._request, name, self._username, self._password) - ################# batch calls vvv class _BatchMethod(object): @@ -256,7 +256,7 @@ req += ', '.join(str(q) for q in self._queue) req += ']' - response = self._server._request(req) + response = json.loads(self._server._request(req).decode()) result = [] for i,r in enumerate(response):
--- a/AuthRPC/server/__init__.py Sun Jan 01 15:59:39 2012 +0000 +++ b/AuthRPC/server/__init__.py Mon Jan 02 00:12:41 2012 +0000 @@ -86,31 +86,42 @@ except KeyError as e: raise exc.HTTPBadRequest("JSON body missing parameter: %s" % e) self._check_auth(username, password, req.user_agent, id) + + if method == '__getfile__': + try: + with open(params[0],'rb') as f: + body = f.read() + except IOError: + raise exc.HTTPNotFound('File not found: %s'%params[0]) + return Response(content_type='application/octet-stream', + body=body) + result = self._process_single(method, params, id) return Response(content_type='application/json', body=dumps(result).encode()) def _check_auth(self, username, password, user_agent, id=None): - if self.auth is not None: - try: - auth_result = self.auth(username, password, user_agent) - except: - text = traceback.format_exc() - exc_value = sys.exc_info()[1] - error_value = dict( - name='JSONRPCError', - code=100, - message=str(exc_value), - error=text) - return Response( - status=500, - content_type='application/json', - body=dumps(dict(result=None, - error=error_value, - id=id))) - if not auth_result: - raise exc.HTTPUnauthorized() + if self.auth is None: + return + try: + auth_result = self.auth(username, password, user_agent) + except: + text = traceback.format_exc() + exc_value = sys.exc_info()[1] + error_value = dict( + name='JSONRPCError', + code=100, + message=str(exc_value), + error=text) + return Response( + status=500, + content_type='application/json', + body=dumps(dict(result=None, + error=error_value, + id=id))) + if not auth_result: + raise exc.HTTPUnauthorized() def _process_single(self, method, params, id): retval = {} @@ -130,7 +141,7 @@ break elif method.startswith('%s.'%self.obj.__class__.__name__): method = method.replace('%s.'%self.obj.__class__.__name__,'',1) - if method.startswith('_'): + if method.startswith('_') and method != '__getfile__': retval['error'] = 'Bad method name %s: must not start with _' % method return retval try:
--- a/AuthRPC/tests.py Sun Jan 01 15:59:39 2012 +0000 +++ b/AuthRPC/tests.py Mon Jan 02 00:12:41 2012 +0000 @@ -156,6 +156,29 @@ with self.assertRaises(ProtocolError): self.client.api.test(1, '2', three=3) +class FileTest(AuthRPCTests): + def runTest(self): + filename = 'LICENCE.txt' + with open(filename,'rb') as f: + source = f.read() + self.assertEqual(self.client.__getfile__(filename), source) + +class NonExistentFileTest(AuthRPCTests): + def runTest(self): + from client import NotFoundException + with self.assertRaises(NotFoundException): + self.client.__getfile__('nonexistant.file') + +class BadAuthFileTest(unittest.TestCase): + def runTest(self): + from client import ServerProxy, UnauthorisedException + self.client = ServerProxy('http://localhost:1337/', + username='testuser', + password='s3cr3t', + user_agent='InternetExploiter') + with self.assertRaises(UnauthorisedException): + self.client.__getfile__('LICENCE.txt') + class BatchTest(AuthRPCTests): def runTest(self): from client import BatchCall @@ -205,6 +228,9 @@ suite.addTest(AddTest()) suite.addTest(ReturnNothing()) suite.addTest(ProtocolErrorTest()) + suite.addTest(FileTest()) + suite.addTest(NonExistentFileTest()) + suite.addTest(BadAuthFileTest()) suite.addTest(BatchTest()) suite.addTest(SetFinishedFlag()) suite.addTest(BadBatchTest())
--- a/CHANGELOG.txt Sun Jan 01 15:59:39 2012 +0000 +++ b/CHANGELOG.txt Mon Jan 02 00:12:41 2012 +0000 @@ -1,6 +1,10 @@ Change Log ========== +0.2.0a +------ +- Added __getfile__ mechanism + 0.1.0a ------ - Added batch requests
--- a/README.txt Sun Jan 01 15:59:39 2012 +0000 +++ b/README.txt Mon Jan 02 00:12:41 2012 +0000 @@ -33,6 +33,7 @@ password='secret', user_agent='myprogram') retval = client.do_something('test') + file_contents = client.__getfile__('myfile.pdf') batch = BatchCall(client) batch.do_something('call 1') batch.do_something('call 2')