From 83f386ea7258e9ecb92c3d5dbcb09ed514f437b4 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Thu, 31 Aug 2017 03:17:19 -0300 Subject: [feature] add support for soledad incoming api -- Related: #8664 --- src/leap/mx/soledadhelper.py | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/leap/mx/soledadhelper.py (limited to 'src/leap/mx/soledadhelper.py') diff --git a/src/leap/mx/soledadhelper.py b/src/leap/mx/soledadhelper.py new file mode 100644 index 0000000..4b2a099 --- /dev/null +++ b/src/leap/mx/soledadhelper.py @@ -0,0 +1,89 @@ +# -*- encoding: utf-8 -*- +# soledadhelper.py +# Copyright (C) 2017 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +""" +Classes for working with Soledad Incoming API. +See: http://soledad.readthedocs.io/en/latest/incoming_box.html +""" + + +import base64 +import treq +from six import raise_from +from io import BytesIO +from twisted.internet import defer + + +class UnavailableIncomingAPIException(Exception): + pass + + +class SoledadIncomingAPI: + """ + Delivers messages using Soledad Incoming API. + """ + + def __init__(self, host, port, token): + """ + Creates a SoledadIncomingAPI helper to deliver messages into user's + database. + + :param host: A hostname string for the Soledad incoming service host. + This will usually be localhost, unless served over stunnel. + :type host: str + :param port: The port of the Soledad incoming service host. + :type port: int + :param token: Incoming service authentication token as configured in + Soledad. + :type token: str + """ + self._incoming_url = "http://%s:%s/incoming/" % (host, port) + b64_token = base64.b64encode(token) + self._auth_header = {'Authorization': ['Token %s' % b64_token]} + + @defer.inlineCallbacks + def put_doc(self, uuid, doc_id, content): + """ + Make a PUT request to Soledad's incoming API, delivering a message into + user's database. + + :param uuid: The uuid of a user + :type uuid: str + :param content: Message content. + :type content: str + + :return: A deferred which fires after the HTTP request is complete, or + which fails with the correspondent exception if there was any + error. + """ + url = self._incoming_url + "user-%s/%s" % (uuid, doc_id) + try: + response = yield treq.put( + url, + BytesIO(str(content)), + headers=self._auth_header, + persistent=False) + except Exception as original_exception: + error_message = "Server unreacheable or unknown error: %s" + error_message %= (original_exception.message) + our_exception = UnavailableIncomingAPIException(error_message) + raise_from(our_exception, original_exception) + if not response.code == 200: + error_message = '%s returned status %s instead of 200' + error_message %= (url, response.code) + raise UnavailableIncomingAPIException(error_message) -- cgit v1.2.3