annotate libervia/pages/_bridge/page_meta.py @ 1288:7cec74557aa3

pages: `_bridge` page: this page is an endpoint to do bridge calls from browser scripts.
author Goffi <goffi@goffi.org>
date Fri, 19 Jun 2020 16:47:51 +0200
parents
children b1215347b5c3
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 tempfile
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 import os
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 import os.path
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 import json
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 from twisted.internet import defer
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 from twisted.web import static
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 from sat.core.i18n import _
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 from sat.core.log import getLogger
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 from libervia.server.constants import Const as C
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 from libervia.server.utils import ProgressHandler
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
13
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
14
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 log = getLogger(__name__)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 """access to restricted bridge"""
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
17
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 name = "bridge"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 on_data_post = "continue"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
21
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 def parse_url(self, request):
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 self.getPathArgs(request, ["method_name"], min_args=1)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
24
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
25
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 async def render(self, request):
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 if request.method != b'POST':
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 log.warning(f"Bad method used with _bridge endpoint: {request.method.decode()}")
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 data = self.getRData(request)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 profile = self.getProfile(request)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 if profile is None:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 log.warning("_bridge endpoint accessed without authorisation")
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 return self.pageError(request, C.HTTP_UNAUTHORIZED)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 self.checkCSRF(request)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 method_name = data["method_name"]
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 method_data = json.load(request.content)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 try:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 bridge_method = getattr(self.host.restricted_bridge, method_name)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 except AttributeError:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 log.warning(_(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 "{profile!r} is trying to access a bridge method not implemented in "
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 "RestrictedBridge: {method_name}").format(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 profile=profile, method_name=method_name))
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
46
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 try:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 args, kwargs = method_data['args'], method_data['kwargs']
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 except KeyError:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 log.warning(_(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 "{profile!r} has sent a badly formatted method call: {method_data}"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 ).format(profile=profile, method_data=method_data))
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
54
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 if "profile" in kwargs:
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 log.warning(_(
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 '"profile" key should not be in method kwargs, hack attempt? '
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 "profile={profile}, method_data={method_data}"
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 ).format(profile=profile, method_data=method_data))
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 return self.pageError(request, C.HTTP_BAD_REQUEST)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
61
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 ret = await bridge_method(*args, **kwargs, profile=profile)
7cec74557aa3 pages: `_bridge` page:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 return json.dumps(ret)