def parse_config(config: dict): """Check that the configuration includes the required keys and parse the values expressed as durations.""" if "period" not in config: raise ConfigError( "'period' is required when using email account validity") if "renew_at" not in config: raise ConfigError( "'renew_at' is required when using email account validity") config["period"] = Config.parse_duration(config.get("period") or 0) config["renew_at"] = Config.parse_duration(config.get("renew_at") or 0) return config
def parse_config(config): """Called on startup to parse config supplied. This should parse the config and raise if there is a problem. The returned value is passed into the constructor. In this case we only care about a single param, the directory, so let's just pull that out. """ return Config.ensure_directory(config["directory"])
def __init__(self, config: dict, api: ModuleApi): self._api = api self._store = EmailAccountValidityStore(config, api) EmailAccountValidityBase.__init__(self, config, self._api, self._store) DirectServeHtmlResource.__init__(self) if "period" in config: self._period = Config.parse_duration(config["period"]) else: raise ConfigError( "'period' is required when using account validity") ( self._account_renewed_template, self._account_previously_renewed_template, self._invalid_token_template, ) = api.read_templates([ "account_renewed.html", "account_previously_renewed.html", "invalid_token.html", ])
def main() -> None: parser = argparse.ArgumentParser() parser.add_argument( "-c", "--config-path", action="append", metavar="CONFIG_FILE", help="The config files for Synapse.", required=True, ) parser.add_argument( "-s", "--since", metavar="duration", help= "Specify how far back to review user registrations for, defaults to 7d (i.e. 7 days).", default="7d", ) parser.add_argument( "-e", "--exclude-emails", action="store_true", help="Exclude users that have validated email addresses.", ) parser.add_argument( "-u", "--only-users", action="store_true", help="Only print user IDs that match.", ) parser.add_argument( "-a", "--exclude-app-service", help="Exclude appservice users.", action="store_true", ) config = ReviewConfig() config_args = parser.parse_args(sys.argv[1:]) config_files = find_config_files(search_paths=config_args.config_path) config_dict = read_config_files(config_files) config.parse_config_dict(config_dict, "", "") since_ms = time.time() * 1000 - Config.parse_duration(config_args.since) exclude_users_with_email = config_args.exclude_emails exclude_users_with_appservice = config_args.exclude_app_service include_context = not config_args.only_users for database_config in config.database.databases: if "main" in database_config.databases: break engine = create_engine(database_config.config) with make_conn(database_config, engine, "review_recent_signups") as db_conn: # This generates a type of Cursor, not LoggingTransaction. user_infos = get_recent_users( db_conn.cursor(), since_ms, exclude_users_with_appservice) # type: ignore[arg-type] for user_info in user_infos: if exclude_users_with_email and user_info.emails: continue if include_context: print_public_rooms = "" if user_info.public_rooms: print_public_rooms = "(" + ", ".join( user_info.public_rooms[:3]) if len(user_info.public_rooms) > 3: print_public_rooms += ", ..." print_public_rooms += ")" print("# Created:", datetime.fromtimestamp(user_info.creation_ts)) print("# Email:", ", ".join(user_info.emails) or "None") print("# IPs:", ", ".join(user_info.ips)) print( "# Number joined public rooms:", len(user_info.public_rooms), print_public_rooms, ) print("# Number joined private rooms:", len(user_info.private_rooms)) print("#") print(user_info.user_id) if include_context: print()
def parse_config(config: dict) -> dict: config["period"] = Config.parse_duration(config.get("period") or 0) return config
def setUp(self): # The root object needs a server property with a public_baseurl. root = Mock() root.server.public_baseurl = "http://test" self.config = Config(root)
class BaseConfigTestCase(unittest.TestCase): def setUp(self): # The root object needs a server property with a public_baseurl. root = Mock() root.server.public_baseurl = "http://test" self.config = Config(root) def test_loading_missing_templates(self): # Use a temporary directory that exists on the system, but that isn't likely to # contain template files with tempfile.TemporaryDirectory() as tmp_dir: # Attempt to load an HTML template from our custom template directory template = self.config.read_templates(["sso_error.html"], (tmp_dir, ))[0] # If no errors, we should've gotten the default template instead # Render the template a_random_string = random_string(5) html_content = template.render({"error_description": a_random_string}) # Check that our string exists in the template self.assertIn( a_random_string, html_content, "Template file did not contain our test string", ) def test_loading_custom_templates(self): # Use a temporary directory that exists on the system with tempfile.TemporaryDirectory() as tmp_dir: # Create a temporary bogus template file with tempfile.NamedTemporaryFile(dir=tmp_dir) as tmp_template: # Get temporary file's filename template_filename = os.path.basename(tmp_template.name) # Write a custom HTML template contents = b"{{ test_variable }}" tmp_template.write(contents) tmp_template.flush() # Attempt to load the template from our custom template directory template = (self.config.read_templates([template_filename], (tmp_dir, )))[0] # Render the template a_random_string = random_string(5) html_content = template.render({"test_variable": a_random_string}) # Check that our string exists in the template self.assertIn( a_random_string, html_content, "Template file did not contain our test string", ) def test_multiple_custom_template_directories(self): """Tests that directories are searched in the right order if multiple custom template directories are provided. """ # Create two temporary directories on the filesystem. tempdirs = [ tempfile.TemporaryDirectory(), tempfile.TemporaryDirectory(), ] # Create one template in each directory, whose content is the index of the # directory in the list. template_filename = "my_template.html.j2" for i in range(len(tempdirs)): tempdir = tempdirs[i] template_path = os.path.join(tempdir.name, template_filename) with open(template_path, "w") as fp: fp.write(str(i)) fp.flush() # Retrieve the template. template = (self.config.read_templates( [template_filename], (td.name for td in tempdirs), ))[0] # Test that we got the template we dropped in the first directory in the list. self.assertEqual(template.render(), "0") # Add another template, this one only in the second directory in the list, so we # can test that the second directory is still searched into when no matching file # could be found in the first one. other_template_name = "my_other_template.html.j2" other_template_path = os.path.join(tempdirs[1].name, other_template_name) with open(other_template_path, "w") as fp: fp.write("hello world") fp.flush() # Retrieve the template. template = (self.config.read_templates( [other_template_name], (td.name for td in tempdirs), ))[0] # Test that the file has the expected content. self.assertEqual(template.render(), "hello world") # Cleanup the temporary directories manually since we're not using a context # manager. for td in tempdirs: td.cleanup() def test_loading_template_from_nonexistent_custom_directory(self): with self.assertRaises(ConfigError): self.config.read_templates(["some_filename.html"], ("a_nonexistent_directory", ))