Compare commits

...

2 commits

Author SHA1 Message Date
Jörg Thalheim 1789416df4 register-new-matrix-user: add a flag to ignore already existing users
This allows to register users in a more declarative and stateless way.

Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
2024-06-14 11:23:46 +02:00
Jörg Thalheim bc199a27f2 register_new_matrix_user: add password-file flag
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 <joerg@thalheim.io>
2024-06-14 11:20:48 +02:00
3 changed files with 42 additions and 7 deletions

View file

@ -0,0 +1,2 @@
`register_new_matrix_user` now supports a --password-file flag, which
is useful for scripting.

View file

@ -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.

View file

@ -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,
)
@ -174,10 +186,22 @@ def main() -> 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",
"--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",
@ -185,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",
@ -247,6 +272,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 +299,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, exists_ok=args.exists_ok)
def _read_file(file_path: Any, config_path: str) -> str: