From afba642b3a9556661b16220751283b8a2f9fc1c4 Mon Sep 17 00:00:00 2001 From: Nico Alt <nicoalt@posteo.org> Date: Mon, 8 Mar 2021 13:00:00 +0000 Subject: [PATCH] Add function to delete pending contact --- .../pending_already_exists_contact.py | 4 +- .../pending_already_exists_pending_contact.py | 5 +- briar_wrapper/models/contacts.py | 67 +++++++++---- tests/briar_wrapper/models/test_contacts.py | 99 +++++++++++++++++++ 4 files changed, 153 insertions(+), 22 deletions(-) diff --git a/briar_wrapper/exceptions/pending_already_exists_contact.py b/briar_wrapper/exceptions/pending_already_exists_contact.py index 4c9bf32..1b29392 100644 --- a/briar_wrapper/exceptions/pending_already_exists_contact.py +++ b/briar_wrapper/exceptions/pending_already_exists_contact.py @@ -12,5 +12,5 @@ class PendingContactAlreadyExistsContact(BriarWrapperException): def __init__(self, response, message=""): self.response = response error = response.json() - self.remoteAuthorName = error["remoteAuthorName"] - super().__init__(message) + self.remote_author_name = error["remoteAuthorName"] + super().__init__(response, message) diff --git a/briar_wrapper/exceptions/pending_already_exists_pending_contact.py b/briar_wrapper/exceptions/pending_already_exists_pending_contact.py index a2329ce..63c23a3 100644 --- a/briar_wrapper/exceptions/pending_already_exists_pending_contact.py +++ b/briar_wrapper/exceptions/pending_already_exists_pending_contact.py @@ -12,5 +12,6 @@ class PendingContactAlreadyExistsPendingContact(BriarWrapperException): def __init__(self, response, message=""): self.response = response error = response.json() - self.pendingContactAlias = error["pendingContactAlias"] - super().__init__(message) + self.pending_contact_alias = error["pendingContactAlias"] + self.pending_contact_id = error["pendingContactId"] + super().__init__(response, message) diff --git a/briar_wrapper/models/contacts.py b/briar_wrapper/models/contacts.py index 52e2276..9c02b48 100644 --- a/briar_wrapper/models/contacts.py +++ b/briar_wrapper/models/contacts.py @@ -4,7 +4,7 @@ """ Wrapper around Briar API's _/contacts/_ resource """ - +from json.decoder import JSONDecodeError from operator import itemgetter from typing import Callable, List from urllib.parse import urljoin @@ -33,16 +33,21 @@ class Contacts(Model): _connections_callback = None - def add_pending(self, link: str, alias: str) -> bool: + def add_pending(self, link: str, alias: str) -> None: # 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_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) @@ -54,24 +59,26 @@ class Contacts(Model): response = _post(url, headers=self._headers, json={"link": link, "alias": alias}) if response.status_code == 200: - return True + return 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) + def delete_pending(self, contact_id: str) -> None: + # pylint: disable=line-too-long + """ + Deletes pending contact with `id` + + [Upstream documentation](https://code.briarproject.org/briar/briar/blob/master/briar-headless/README.md#adding-a-contact) + + .. versionadded:: 0.0.7 + """ + url = urljoin(BASE_HTTP_URL, self._API_ENDPOINT + "add/pending/") + response = _delete(url, headers=self._headers, + json={"pendingContactId": contact_id}) + if response.status_code == 200: + return raise BriarWrapperException(response, "An unknown error occurred while" - f"adding a pending contact: {response.text}") + f"deleting a pending contact: " + f"{response.text}") def set_alias(self, contact_id: int, alias: str) -> None: # pylint: disable=line-too-long @@ -156,6 +163,30 @@ class Contacts(Model): else: raise Exception(f"Wrong event in callback: {message['name']}") + @staticmethod + def _handle_add_pending_error(response): + error = dict() + try: + error = response.json() + except JSONDecodeError as json_error: + raise BriarWrapperException(response, + "An unknown error occurred while" + "adding a pending contact: " + "JSONDecodeError") from json_error + 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: " + f"{response.text}") + @staticmethod def _sort_contact_list(contacts: list) -> list: contacts.sort(key=itemgetter("lastChatActivity"), diff --git a/tests/briar_wrapper/models/test_contacts.py b/tests/briar_wrapper/models/test_contacts.py index 2017565..ba49324 100644 --- a/tests/briar_wrapper/models/test_contacts.py +++ b/tests/briar_wrapper/models/test_contacts.py @@ -6,6 +6,15 @@ import json import pytest import requests_mock +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.models.contacts import Contacts from briar_wrapper.models.socket_listener import SocketListener @@ -14,6 +23,7 @@ BASE_HTTP_URL = "http://localhost:7000/v1/contacts/" TEST_ALIAS = "Alice" TEST_CONTACT_ID = 42 +TEST_PENDING_CONTACT_ID = "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=" TEST_CONTACT_FIRST = { "lastChatActivity": 1 @@ -50,6 +60,95 @@ def match_request_add_pending(request): return {"alias": TEST_ALIAS, "link": TEST_LINK} == request.json() +@requests_mock.Mocker(kw="requests_mock") +def test_add_pending_invalid_public_key(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.post(BASE_HTTP_URL + "add/pending/", + status_code=400, + json={"error": "INVALID_PUBLIC_KEY"}) + with pytest.raises(PendingContactInvalidPublicKeyException): + contacts.add_pending(TEST_LINK, TEST_ALIAS) + + +@requests_mock.Mocker(kw="requests_mock") +def test_add_pending_invalid_link(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.post(BASE_HTTP_URL + "add/pending/", + status_code=400, + json={"error": "INVALID_LINK"}) + with pytest.raises(PendingContactInvalidLinkException): + contacts.add_pending(TEST_LINK, TEST_ALIAS) + + +@requests_mock.Mocker(kw="requests_mock") +def test_add_pending_contact_exists(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.post(BASE_HTTP_URL + "add/pending/", + status_code=403, + json={ + "error": "CONTACT_EXISTS", + "remoteAuthorName": TEST_ALIAS + }) + with pytest.raises(PendingContactAlreadyExistsContact): + contacts.add_pending(TEST_LINK, TEST_ALIAS) + + +@requests_mock.Mocker(kw="requests_mock") +def test_add_pending_pending_exists(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.post(BASE_HTTP_URL + "add/pending/", + status_code=403, + json={ + "error": "PENDING_EXISTS", + "pendingContactAlias": TEST_ALIAS, + "pendingContactId": TEST_PENDING_CONTACT_ID + }) + with pytest.raises(PendingContactAlreadyExistsPendingContact): + contacts.add_pending(TEST_LINK, TEST_ALIAS) + + +@requests_mock.Mocker(kw="requests_mock") +def test_add_pending_unknown_error(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.post(BASE_HTTP_URL + "add/pending/", + status_code=500, + json={"error": "CRAZY_ERROR"}) + with pytest.raises(BriarWrapperException): + contacts.add_pending(TEST_LINK, TEST_ALIAS) + + +@requests_mock.Mocker(kw="requests_mock") +def test_add_pending_no_json(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.post(BASE_HTTP_URL + "add/pending/", + status_code=500) + with pytest.raises(BriarWrapperException): + contacts.add_pending(TEST_LINK, TEST_ALIAS) + + +@requests_mock.Mocker(kw="requests_mock") +def test_delete_pending(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.register_uri("DELETE", + BASE_HTTP_URL + "add/pending/", + request_headers=request_headers, + additional_matcher=match_request_delete_pending) + contacts.delete_pending(TEST_PENDING_CONTACT_ID) + + +def match_request_delete_pending(request): + return {"pendingContactId": TEST_PENDING_CONTACT_ID} == request.json() + + +@requests_mock.Mocker(kw="requests_mock") +def test_delete_pending_unknown_error(api, request_headers, requests_mock): + contacts = Contacts(api) + requests_mock.delete(BASE_HTTP_URL + "add/pending/", + status_code=500) + with pytest.raises(BriarWrapperException): + contacts.delete_pending(TEST_PENDING_CONTACT_ID) + + @requests_mock.Mocker(kw="requests_mock") def test_set_alias(api, request_headers, requests_mock): contacts = Contacts(api) -- GitLab