diff --git a/epicyon.py b/epicyon.py index d90b14fb5..62ce6dfa7 100644 --- a/epicyon.py +++ b/epicyon.py @@ -3338,8 +3338,9 @@ def _command_options() -> None: if domain.endswith('.ipns'): port = 80 http_prefix = 'ipns' + password = argb.password.strip() create_person(base_dir, nickname, domain, port, http_prefix, - True, not argb.noapproval, argb.password.strip()) + True, not argb.noapproval, password, debug) if is_a_dir(account_dir): print('Account created for ' + nickname + '@' + domain) else: @@ -3375,8 +3376,9 @@ def _command_options() -> None: if is_a_dir(account_dir): print('Group already exists') sys.exit() + password = argb.password.strip() create_group(base_dir, nickname, domain, port, http_prefix, - True, argb.password.strip()) + True, password, debug) if is_a_dir(account_dir): print('Group created for ' + nickname + '@' + domain) else: @@ -3914,16 +3916,15 @@ def _command_options() -> None: str(max_registrations)) create_person(base_dir, 'maxboardroom', domain, port, http_prefix, - True, False, password) + True, False, password, debug) create_person(base_dir, 'ultrapancake', domain, port, http_prefix, - True, False, password) + True, False, password, debug) create_person(base_dir, 'drokk', domain, port, http_prefix, - True, False, password) + True, False, password, debug) create_person(base_dir, 'sausagedog', domain, port, http_prefix, - True, False, password) - + True, False, password, debug) create_person(base_dir, nickname, domain, port, http_prefix, - True, False, 'likewhateveryouwantscoob') + True, False, 'likewhateveryouwantscoob', debug) set_skill_level(base_dir, nickname, domain, 'testing', 60) set_skill_level(base_dir, nickname, domain, 'typing', 50) set_role(base_dir, nickname, domain, 'admin') diff --git a/src/daemon_post_login.py b/src/daemon_post_login.py index 7a2103b04..bece1b3cd 100644 --- a/src/daemon_post_login.py +++ b/src/daemon_post_login.py @@ -116,7 +116,7 @@ def post_login_screen(self, calling_domain: str, cookie: str, if not register_account(base_dir, http_prefix, domain, port, login_nickname, login_password, - manual_follower_approval): + manual_follower_approval, debug): self.server.postreq_busy = False login_url = \ get_instance_url(calling_domain, diff --git a/src/person.py b/src/person.py index 51fa695a4..29446874e 100644 --- a/src/person.py +++ b/src/person.py @@ -466,7 +466,8 @@ def _create_person_base(base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, save_to_file: bool, manual_follower_approval: bool, group_account: bool, - password: str) -> (str, str, {}, {}): + password: str, + debug: bool) -> (str, str, {}, {}): """Returns the private key, public key, actor and webfinger endpoint """ private_key_pem, public_key_pem = generate_rsa_key() @@ -676,12 +677,17 @@ def _create_person_base(base_dir: str, nickname: str, domain: str, port: int, password = remove_eol(password).strip() store_basic_credentials(base_dir, nickname, password) + if debug: + print('DEBUG: _create_person_base type ' + person_type + ' ' + + nickname + '@' + domain) + return private_key_pem, public_key_pem, new_person, webfinger_endpoint def register_account(base_dir: str, http_prefix: str, domain: str, port: int, nickname: str, password: str, - manual_follower_approval: bool) -> bool: + manual_follower_approval: bool, + debug: bool) -> bool: """Registers a new account from the web interface """ if _account_exists(base_dir, nickname, domain): @@ -697,7 +703,7 @@ def register_account(base_dir: str, http_prefix: str, domain: str, port: int, domain, port, http_prefix, True, manual_follower_approval, - password) + password, debug) if private_key_pem: return True return False @@ -705,14 +711,16 @@ def register_account(base_dir: str, http_prefix: str, domain: str, port: int, def create_group(base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, save_to_file: bool, - password: str) -> (str, str, {}, {}): + password: str, + debug: bool) -> (str, str, {}, {}): """Returns a group """ (private_key_pem, public_key_pem, new_person, webfinger_endpoint) = create_person(base_dir, nickname, domain, port, http_prefix, save_to_file, - False, password, True) + False, password, + debug, True) return private_key_pem, public_key_pem, new_person, webfinger_endpoint @@ -750,7 +758,12 @@ def save_person_qrcode(base_dir: str, if is_a_file(qrcode_filename): return handle = get_full_domain('@' + nickname + '@' + qrcode_domain, port) - url = pyqrcode.create(handle) + try: + url = pyqrcode.create(handle) + except UnicodeEncodeError as exc: + print('EX: pyqrcode unable to create from handle ' + handle + + ' ' + str(exc)) + return try: url.png(qrcode_filename, scale) except ModuleNotFoundError: @@ -761,10 +774,13 @@ def create_person(base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, save_to_file: bool, manual_follower_approval: bool, password: str, + debug: bool, group_account: bool = False) -> (str, str, {}, {}): """Returns the private key, public key, actor and webfinger endpoint """ if not valid_nickname(domain, nickname): + if debug: + print('DEBUG: create_person invalid nickname') return None, None, None, None # If a config.json file doesn't exist then don't decrement @@ -775,11 +791,15 @@ def create_person(base_dir: str, nickname: str, domain: str, port: int, if remaining_config_exists: registrations_remaining = int(remaining_config_exists) if registrations_remaining <= 0: + if debug: + print('DEBUG: create_person no registrations remaining') return None, None, None, None else: dir_str = data_dir(base_dir) if is_a_dir(dir_str + '/news@' + domain): # news account already exists + if debug: + print('DEBUG: create_person news account already exists') return None, None, None, None manual_follower = manual_follower_approval @@ -791,7 +811,8 @@ def create_person(base_dir: str, nickname: str, domain: str, port: int, save_to_file, manual_follower, group_account, - password) + password, + debug) if not get_config_param(base_dir, 'admin'): if nickname != 'news': # print(nickname+' becomes the instance admin and a moderator') @@ -873,16 +894,18 @@ def create_shared_inbox(base_dir: str, nickname: str, domain: str, port: int, http_prefix: str) -> (str, str, {}, {}): """Generates the shared inbox """ + debug = False return _create_person_base(base_dir, nickname, domain, port, http_prefix, - True, True, False, None) + True, True, False, None, debug) def create_news_inbox(base_dir: str, domain: str, port: int, http_prefix: str) -> (str, str, {}, {}): """Generates the news inbox """ + debug = False return create_person(base_dir, 'news', domain, port, - http_prefix, True, True, None) + http_prefix, True, True, None, debug) def person_upgrade_actor(base_dir: str, person_json: {}, diff --git a/src/tests.py b/src/tests.py index c24c2559b..d19ce6a46 100644 --- a/src/tests.py +++ b/src/tests.py @@ -346,7 +346,7 @@ def _test_http_signed_get(base_dir: str): no_recency_check = True private_key_pem, public_key_pem, _, _ = \ create_person(path, nickname, domain, port, http_prefix, - False, False, password) + False, False, password, debug) assert private_key_pem assert public_key_pem message_body_json_str = '' @@ -634,7 +634,7 @@ def _test_signature(): assert total % system == 374 -def _test_httpsig_base(with_digest: bool, base_dir: str): +def _test_httpsig_base(with_digest: bool, base_dir: str, nickname: str): print('test_httpsig(' + str(with_digest) + ')') path = base_dir + '/.testHttpsigBase' @@ -643,10 +643,10 @@ def _test_httpsig_base(with_digest: bool, base_dir: str): makedir(path) os.chdir(path) + debug = True algorithm = 'rsa-sha256' digest_algorithm = 'rsa-sha256' content_type = 'application/activity+json' - nickname = 'socrates' host_domain = 'someother.instance' domain = 'argumentative.social' http_prefix = 'https' @@ -654,7 +654,7 @@ def _test_httpsig_base(with_digest: bool, base_dir: str): password = 'SuperSecretPassword' private_key_pem, public_key_pem, person, wf_endpoint = \ create_person(path, nickname, domain, port, http_prefix, - False, False, password) + False, False, password, debug) assert private_key_pem assert public_key_pem assert person @@ -757,8 +757,10 @@ def _test_httpsig_base(with_digest: bool, base_dir: str): def _test_httpsig(base_dir: str): - _test_httpsig_base(True, base_dir) - _test_httpsig_base(False, base_dir) + for nickname in ('socrates', '有効', 'дійсний', 'גילטיק'): + print('\nTesting http signatures with nickname ' + nickname) + _test_httpsig_base(True, base_dir, nickname) + _test_httpsig_base(False, base_dir, nickname) def _test_cache(): @@ -803,6 +805,7 @@ def create_server_alice(path: str, domain: str, port: int, shutil.rmtree(path, ignore_errors=False) makedir(path) os.chdir(path) + debug = True shared_items_federated_domains: list[str] = [] system_language: str = 'en' languages_understood: list[str] = [system_language] @@ -817,7 +820,7 @@ def create_server_alice(path: str, domain: str, port: int, low_bandwidth: bool = True private_key_pem, public_key_pem, person, wf_endpoint = \ create_person(path, nickname, domain, port, http_prefix, True, - False, password) + False, password, debug) assert private_key_pem assert public_key_pem assert person @@ -1013,6 +1016,7 @@ def create_server_bob(path: str, domain: str, port: int, shutil.rmtree(path, ignore_errors=False) makedir(path) os.chdir(path) + debug = True shared_items_federated_domains: list[str] = [] system_language: str = 'en' languages_understood: list = [system_language] @@ -1028,7 +1032,7 @@ def create_server_bob(path: str, domain: str, port: int, low_bandwidth: bool = True private_key_pem, public_key_pem, person, wf_endpoint = \ create_person(path, nickname, domain, port, http_prefix, True, - False, password) + False, password, debug) assert private_key_pem assert public_key_pem assert person @@ -1223,6 +1227,7 @@ def create_server_eve(path: str, domain: str, port: int, federation_list: [], shutil.rmtree(path, ignore_errors=False) makedir(path) os.chdir(path) + debug = True shared_items_federated_domains: list[str] = [] nickname: str = 'eve' http_prefix: str = 'http' @@ -1232,7 +1237,7 @@ def create_server_eve(path: str, domain: str, port: int, federation_list: [], allow_deletion = True private_key_pem, public_key_pem, person, wf_endpoint = \ create_person(path, nickname, domain, port, http_prefix, True, - False, password) + False, password, debug) assert private_key_pem assert public_key_pem assert person @@ -1350,6 +1355,7 @@ def create_server_group(path: str, domain: str, port: int, os.chdir(path) shared_items_federated_domains: list[str] = [] # system_language = 'en' + debug = True nickname = 'testgroup' http_prefix = 'http' proxy_type = None @@ -1360,7 +1366,7 @@ def create_server_group(path: str, domain: str, port: int, allow_deletion = True private_key_pem, public_key_pem, person, wf_endpoint = \ create_group(path, nickname, domain, port, http_prefix, True, - password) + password, debug) assert private_key_pem assert public_key_pem assert person @@ -2957,6 +2963,7 @@ def test_group_follow(base_dir: str) -> None: def _test_followers_of_person(base_dir: str) -> None: print('test_followers_of_person') + debug = True curr_dir = base_dir nickname = 'mxpop' domain = 'diva.domain' @@ -2970,15 +2977,15 @@ def _test_followers_of_person(base_dir: str) -> None: makedir(base_dir) os.chdir(base_dir) create_person(base_dir, nickname, domain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'maxboardroom', domain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'ultrapancake', domain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'drokk', domain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'sausagedog', domain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) clear_follows(base_dir, nickname, domain, 'following.txt') follow_person(base_dir, nickname, domain, 'maxboardroom', domain, @@ -3006,6 +3013,7 @@ def _test_followers_of_person(base_dir: str) -> None: def _test_followers_on_domain(base_dir: str) -> None: print('test_followers_on_domain') + debug = True curr_dir = base_dir nickname = 'mxpop' domain = 'diva.domain' @@ -3020,15 +3028,15 @@ def _test_followers_on_domain(base_dir: str) -> None: makedir(base_dir) os.chdir(base_dir) create_person(base_dir, nickname, domain, port, http_prefix, True, - False, password) + False, password, debug) create_person(base_dir, 'maxboardroom', otherdomain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'ultrapancake', otherdomain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'drokk', otherdomain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) create_person(base_dir, 'sausagedog', otherdomain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) follow_person(base_dir, 'drokk', otherdomain, nickname, domain, federation_list, False, False, 'following.txt') @@ -3074,6 +3082,7 @@ def _test_followers_on_domain(base_dir: str) -> None: def _test_group_followers(base_dir: str) -> None: print('test_group_followers') + debug = True curr_dir = base_dir nickname = 'test735' domain = 'mydomain.com' @@ -3087,7 +3096,7 @@ def _test_group_followers(base_dir: str) -> None: makedir(base_dir) os.chdir(base_dir) create_person(base_dir, nickname, domain, port, http_prefix, True, - False, password) + False, password, debug) clear_followers(base_dir, nickname, domain) add_follower_of_person(base_dir, nickname, domain, 'badger', 'wild.domain', @@ -3120,6 +3129,7 @@ def _test_group_followers(base_dir: str) -> None: def _test_follows(base_dir: str) -> None: print('test_follows') + debug = True curr_dir = base_dir nickname: str = 'test529' domain: str = 'testdomain.com' @@ -3133,7 +3143,7 @@ def _test_follows(base_dir: str) -> None: makedir(base_dir) os.chdir(base_dir) create_person(base_dir, nickname, domain, port, http_prefix, True, - False, password) + False, password, debug) clear_follows(base_dir, nickname, domain, 'following.txt') follow_person(base_dir, nickname, domain, 'badger', 'wild.com', @@ -3210,6 +3220,7 @@ def _test_follows(base_dir: str) -> None: def _test_create_person_account(base_dir: str): print('test_create_person_account') + debug = True system_language: str = 'en' languages_understood: list = [system_language] curr_dir: str = base_dir @@ -3227,7 +3238,7 @@ def _test_create_person_account(base_dir: str): private_key_pem, public_key_pem, person, wf_endpoint = \ create_person(base_dir, nickname, domain, port, - http_prefix, True, False, password) + http_prefix, True, False, password, debug) assert private_key_pem assert public_key_pem assert person @@ -4276,6 +4287,7 @@ def _test_web_links(): def _test_addemoji(base_dir: str): print('test_addemoji') + debug = True content: str = "Emoji :lemon: :strawberry: :banana:" http_prefix: str = 'http' nickname: str = 'testuser' @@ -4301,7 +4313,7 @@ def _test_addemoji(base_dir: str): os.chdir(base_dir) private_key_pem, public_key_pem, person, wf_endpoint = \ create_person(base_dir, nickname, domain, port, - http_prefix, True, False, 'password') + http_prefix, True, False, 'password', debug) assert private_key_pem assert public_key_pem assert person @@ -5326,6 +5338,21 @@ def _test_valid_nick(): nickname = 'myvalidnick' assert valid_nickname(domain, nickname) + nickname = 'صالح' + assert valid_nickname(domain, nickname) + + nickname = 'वैध' + assert valid_nickname(domain, nickname) + + nickname = '有効' + assert valid_nickname(domain, nickname) + + nickname = 'גילטיק' + assert valid_nickname(domain, nickname) + + nickname = 'дійсний' + assert valid_nickname(domain, nickname) + nickname = 'my#invalid#nick' assert not valid_nickname(domain, nickname) @@ -5338,10 +5365,6 @@ def _test_valid_nick(): nickname = 'my invalid nick?' assert not valid_nickname(domain, nickname) - # causes http signature check failures - nickname = '你好' - assert not valid_nickname(domain, nickname) - nickname = 'abc.def' assert valid_nickname(domain, nickname) @@ -7917,7 +7940,7 @@ def _test_httpsig_base_new(with_digest: bool, base_dir: str, password = 'SuperSecretPassword' private_key_pem, public_key_pem, _, _ = \ create_person(path, nickname, domain, port, http_prefix, - False, False, password) + False, False, password, debug) assert private_key_pem if with_digest: message_body_json = { diff --git a/src/utils.py b/src/utils.py index 62b6ad04b..674e5d9a3 100644 --- a/src/utils.py +++ b/src/utils.py @@ -2466,6 +2466,50 @@ def _is_valid_language(text: str) -> bool: "Gujarati": [2688, 2816], "Oriya": [2816, 2944], "Tamil": [2944, 3072], + "Japanese_hiragana1": [12353, 12436], + "Japanese_hiragana2": [12441, 12446], + "Japanese_hiragana3": [12437, 12438], + "Japanese_hiragana4": [12447, 12447], + "Japanese_KanaA1": [110848, 110878], + "Japanese_KanaA2": [110879, 110882], + "Japanese_KanaB1": [110576, 110579], + "Japanese_KanaB2": [110581, 110587], + "Japanese_KanaB3": [110589, 110590], + "Japanese_KanaSup1": [110592, 110593], + "Japanese_KanaSup2": [110594, 110847], + "Japanese_SmallKana1": [110928, 110930], + "Japanese_SmallKana2": [110948, 110951], + "Japanese_SmallKana3": [110898, 110933], + "Japanese_Katakana1": [12449, 12534], + "Japanese_Katakana2": [12539, 12542], + "Japanese_Katakana3": [12535, 12538], + "Japanese_Katakana4": [12448, 12543], + "Japanese_KatakanaPhon": [12784, 12799], + "CJK1": [19968, 25343], + "CJK2": [25344, 30719], + "CJK3": [30720, 36095], + "CJK4": [36096, 40959], + "CJKExtA": [13312, 19903], + "CJKExtB1": [131072, 136703], + "CJKExtB2": [136704, 143615], + "CJKExtB3": [143616, 148991], + "CJKExtB4": [148992, 155903], + "CJKExtB5": [155904, 161279], + "CJKExtB6": [161280, 168191], + "CJKExtB7": [168192, 173791], + "CJKExtC": [173824, 177983], + "CJKExtD": [177984, 178207], + "CJKExtE": [178208, 183983], + "CJKExtF": [183984, 191471], + "CJKExtG": [196608, 201551], + "CJKExtH": [201552, 205743], + "CJKExtI": [191472, 192095], + "CJKExtJ": [205744, 210047], + "CJKcompat": [63744, 64255], + "CJKcompatLegacy": [13056, 13311], + "CJKcompatLegacyForms": [65072, 65103], + "CJKcompatLegacyIdeo": [63744, 64255], + "CJKcompatLegacyIdeoSupp": [194560, 195103], "Telugu": [3072, 3200], "Kannada": [3200, 3328], "Malayalam": [3328, 3456], @@ -2495,17 +2539,19 @@ def _is_valid_language(text: str) -> bool: "Phonetic Extensions": [7467, 7544], "Combining Half Marks": [65070, 65071] } - for _, lang_range in natural_languages.items(): - ok_lang = True - for char in text: - if char.isdigit() or char == '_' or char == '.': - continue - if ord(char) not in range(lang_range[0], lang_range[1]): - ok_lang = False + for char in text: + # allowed characters + if char.isdigit() or char == '_' or char == '.': + continue + # character should exist in at least one language + char_found = False + for _, lang_range in natural_languages.items(): + if ord(char) in range(lang_range[0], lang_range[1]): + char_found = True break - if ok_lang: - return True - return False + if not char_found: + return False + return True def _get_reserved_words() -> str: