diff --git a/daemon.py b/daemon.py index 27ff86eb3..4a85356f5 100644 --- a/daemon.py +++ b/daemon.py @@ -17313,6 +17313,88 @@ class PubServer(BaseHTTPRequestHandler): self._400() return + # wanted items collection for this instance + # this is only accessible to instance members or to + # other instances which present an authorization token + if self.path.startswith('/users/') and '/wanted' in self.path: + wanted_collection_authorized = authorized + nickname = self.path.split('/users/')[1] + if '/' in nickname: + nickname = nickname.split('/')[0] + page_number = 1 + if '?page=' in self.path: + page_number_str = self.path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if page_number_str.isdigit(): + page_number = int(page_number_str) + if not wanted_collection_authorized: + if self.server.debug: + print('Wanted collection access is not authorized. ' + + 'Checking Authorization header') + # Check the authorization token + if self.headers.get('Origin') and \ + self.headers.get('Authorization'): + permitted_domains = \ + self.server.shared_items_federated_domains + shared_item_tokens = \ + self.server.shared_item_federation_tokens + if authorize_shared_items(permitted_domains, + self.server.base_dir, + self.headers['Origin'], + calling_domain, + self.headers['Authorization'], + self.server.debug, + shared_item_tokens): + wanted_collection_authorized = True + elif self.server.debug: + print('Authorization token refused for ' + + 'wanted collection federation') + # show wanted collection for federation + if self._has_accept(calling_domain) and \ + wanted_collection_authorized: + if self.server.debug: + print('Preparing wanted collection') + + domain_full = self.server.domain_full + http_prefix = self.server.http_prefix + nickname = self.path.split('/users/')[1] + if '/' in nickname: + nickname = nickname.split('/')[0] + if self.server.debug: + print('Wanted collection for account: ' + nickname) + base_dir = self.server.base_dir + wanted_items_per_page = 12 + max_shares_per_account = wanted_items_per_page + shared_items_federated_domains = \ + self.server.shared_items_federated_domains + actor = \ + local_actor_url(http_prefix, nickname, domain_full) + \ + '/wanted' + wanted_json = \ + get_shares_collection(actor, page_number, + wanted_items_per_page, base_dir, + self.server.domain, nickname, + max_shares_per_account, + shared_items_federated_domains, + 'wanted') + msg_str = json.dumps(wanted_json, + ensure_ascii=False) + msg_str = self._convert_domains(calling_domain, + referer_domain, + msg_str) + msg = msg_str.encode('utf-8') + msglen = len(msg) + accept_str = self.headers['Accept'] + protocol_str = \ + get_json_content_from_accept(accept_str) + self._set_headers(protocol_str, msglen, + None, calling_domain, False) + self._write(msg) + return + self._400() + return + # shared items catalog for this instance # this is only accessible to instance members or to # other instances which present an authorization token diff --git a/shares.py b/shares.py index 1a79c808d..380c8e68d 100644 --- a/shares.py +++ b/shares.py @@ -1067,6 +1067,41 @@ def get_offers_via_server(session, nickname: str, password: str, return offers_json +def get_wanted_via_server(session, nickname: str, password: str, + domain: str, port: int, + http_prefix: str, debug: bool, + signing_priv_key_pem: str) -> {}: + """Returns the wanted collection for shared items via c2s + """ + if not session: + print('WARN: No session for get_wanted_via_server') + return 6 + + auth_header = create_basic_auth_header(nickname, password) + + headers = { + 'host': domain, + 'Content-type': 'application/json', + 'Authorization': auth_header, + 'Accept': 'application/json' + } + domain_full = get_full_domain(domain, port) + url = local_actor_url(http_prefix, nickname, domain_full) + '/wanted' + if debug: + print('Wanted collection request to: ' + url) + wanted_json = get_json(signing_priv_key_pem, session, url, headers, None, + debug, __version__, http_prefix, None) + if not wanted_json: + if debug: + print('DEBUG: GET wanted collection failed for c2s to ' + url) +# return 5 + + if debug: + print('DEBUG: c2s GET wanted collection success') + + return wanted_json + + def outbox_share_upload(base_dir: str, http_prefix: str, nickname: str, domain: str, port: int, message_json: {}, debug: bool, city: str, diff --git a/tests.py b/tests.py index 9b165423e..45083d952 100644 --- a/tests.py +++ b/tests.py @@ -199,6 +199,7 @@ from shares import merge_shared_item_tokens from shares import send_share_via_server from shares import get_shared_items_catalog_via_server from shares import get_offers_via_server +from shares import get_wanted_via_server from cwlists import add_cw_from_lists from cwlists import load_cw_lists from happening import dav_month_via_server @@ -2090,7 +2091,17 @@ def test_shared_items_federation(base_dir: str) -> None: print('Offers collection:') pprint(offers_json) assert isinstance(offers_json, list) - assert len(offers_json) == 1 + assert len(offers_json) >= 1 + + wanted_json = \ + get_wanted_via_server(session_bob, 'bob', bob_password, + bob_domain, bob_port, + http_prefix, True, + signing_priv_key_pem) + print('Wanted collection:') + pprint(wanted_json) + assert isinstance(wanted_json, list) + assert len(wanted_json) == 0 print('\n\n*********************************************************') print('Alice sends a message to Bob')