Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

register_new_matrix_user: read server url from config #13616

Merged
merged 1 commit into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/13616.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a longstanding bug in `register_new_matrix_user` which meant it was always necessary to explicitly give a server URL.
57 changes: 51 additions & 6 deletions synapse/_scripts/register_new_matrix_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
import hmac
import logging
import sys
from typing import Callable, Optional
from typing import Any, Callable, Dict, Optional

import requests
import yaml

_DEFAULT_SERVER_URL = "http://localhost:8008"


def request_registration(
user: str,
Expand Down Expand Up @@ -203,31 +205,74 @@ def main() -> None:

parser.add_argument(
"server_url",
default="https://localhost:8448",
nargs="?",
help="URL to use to talk to the homeserver. Defaults to "
" 'https://localhost:8448'.",
help="URL to use to talk to the homeserver. By default, tries to find a "
"suitable URL from the configuration file. Otherwise, defaults to "
f"'{_DEFAULT_SERVER_URL}'.",
)

args = parser.parse_args()

if "config" in args and args.config:
config = yaml.safe_load(args.config)

if args.shared_secret:
secret = args.shared_secret
else:
# argparse should check that we have either config or shared secret
assert config

secret = config.get("registration_shared_secret", None)
if not secret:
print("No 'registration_shared_secret' defined in config.")
sys.exit(1)

if args.server_url:
server_url = args.server_url
elif config:
server_url = _find_client_listener(config)
if not server_url:
server_url = _DEFAULT_SERVER_URL
print(
"Unable to find a suitable HTTP listener in the configuration file. "
f"Trying {server_url} as a last resort.",
file=sys.stderr,
)
Comment on lines +233 to +240
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use config.server.public_baseurl instead? Or is the assumption that this is only supposed to talk back on private networks?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, often config.server.public_baseurl will point to a reverse-proxy, where we explicitly advise against exposing the /_synapse/admin namespace.

Given we're reading the homeserver.yaml, we have a reasonable intuition that synapse is running on the same host, so a hit to localhost is relatively likely to work.

else:
secret = args.shared_secret
server_url = _DEFAULT_SERVER_URL
print(
f"No server url or configuration file given. Defaulting to {server_url}.",
file=sys.stderr,
)

admin = None
if args.admin or args.no_admin:
admin = args.admin

register_new_user(
args.user, args.password, args.server_url, secret, admin, args.user_type
args.user, args.password, server_url, secret, admin, args.user_type
)


def _find_client_listener(config: Dict[str, Any]) -> Optional[str]:
# try to find a listener in the config. Returns a host:port pair
for listener in config.get("listeners", []):
if listener.get("type") != "http" or listener.get("tls", False):
continue

if not any(
name == "client"
for resource in listener.get("resources", [])
for name in resource.get("names", [])
):
continue

# TODO: consider bind_addresses
return f"http://localhost:{listener['port']}"

# no suitable listeners?
return None


if __name__ == "__main__":
main()