Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewriting the user modify command #126

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
59 changes: 59 additions & 0 deletions synadm/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ def user_modify(self, user_id, password, display_name, threepid,

Threepid should be passed as a tuple in a tuple
"""
# TODO: deprecate
Copy link
Owner

Choose a reason for hiding this comment

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

I agree we should deprecate synadm user modify within this PR, or actually I'd like to achieve this: As soon as everything from user modify has its own command or the user should be warned - best with a literal log.warning.

But I'm not sure anymore wether we'd like to keep some parts of user modify as-is and not invent new commands. Can't recall what was the outcome of that discussion, please help me remember! :-)

If we would keep parts of modify as-is and do not plan to change, then probably it would be better that exactly when these options are used, a log.warning is spit out. Not sure though what's best....

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But I'm not sure anymore wether we'd like to keep some parts of user modify as-is and not invent new commands. Can't recall what was the outcome of that discussion, please help me remember! :-)

If we would keep parts of modify as-is and do not plan to change, then probably it would be better that exactly when these options are used, a log.warning is spit out. Not sure though what's best....

I think deprecating by warning the user is the best option, and we could remove the modify command in the future.

We also do not add any new functions to the modify command to discourage use of it.

data = {}
if password:
data.update({"password": password})
Expand All @@ -627,9 +628,67 @@ def user_modify(self, user_id, password, display_name, threepid,
if user_type:
data.update({"user_type": None if user_type == 'null' else
user_type})
return self._user_modify_api(user_id, data)

def _user_modify_api(self, user_id, data):
"""
Wrapper for the user modify API

Passes data to synapse as is, and returns the response of the query.
"""
return self.query("put", "v2/users/{user_id}", data=data,
user_id=user_id)

def user_set_display_name(self, user_id, display_name):
data = {
"displayname": display_name
}
return self._user_modify_api(user_id, data)

def user_set_profile_picture(self, user_id, mxc_uri):
data = {
"avatar_url": mxc_uri
}
return self._user_modify_api(user_id, data)

def user_set_type(self, user_id, user_type):
"""
Set user type for a user.

Args:
user_id: A Matrix user ID.
user_type (str or None): A user type. Accepted value depends on
Synapse. A python None is the same as removing the user
type.
"""
data = {
"user_type": user_type
}
return self._user_modify_api(user_id, data)

def user_reactivate(self, user_id, password=None):
"""
Args:
user_id (str): A Matrix user ID
password (str or None): A password. Not set if None Required
under certain conditions.
"""
data = {
"deactivated": False
}
if password is not None:
data["password"] = password
return self._user_modify_api(user_id, data)

def user_set_lock(self, user_id, locked):
"""
Lock or unlock an account.
"""
return self._user_modify_api(user_id, {"locked": locked})

def user_set_admin(self, user_id, admin):
return self._user_modify_api(user_id, {"admin": admin})

def user_whois(self, user_id):
""" Return information about the active sessions for a specific user
"""
Expand Down
116 changes: 116 additions & 0 deletions synadm/cli/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,122 @@ def modify(ctx, helper, user_id, password, password_prompt, display_name,
click.echo("Abort.")


# for these placeholders, function similarly to the modify command, but in
# it's own command.
# TODO: find 3pid modify command
Copy link
Owner

Choose a reason for hiding this comment

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

We have a 3pid command already, but it's for displaying only: https://synadm.readthedocs.io/en/latest/synadm.cli.user.html#synadm-user-3pid

That I guess is what you are thinking about? Where should we put / and how should we name the modify command for 3pid modify?

Currently 3pid modify is included with the original user modify command: https://synadm.readthedocs.io/en/latest/synadm.cli.user.html#cmdoption-synadm-user-modify-t



@user.command()
@click.argument("user_id", type=str)
@click.argument("user_type", type=str)
@click.pass_obj
def set_user_type(helper, user_id, user_type):
"""Set a user type.

For the user_type argument, the accepted values are "null" (to
clear/remove the user type), or any other value that synapse accepts
("bot" and "support").
"""
if user_type == "null":
user_type = None
helper.output(helper.api.user_set_type(user_id, user_type))


@user.command()
@click.argument("user_id", type=str)
@click.argument("mxc_uri", type=str)
@click.pass_obj
def set_profile_picture(helper, user_id, mxc_uri):
"""
Set a profile picture for a user by the MXC URI.

Setting the MXC URI to an empty strings removes the profile picture.
"""
modified = helper.user_set_profile_picture(user_id, mxc_uri)
if modified is None:
click.echo("Could not set profile picture.", err=True)
raise SystemExit(1)
helper.output(modified)


@user.command()
@click.argument("user_id", type=str)
@click.argument("display_name", type=str)
@click.pass_obj
def set_display_name(helper, user_id, display_name):
"""
Set the display name of a user.

Display name can be set to an empty string to remove it.
"""
mxid = helper.generate_mxid(user_id)
modified = helper.api.user_set_display_name(mxid, display_name)
if modified is None:
click.echo("Could not set display name.", err=True)
raise SystemExit(1)
if helper.output_format == "human":
new_display_name = modified["displayname"]
if new_display_name is None:
click.echo(f"Removed display name for {mxid}")
else:
click.echo(f"Set display name for {mxid} to {new_display_name}")
else:
helper.output(modified)


@user.command()
@click.argument("user_id", type=str)
# TODO: check compatibility with --batch
@click.password_option(
required=False,
help="""The new password to set to. This is required when reactivating a
user on a Synapse installation with passwords enabled.""")
@click.pass_obj
def reactivate(helper, user_id, password):
result = helper.api.user_reactivate(user_id, password)
helper.output(result)


@user.command()
@click.argument("user_id", type=str)
@click.pass_obj
def lock(helper, user_id):
"""
Lock a user account, preventing them from logging in or using the
account.
"""
result = helper.api.user_set_lock(user_id, True)
helper.output(result)


@user.command()
@click.argument("user_id", type=str)
@click.pass_obj
def unlock(helper, user_id):
"""
Unlock a user account, allowing a locked account to log in and use the
account.
"""
result = helper.api.user_set_lock(user_id, False)
helper.output(result)


@user.command()
@click.argument("user_id", type=str)
@click.pass_obj
def admin_grant(helper, user_id):
result = helper.api.user_set_admin(user_id, True)
helper.output(result)


@user.command()
@click.argument("user_id", type=str)
@click.pass_obj
def admin_revoke(helper, user_id):
result = helper.api.user_set_admin(user_id, False)
helper.output(result)


@user.command()
@click.argument("user_id", type=str)
@click.pass_obj
Expand Down