annotate libervia/pages/_bridge/page_meta.py @ 1504:409d10211b20

server, browser: dynamic pages refactoring: dynamic pages has been reworked, to change the initial basic implementation. Pages are now dynamic by default, and a websocket is established by the first connected page of a session. The socket is used to transmit bridge signals, and then the signal is broadcasted to other tabs using broadcast channel. If the connecting tab is closed, an other one is chosen. Some tests are made to retry connecting in case of problem, and sometimes reload the pages (e.g. if profile is connected). Signals (or other data) are cached during reconnection phase, to avoid lost of data. All previous partial rendering mechanism have been removed, chat page is temporarily not working anymore, but will be eventually redone (one of the goal of this work is to have proper chat).
author Goffi <goffi@goffi.org>
date Wed, 01 Mar 2023 18:02:44 +0100
parents 7472d5a88006
children 106bae41f5c8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1288
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 import json
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 from sat.core.i18n import _
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from sat.core.log import getLogger
1296
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
6 from sat_frontends.bridge.bridge_frontend import BridgeException
1288
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 from libervia.server.constants import Const as C
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
8
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
9
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 log = getLogger(__name__)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 """access to restricted bridge"""
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
12
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 name = "bridge"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 on_data_post = "continue"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
1431
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
16 # bridge method allowed when no profile is connected
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
17 NO_SESSION_ALLOWED = ("getContacts", "identitiesBaseGet", "identitiesGet")
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
18
1288
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 def parse_url(self, request):
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 self.getPathArgs(request, ["method_name"], min_args=1)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
22
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 async def render(self, request):
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 if request.method != b'POST':
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 log.warning(f"Bad method used with _bridge endpoint: {request.method.decode()}")
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 data = self.getRData(request)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 profile = self.getProfile(request)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 self.checkCSRF(request)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 method_name = data["method_name"]
1431
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
32 if profile is None:
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
33 if method_name in NO_SESSION_ALLOWED:
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
34 # this method is allowed, we use the service profile
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
35 profile = C.SERVICE_PROFILE
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
36 else:
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
37 log.warning("_bridge endpoint accessed without authorisation")
7472d5a88006 browser(bridge): allow some bridge methods for session profile:
Goffi <goffi@goffi.org>
parents: 1296
diff changeset
38 return self.pageError(request, C.HTTP_UNAUTHORIZED)
1288
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 method_data = json.load(request.content)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 try:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 bridge_method = getattr(self.host.restricted_bridge, method_name)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 except AttributeError:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 log.warning(_(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 "{profile!r} is trying to access a bridge method not implemented in "
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 "RestrictedBridge: {method_name}").format(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 profile=profile, method_name=method_name))
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 try:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 args, kwargs = method_data['args'], method_data['kwargs']
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 except KeyError:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 log.warning(_(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 "{profile!r} has sent a badly formatted method call: {method_data}"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 ).format(profile=profile, method_data=method_data))
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
1296
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
57 if "profile" in kwargs or "profile_key" in kwargs:
1288
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 log.warning(_(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 '"profile" key should not be in method kwargs, hack attempt? '
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 "profile={profile}, method_data={method_data}"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 ).format(profile=profile, method_data=method_data))
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
63
1296
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
64 try:
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
65 ret = await bridge_method(*args, **kwargs, profile=profile)
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
66 except BridgeException as e:
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
67 request.setResponseCode(C.HTTP_PROXY_ERROR)
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
68 ret = {
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
69 "fullname": e.fullname,
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
70 "message": e.message,
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
71 "condition": e.condition,
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
72 "module": e.module,
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
73 "classname": e.classname,
b1215347b5c3 pages (bridge): better handling of errors:
Goffi <goffi@goffi.org>
parents: 1288
diff changeset
74 }
1288
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 return json.dumps(ret)