-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathmatrix.py
152 lines (134 loc) · 5.2 KB
/
matrix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# -*- coding: utf-8 -*-
# synadm
# Copyright (C) 2020-2023 Johannes Tiefenbacher
#
# synadm is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# synadm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" CLI commands executing regular Matrix API calls
"""
import click
from synadm import cli
from click_option_group import optgroup, MutuallyExclusiveOptionGroup
@cli.root.group()
def matrix():
""" Execute Matrix API calls.
"""
@matrix.command(name="login")
@click.argument(
"user_id", type=str)
@click.option(
"--password", "-p", type=str,
help="""The Matrix user's password. If missing, an interactive password
prompt is shown.""")
@click.pass_obj
def login_cmd(helper, user_id, password):
""" Login to Matrix via username/password and receive an access token.
The response also contains a newly generated device ID and further
information about user and homeserver.
Each successful login will show up in the user's devices list marked
with a display name of 'synadm matrix login command'.
"""
if not password:
if helper.no_confirm:
helper.log.error(
"Password prompt not available in non-interactive mode. "
"Use -p.")
raise SystemExit(1)
else:
password = click.prompt("Password", hide_input=True)
mxid = helper.generate_mxid(user_id)
login = helper.matrix_api.user_login(mxid, password)
if helper.no_confirm:
if login is None:
raise SystemExit(1)
helper.output(login)
else:
if login is None:
click.echo("Matrix login failed.")
raise SystemExit(1)
else:
helper.output(login)
@matrix.command(name="raw")
@click.argument(
"endpoint", type=str)
@click.option(
"--method", "-m", type=click.Choice(["get", "post", "put", "delete"]),
help="""The HTTP method used for the request.""",
default="get", show_default=True)
@optgroup.group(
"Data input",
cls=MutuallyExclusiveOptionGroup,
help="")
@optgroup.option(
"--data", "-d", type=str, default='{}', show_default=True,
help="""The JSON string sent in the body of post, put and delete requests -
provided as a string. Make sure to escape it from shell interpretation by
using single quotes. E.g '{"key1": "value1", "key2": 123}'
""")
@optgroup.option(
"--data-file", "-f", type=click.File("rt"),
show_default=True,
help="""Read JSON data from file. To read from stdin use "-" as the
filename argument.
""")
@optgroup.group(
"Matrix token",
cls=MutuallyExclusiveOptionGroup,
help="")
@optgroup.option(
"--token", "-t", type=str, envvar='MTOKEN', show_default=True,
help="""Token used for Matrix authentication instead of the configured
admin user's token. If --token (and --prompt) option is missing, the token
is read from environment variable $MTOKEN instead. To make sure a user's
token does not show up in system logs, don't provide it on the shell
directly but set $MTOKEN with shell command `read MTOKEN`.""")
@optgroup.option(
"--prompt", "-p", is_flag=True, show_default=True,
help="""Prompt for the token used for Matrix authentication. This option
always overrides $MTOKEN.""")
@click.pass_obj
def raw_request_cmd(helper, endpoint, method, data, data_file, token, prompt):
""" Execute a raw request to the Matrix API.
The endpoint argument is the part of the URL _after_ the configured base
URL and Matrix path (see `synadm config`). A simple get request would e.g
look like this: `synadm matrix raw client/versions`
Use either --token or --prompt to provide a user's token and execute Matrix
commands on their behalf. Respect the privacy of others! Be responsible!
The precedence rules for token reading are:
1. Interactive input using --prompt; 2. Set on CLI via --token string;
3. Read from environment variable $MTOKEN; 4. Preconfigured admin token
set in synadm's config file.
"""
if prompt:
token = click.prompt("Matrix token", type=str)
if data_file:
raw_request = helper.matrix_api.raw_request(
endpoint,
method,
data_file.read(),
token=token
)
else:
raw_request = helper.matrix_api.raw_request(endpoint, method, data,
token=token)
if helper.no_confirm:
if raw_request is None:
raise SystemExit(1)
helper.output(raw_request)
else:
if raw_request is None:
click.echo("The Matrix API's response was empty or JSON data "
"could not be loaded.")
raise SystemExit(1)
else:
helper.output(raw_request)