testmatrix 0.2.1__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testmatrix
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: A matrix server sanity tester
5
5
  Author-email: Sebastian Spaeth <Sebastian@SSpaeth.de>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -5,7 +5,7 @@
5
5
  from .matrixserver import MatrixServer
6
6
  from .jwtauth import JWTAuth
7
7
 
8
- __version__ = "0.2.1"
8
+ __version__ = "0.2.3"
9
9
  __all__ = ["MatrixServer", "JWTAuth"]
10
10
 
11
11
  # User Agent and possibly other required headers that we need for all requests
@@ -38,17 +38,14 @@ class JWTAuth:
38
38
  s = f"𐄂 DNS Error resolving host {self.baseurl}"
39
39
  logging.error(s)
40
40
  else:
41
- logging.debug(" JWTauth healtz url: %s", self.loganon(self.baseurl))
42
41
  if r.status_code == 404:
43
- logging.warning("𐄂 jwtauth healthz endpoint does not exist at %s (404)",
42
+ logging.info(" jwtauth healthz endpoint does not exist at %s (404)",
44
43
  self.loganon(url))
45
44
  elif r.status_code != 200:
46
- logging.error("𐄂 jwtauth healthz http error %s",
45
+ logging.warn(" jwtauth healthz http error %s",
47
46
  r.status_code)
48
47
  else:
49
48
  #status code 200, all is well!
50
- if not "Access-Control-Allow-Origin" in r.headers:
51
- logging.debug(" jwt healthz has no CORS header (that is OK")
52
49
  logging.info("✔ JWTauth healthz responds")
53
50
  return True
54
51
  return False
@@ -65,9 +65,12 @@ class MatrixServer:
65
65
 
66
66
  def parse_livekit_json(self, livekit_json: Optional[list]) \
67
67
  -> Optional[bool]:
68
- """Parses client well-known livekit parts and initiates self.livekits
68
+ """Parses livekit json parts and initiates self.livekits
69
+ It works both with the client well-known and the
70
+ /_matrix/client/v1/rtc/transports endpoint.
69
71
 
70
- Returns True (success), False (no Livekit) or None (Error)"""
72
+ Returns True (success), False (no Livekit) or None (Error)
73
+ """
71
74
  self.livekits = []
72
75
  if livekit_json is None:
73
76
  self.livekits = None
@@ -86,8 +89,6 @@ class MatrixServer:
86
89
  continue
87
90
  anon: bool = (self.args is not None) and self.args.anonymize
88
91
  self.livekits.append(JWTAuth(livekit["livekit_service_url"], anon))
89
- logging.debug(" Adding livekit service URL: %s",
90
- livekit["livekit_service_url"])
91
92
  return len(self.livekits) > 0
92
93
 
93
94
  def get_server_baseurl(self) -> Optional[str]:
@@ -122,14 +123,18 @@ class MatrixServer:
122
123
  logging.error("𐄂 Server well-known error %s", str(e))
123
124
  except requests.exceptions.JSONDecodeError as e:
124
125
  if self.diagnostics:
125
- logging.error("𐄂 Server well known is no valid json")
126
+ logging.error("𐄂 Server well-known is no valid json")
126
127
  else:
127
- self.federation_baseurl = "https://" + wellknown_server["m.server"]
128
- if self.diagnostics:
129
- logging.debug(" Federation url: %s",
130
- self.loganon(self.federation_baseurl,
131
- self.servername))
132
- logging.info("✔ Server well-known exists")
128
+ if not "m.server" in wellknown_server:
129
+ logging.warning("𐄂 Server well-known does not contain information about server!")
130
+ else:
131
+ self.federation_baseurl = \
132
+ "https://" + wellknown_server["m.server"]
133
+ if self.diagnostics:
134
+ logging.debug(" Federation url: %s",
135
+ self.loganon(self.federation_baseurl,
136
+ self.servername))
137
+ logging.info("✔ Server well-known exists")
133
138
 
134
139
  # use default address in case of failed well-known
135
140
  if not self.federation_baseurl:
@@ -217,7 +222,9 @@ class MatrixServer:
217
222
  # Retrieve array of livekit instances or None
218
223
  livekit_json = wellknown_client.get("org.matrix.msc4143.rtc_foci",
219
224
  None)
220
- self.parse_livekit_json(livekit_json)
225
+ livekit_detected = self.parse_livekit_json(livekit_json)
226
+ if livekit_detected:
227
+ logging.debug(" Livekit detected via client .well-known (deprecated)")
221
228
  return self.client_baseurl
222
229
 
223
230
  def get_server_version(self) -> str:
@@ -324,6 +331,64 @@ class MatrixServer:
324
331
  logging.info("𐄂 Client API endpoint problem (no versions document)")
325
332
  return res
326
333
 
334
+ def test_oauth_metadata(self) -> bool:
335
+ """Tests if /_matrix/client/v1/auth_metadata
336
+ This is part of the 1.15 spec."""
337
+ res = True # Success result
338
+ try:
339
+ url = f"{self.client_baseurl}/_matrix/client/v1/auth_metadata"
340
+ r = requests.get(url, headers = req_headers)
341
+ r.raise_for_status() # raise e.g. on 404
342
+ if self.diagnostics and not "Access-Control-Allow-Origin" in r.headers:
343
+ logging.error("𐄂 Client version endpoint has no CORS header")
344
+ elif self.diagnostics and r.headers["Access-Control-Allow-Origin"] != "*":
345
+ logging.error("𐄂 Client version endpoint has no proper CORS header: '%s'", r.headers["Access-Control-Allow-Origin"])
346
+ except requests.exceptions.HTTPError as e:
347
+ res = False
348
+ logging.info(" Server oauth metadata endpoint failed (spec 1.15)")
349
+ else:
350
+ logging.debug("✔ Server oauth metadata endpoint exists")
351
+ return res
352
+
353
+ def test_rtc_endpoint_msc4195(self) -> bool:
354
+ """returns true if unstable rtc/transports returns info"""
355
+ res:bool = False # result
356
+ if self.args is None or self.args.token is None:
357
+ logging.info(" RTC Transport endpoint skipped, no auth token")
358
+ return False
359
+ try:
360
+ # TODO: once stable, use /_matrix/client/v1/rtc/transports
361
+ url = f"{self.client_baseurl}/_matrix/client/unstable/org.matrix.msc4143/rtc/transports"
362
+ headers = {"Authorization": f"Bearer {self.args.token}"}
363
+ headers.update(req_headers)
364
+ r = requests.get(url, headers = headers)
365
+ r.raise_for_status() # raise e.g. on 404
366
+ rtc_transports = r.json()
367
+ res = True
368
+ except requests.exceptions.HTTPError as e:
369
+ if e.response.status_code == 404:
370
+ logging.info("𐄂 RTC Transport (unstable) returns (404)")
371
+ elif e.response.status_code == 401:
372
+ logging.warning("𐄂 RTC Transport discovery needs authentication (use a token) (401)")
373
+ else:
374
+ logging.error("𐄂 RTC transport endpoints returns error %s", str(e))
375
+ res = False
376
+ except requests.exceptions.JSONDecodeError as e:
377
+ if self.diagnostics:
378
+ logging.error("𐄂 RTC transport response is no valid json")
379
+ res = False
380
+ if res:
381
+ rtc_transports = rtc_transports.get("rtc_transports", None)
382
+ livekit_detected = self.parse_livekit_json(rtc_transports)
383
+ if livekit_detected:
384
+ logging.debug("✔ Livekit detected via RTC transport endpoint")
385
+ else:
386
+ logging.warn("𐄂 RTC transport endpoints exists but no livekit detected")
387
+ elif self.diagnostics:
388
+ logging.info("𐄂 RTC transport endpoint problem")
389
+ return res
390
+
391
+
327
392
  def test_qrcode_login(self) -> bool:
328
393
  """Returns true if QRcode login is setup (msc4108)"""
329
394
  res:bool = False # qrcode has been setup
@@ -489,7 +554,7 @@ class MatrixServer:
489
554
  r.raise_for_status() # raise e.g. on 403
490
555
  except requests.exceptions.HTTPError as e:
491
556
  if r is not None and r.status_code != 403:
492
- logging.warning("𐄂 Direct open registration might not be forbidden!")
557
+ logging.warning("𐄂 Direct open registration might not be forbidden (returned %d)!", r.status_code)
493
558
  res = False
494
559
  # Next test for guest access
495
560
  try:
@@ -502,8 +567,7 @@ class MatrixServer:
502
567
  except requests.exceptions.HTTPError as e:
503
568
  pass
504
569
  if r is not None and r.status_code != 403:
505
- logging.warning("𐄂 Guest access might not be forbidden (returned %d)!",
506
- r.status_code)
570
+ logging.warning("𐄂 Guest access might not be forbidden (returned %d)!", r.status_code)
507
571
  res = False
508
572
  if res:
509
573
  logging.debug("✔ Direct registration and guest access forbidden per se 👍")
@@ -518,6 +582,8 @@ class MatrixServer:
518
582
  self.test_server_keys()
519
583
  self.get_server_version()
520
584
  self.test_client_endpoint()
585
+ self.test_oauth_metadata()
586
+ self.test_rtc_endpoint_msc4195()
521
587
  if self.diagnostics:
522
588
  self.test_qrcode_login()
523
589
  self.test_room_directory()
@@ -5,7 +5,8 @@
5
5
  from typing import Optional
6
6
  import re
7
7
  # User Agent and possibly other required headers that we need for all requests
8
- req_headers = {"User-Agent": "Mozilla/5.0 (Linux; x64)"}
8
+ req_headers = {"User-Agent": "Mozilla/5.0 (Linux; x64)",
9
+ "Origin": "https://localhost"}
9
10
  DOMAIN = re.compile(r"(?P<prefix>https://.*?)\w*\.\w{2,}(?P<URL>/)",
10
11
  re.IGNORECASE)
11
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testmatrix
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: A matrix server sanity tester
5
5
  Author-email: Sebastian Spaeth <Sebastian@SSpaeth.de>
6
6
  License-Expression: AGPL-3.0-or-later
File without changes
File without changes
File without changes
File without changes
File without changes