diff --git a/briar_wrapper/exception.py b/briar_wrapper/exception.py new file mode 100644 index 0000000000000000000000000000000000000000..9de0ee947ba821019db84a7099804040bf1486a6 --- /dev/null +++ b/briar_wrapper/exception.py @@ -0,0 +1,13 @@ +# Copyright (c) 2021 Nico Alt +# SPDX-License-Identifier: AGPL-3.0-only +# License-Filename: LICENSE.md +""" +Forward exceptions thrown by Briar Headless +""" + + +class BriarWrapperException(Exception): + + def __init__(self, response, message=""): + self.response = response + super().__init__(message) diff --git a/briar_wrapper/exceptions/__init__.py b/briar_wrapper/exceptions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fba05b9f406d21d8d08def7dc54b0d69b95f53f1 --- /dev/null +++ b/briar_wrapper/exceptions/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Nico Alt +# SPDX-License-Identifier: AGPL-3.0-only +# License-Filename: LICENSE.md +""" +Exceptions thrown in case of errors +""" diff --git a/briar_wrapper/exceptions/pending_already_exists_contact.py b/briar_wrapper/exceptions/pending_already_exists_contact.py new file mode 100644 index 0000000000000000000000000000000000000000..4c9bf3262d064eaa88aa87027811ea7408c82074 --- /dev/null +++ b/briar_wrapper/exceptions/pending_already_exists_contact.py @@ -0,0 +1,16 @@ +# Copyright (c) 2021 Nico Alt +# SPDX-License-Identifier: AGPL-3.0-only +# License-Filename: LICENSE.md +""" +Thrown when a contact already exists while adding a pending contact +""" +from briar_wrapper.exception import BriarWrapperException + + +class PendingContactAlreadyExistsContact(BriarWrapperException): + + def __init__(self, response, message=""): + self.response = response + error = response.json() + self.remoteAuthorName = error["remoteAuthorName"] + super().__init__(message) diff --git a/briar_wrapper/exceptions/pending_already_exists_pending_contact.py b/briar_wrapper/exceptions/pending_already_exists_pending_contact.py new file mode 100644 index 0000000000000000000000000000000000000000..a2329cedc738a770de9e305fb1a62332765a1cbf --- /dev/null +++ b/briar_wrapper/exceptions/pending_already_exists_pending_contact.py @@ -0,0 +1,16 @@ +# Copyright (c) 2021 Nico Alt +# SPDX-License-Identifier: AGPL-3.0-only +# License-Filename: LICENSE.md +""" +Thrown when a contact already exists while adding a pending contact +""" +from briar_wrapper.exception import BriarWrapperException + + +class PendingContactAlreadyExistsPendingContact(BriarWrapperException): + + def __init__(self, response, message=""): + self.response = response + error = response.json() + self.pendingContactAlias = error["pendingContactAlias"] + super().__init__(message) diff --git a/briar_wrapper/exceptions/pending_invalid_link.py b/briar_wrapper/exceptions/pending_invalid_link.py new file mode 100644 index 0000000000000000000000000000000000000000..0979edb9e31b14954282d1feb4c147e93bc7b5ba --- /dev/null +++ b/briar_wrapper/exceptions/pending_invalid_link.py @@ -0,0 +1,11 @@ +# Copyright (c) 2021 Nico Alt +# SPDX-License-Identifier: AGPL-3.0-only +# License-Filename: LICENSE.md +""" +Thrown when public key of pending contact is invalid +""" +from briar_wrapper.exception import BriarWrapperException + + +class PendingContactInvalidLinkException(BriarWrapperException): + pass diff --git a/briar_wrapper/exceptions/pending_invalid_public_key.py b/briar_wrapper/exceptions/pending_invalid_public_key.py new file mode 100644 index 0000000000000000000000000000000000000000..9186cc04cdd926130ea2261ae1c7ac89a4976bea --- /dev/null +++ b/briar_wrapper/exceptions/pending_invalid_public_key.py @@ -0,0 +1,11 @@ +# Copyright (c) 2021 Nico Alt +# SPDX-License-Identifier: AGPL-3.0-only +# License-Filename: LICENSE.md +""" +Thrown when public key of pending contact is invalid +""" +from briar_wrapper.exception import BriarWrapperException + + +class PendingContactInvalidPublicKeyException(BriarWrapperException): + pass diff --git a/briar_wrapper/models/contacts.py b/briar_wrapper/models/contacts.py index 763024e308044ed55db25481e4a081ded0b49126..52e22762ad1763277c65a2ba4f0d3c0c732621e3 100644 --- a/briar_wrapper/models/contacts.py +++ b/briar_wrapper/models/contacts.py @@ -15,28 +15,63 @@ from requests import post as _post from requests import put as _put from briar_wrapper.constants import BASE_HTTP_URL +from briar_wrapper.exception import BriarWrapperException +from briar_wrapper.exceptions.pending_already_exists_contact import \ + PendingContactAlreadyExistsContact +from briar_wrapper.exceptions.pending_already_exists_pending_contact import \ + PendingContactAlreadyExistsPendingContact +from briar_wrapper.exceptions.pending_invalid_link import \ + PendingContactInvalidLinkException +from briar_wrapper.exceptions.pending_invalid_public_key import \ + PendingContactInvalidPublicKeyException from briar_wrapper.model import Model class Contacts(Model): - _API_ENDPOINT = "contacts/" _CONNECTION_EVENTS = ("ContactConnectedEvent", "ContactDisconnectedEvent") _connections_callback = None - def add_pending(self, link: str, alias: str) -> None: + def add_pending(self, link: str, alias: str) -> bool: # pylint: disable=line-too-long """ - Adds pending contact to Briar with `link` URL and `alias` + Raises: + * `briar_wrapper.exceptions.pending_already_exists_pending_contact.PendingContactAlreadyExistsContact` + * `briar_wrapper.exceptions.pending_already_exists_pending_contact.PendingContactAlreadyExistsPendingContact` + * `briar_wrapper.exceptions.pending_invalid_link.PendingContactInvalidLinkException` + * `briar_wrapper.exceptions.pending_invalid_public_key.PendingContactInvalidPublicKeyException` + * `briar_wrapper.exception.BriarWrapperException` for unknown API errors + [Upstream documentation](https://code.briarproject.org/briar/briar/blob/master/briar-headless/README.md#adding-a-contact) .. versionadded:: 0.0.3 + .. versionchanged:: 0.0.7 """ url = urljoin(BASE_HTTP_URL, self._API_ENDPOINT + "add/pending/") - _post(url, headers=self._headers, json={"link": link, "alias": alias}) + response = _post(url, headers=self._headers, + json={"link": link, "alias": alias}) + if response.status_code == 200: + return True + self._handle_add_pending_error(response) + + @staticmethod + def _handle_add_pending_error(response): + error = response.json() + if response.status_code == 400: + if error["error"] == "INVALID_PUBLIC_KEY": + raise PendingContactInvalidPublicKeyException(response) + if error["error"] == "INVALID_LINK": + raise PendingContactInvalidLinkException(response) + if response.status_code == 403: + if error["error"] == "CONTACT_EXISTS": + raise PendingContactAlreadyExistsContact(response) + if error["error"] == "PENDING_EXISTS": + raise PendingContactAlreadyExistsPendingContact(response) + raise BriarWrapperException(response, "An unknown error occurred while" + f"adding a pending contact: {response.text}") def set_alias(self, contact_id: int, alias: str) -> None: # pylint: disable=line-too-long @@ -48,7 +83,8 @@ class Contacts(Model): .. versionadded:: 0.0.5 .. versionchanged:: 0.0.6 """ - url = urljoin(BASE_HTTP_URL, self._API_ENDPOINT + f"{str(contact_id)}/alias") + url = urljoin(BASE_HTTP_URL, + self._API_ENDPOINT + f"{str(contact_id)}/alias") _put(url, headers=self._headers, json={"alias": alias}) def delete(self, contact_id: int) -> None: