From bc199a27f23b0fcf175b116f7cf606c0d22b422a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Tue, 11 Jun 2024 11:40:47 +0200 Subject: [PATCH 1/2] register_new_matrix_user: add password-file flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getpass in python expects stdin to be a tty, hence we cannot just pipe into register_new_matrix_user. --password-file instead works better and it would also allow the use of stdin if /dev/stdin is passed. Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Signed-off-by: Jörg Thalheim --- changelog.d/17294.feature | 2 ++ debian/register_new_matrix_user.ronn | 9 +++++++-- synapse/_scripts/register_new_matrix_user.py | 20 +++++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 changelog.d/17294.feature diff --git a/changelog.d/17294.feature b/changelog.d/17294.feature new file mode 100644 index 0000000000..33aac7b0bc --- /dev/null +++ b/changelog.d/17294.feature @@ -0,0 +1,2 @@ +`register_new_matrix_user` now supports a --password-file flag, which +is useful for scripting. diff --git a/debian/register_new_matrix_user.ronn b/debian/register_new_matrix_user.ronn index 0410b1f4cd..d99e9215a1 100644 --- a/debian/register_new_matrix_user.ronn +++ b/debian/register_new_matrix_user.ronn @@ -31,8 +31,13 @@ A sample YAML file accepted by `register_new_matrix_user` is described below: Local part of the new user. Will prompt if omitted. * `-p`, `--password`: - New password for user. Will prompt if omitted. Supplying the password - on the command line is not recommended. Use the STDIN instead. + New password for user. Will prompt if this option and `--password-file` are omitted. + Supplying the password on the command line is not recommended. + Use `--password-file` if possible. + + * `--password-file`: + File containing the new password for user. If set, overrides `--password`. + This is a more secure alternative to specifying the password on the command line. * `-a`, `--admin`: Register new user as an admin. Will prompt if omitted. diff --git a/synapse/_scripts/register_new_matrix_user.py b/synapse/_scripts/register_new_matrix_user.py index 77a7129ee2..972b35e2dc 100644 --- a/synapse/_scripts/register_new_matrix_user.py +++ b/synapse/_scripts/register_new_matrix_user.py @@ -173,11 +173,18 @@ def main() -> None: default=None, help="Local part of the new user. Will prompt if omitted.", ) - parser.add_argument( + password_group = parser.add_mutually_exclusive_group() + password_group.add_argument( "-p", "--password", default=None, - help="New password for user. Will prompt if omitted.", + help="New password for user. Will prompt for a password if " + "this flag and `--password-file` are both omitted.", + ) + password_group.add_argument( + "--password-file", + default=None, + help="File containing the new password for user. If set, will override `--password`.", ) parser.add_argument( "-t", @@ -247,6 +254,11 @@ def main() -> None: print(_NO_SHARED_SECRET_OPTS_ERROR, file=sys.stderr) sys.exit(1) + if args.password_file: + password = _read_file(args.password_file, "password-file").strip() + else: + password = args.password + if args.server_url: server_url = args.server_url elif config is not None: @@ -269,9 +281,7 @@ def main() -> None: if args.admin or args.no_admin: admin = args.admin - register_new_user( - args.user, args.password, server_url, secret, admin, args.user_type - ) + register_new_user(args.user, password, server_url, secret, admin, args.user_type) def _read_file(file_path: Any, config_path: str) -> str: From 1789416df425d22693b0055a6688d8686e0ee4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 13 Jun 2024 14:38:19 +0200 Subject: [PATCH 2/2] register-new-matrix-user: add a flag to ignore already existing users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to register users in a more declarative and stateless way. Signed-off-by: Jörg Thalheim --- synapse/_scripts/register_new_matrix_user.py | 22 ++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/synapse/_scripts/register_new_matrix_user.py b/synapse/_scripts/register_new_matrix_user.py index 972b35e2dc..233e7267d0 100644 --- a/synapse/_scripts/register_new_matrix_user.py +++ b/synapse/_scripts/register_new_matrix_user.py @@ -52,6 +52,7 @@ def request_registration( user_type: Optional[str] = None, _print: Callable[[str], None] = print, exit: Callable[[int], None] = sys.exit, + exists_ok: bool = False, ) -> None: url = "%s/_synapse/admin/v1/register" % (server_location.rstrip("/"),) @@ -97,6 +98,10 @@ def request_registration( r = requests.post(url, json=data) if r.status_code != 200: + response = r.json() + if exists_ok and response["errcode"] == "M_USER_IN_USE": + _print("User already exists. Skipping.") + return _print("ERROR! Received %d %s" % (r.status_code, r.reason)) if 400 <= r.status_code < 500: try: @@ -115,6 +120,7 @@ def register_new_user( shared_secret: str, admin: Optional[bool], user_type: Optional[str], + exists_ok: bool = False, ) -> None: if not user: try: @@ -154,7 +160,13 @@ def register_new_user( admin = False request_registration( - user, password, server_location, shared_secret, bool(admin), user_type + user, + password, + server_location, + shared_secret, + bool(admin), + user_type, + exists_ok=exists_ok, ) @@ -173,6 +185,11 @@ def main() -> None: default=None, help="Local part of the new user. Will prompt if omitted.", ) + parser.add_argument( + "--exists-ok", + action="store_true", + help="Do not fail if user already exists.", + ) password_group = parser.add_mutually_exclusive_group() password_group.add_argument( "-p", @@ -192,6 +209,7 @@ def main() -> None: default=None, help="User type as specified in synapse.api.constants.UserTypes", ) + admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( "-a", @@ -281,7 +299,7 @@ def main() -> None: if args.admin or args.no_admin: admin = args.admin - register_new_user(args.user, password, server_url, secret, admin, args.user_type) + register_new_user(args.user, password, server_url, secret, admin, args.user_type, exists_ok=args.exists_ok) def _read_file(file_path: Any, config_path: str) -> str: