Example #1
0
    def test_procurementSecurity(self) -> None:
        """
        Once a session is negotiated, it should be the identical object to
        avoid duplicate work - unless we are using forceInsecure to retrieve
        the insecure session from a secure request, in which case the result
        should not be cached.
        """
        sessions = []
        mss = MemorySessionStore()
        router = Klein()

        @router.route("/")
        @inlineCallbacks
        def route(request: IRequest) -> Deferred:
            sproc = SessionProcurer(mss)
            sessions.append((yield sproc.procureSession(request)))
            sessions.append((yield sproc.procureSession(request)))
            sessions.append((yield sproc.procureSession(request,
                                                        forceInsecure=True)))
            returnValue(b"sessioned")

        treq = StubTreq(router.resource())
        self.successResultOf(treq.get("http://unittest.example.com/"))
        self.assertIs(sessions[0], sessions[1])
        self.assertIs(sessions[0], sessions[2])
        self.successResultOf(treq.get("https://unittest.example.com/"))
        self.assertIs(sessions[3], sessions[4])
        self.assertIsNot(sessions[3], sessions[5])
Example #2
0
    def test_resource(self, mock_kr):
        """
        L{Klien.resource} returns a L{KleinResource}.
        """
        app = Klein()
        resource = app.resource()

        mock_kr.assert_called_with(app)
        self.assertEqual(mock_kr.return_value, resource)
Example #3
0
    def test_resource(self, mock_kr):
        """
        L{Klien.resource} returns a L{KleinResource}.
        """
        app = Klein()
        resource = app.resource()

        mock_kr.assert_called_with(app)
        self.assertEqual(mock_kr.return_value, resource)
Example #4
0
def simpleSessionRouter():
    # type: () -> Tuple[sessions, errors, str, str, StubTreq]
    """
    Construct a simple router.
    """
    sessions = []
    exceptions = []
    mss = MemorySessionStore.fromAuthorizers([memoryAuthorizer])
    router = Klein()
    token = "X-Test-Session-Token"
    cookie = "X-Test-Session-Cookie"
    sproc = SessionProcurer(
        mss,
        secureTokenHeader=b"X-Test-Session-Token",
        secureCookie=b"X-Test-Session-Cookie",
    )

    @router.route("/")
    @inlineCallbacks
    def route(request):
        # type: (IRequest) -> Deferred
        try:
            sessions.append((yield sproc.procureSession(request)))
        except NoSuchSession as nss:
            exceptions.append(nss)
        returnValue(b"ok")

    requirer = Requirer()

    @requirer.prerequisite([ISession])
    def procure(request):
        # type: (IRequest) -> Deferred
        return sproc.procureSession(request)

    @requirer.require(router.route("/test"), simple=Authorization(ISimpleTest))
    def testRoute(simple):
        # type: (SimpleTest) -> str
        return "ok: " + str(simple.doTest() + 4)

    @requirer.require(router.route("/denied"), nope=Authorization(IDenyMe))
    def testDenied(nope):
        # type: (IDenyMe) -> str
        return "bad"

    treq = StubTreq(router.resource())
    return sessions, exceptions, token, cookie, treq
Example #5
0
def webserver_for_test(test, url_path, response_content):
    """
    Create a webserver that serves ``response_content`` from ``url_path``.
    """
    app = Klein()

    @app.route(url_path)
    def _respond(request):
        return response_content
    factory = Site(app.resource())
    endpoint = serverFromString(reactor, b"tcp:0")
    listening = endpoint.listen(factory)

    def stop_port(port):
        test.addCleanup(port.stopListening)
        return port
    listening.addCallback(stop_port)
    return listening
Example #6
0
    def test_cookiesTurnedOff(self) -> None:
        """
        If cookies can't be set, then C{procureSession} raises
        L{NoSuchSession}.
        """
        mss = MemorySessionStore()
        router = Klein()

        @router.route("/")
        @inlineCallbacks
        def route(request: IRequest) -> Deferred:
            sproc = SessionProcurer(mss, setCookieOnGET=False)
            with self.assertRaises(NoSuchSession):
                yield sproc.procureSession(request)
            returnValue(b"no session")

        treq = StubTreq(router.resource())
        result = self.successResultOf(treq.get("http://unittest.example.com/"))
        self.assertEqual(self.successResultOf(result.content()), b"no session")
Example #7
0
def webserver_for_test(test, url_path, response_content):
    """
    Create a webserver that serves ``response_content`` from ``url_path``.
    """
    app = Klein()

    @app.route(url_path)
    def _respond(request):
        return response_content

    factory = Site(app.resource())
    endpoint = serverFromString(reactor, b"tcp:0")
    listening = endpoint.listen(factory)

    def stop_port(port):
        test.addCleanup(port.stopListening)
        return port

    listening.addCallback(stop_port)
    return listening
Example #8
0
    def test_procuredTooLate(self) -> None:
        """
        If you start writing stuff to the response before procuring the
        session, when cookies need to be set, you will get a comprehensible
        error.
        """
        mss = MemorySessionStore()
        router = Klein()

        @router.route("/")
        @inlineCallbacks
        def route(request: IRequest) -> Deferred:
            sproc = SessionProcurer(mss)
            request.write(b"oops...")
            with self.assertRaises(TooLateForCookies):
                yield sproc.procureSession(request)
            request.write(b"bye")
            request.finish()

        treq = StubTreq(router.resource())
        result = self.successResultOf(treq.get("http://unittest.example.com/"))
        self.assertEqual(self.successResultOf(result.content()), b"oops...bye")
Example #9
0
def main(reactor):
    component = Component(
        transports=u"ws://localhost:8080/ws",
        realm=u"crossbardemo",
    )
    app = Klein()
    webapp = WebApplication(app, component)

    # have our Web site listen on 8090
    site = Site(app.resource())
    server_ep = TCP4ServerEndpoint(reactor, 8090)
    port = yield server_ep.listen(site)
    print("Web application on {}".format(port))

    # we don't *have* to hand over control of the reactor to
    # component.run -- if we don't want to, we call .start()
    # The Deferred it returns fires when the component is "completed"
    # (or errbacks on any problems).
    comp_d = component.start(reactor)

    # When not using run() we also must start logging ourselves.
    import txaio
    txaio.start_logging(level='info')

    # If the Component raises an exception we want to exit. Note that
    # things like failing to connect will be swallowed by the
    # re-connection mechanisms already so won't reach here.

    def _failed(f):
        print("Component failed: {}".format(f))
        done.errback(f)

    comp_d.addErrback(_failed)

    # wait forever (unless the Component raises an error)
    done = Deferred()
    yield done
Example #10
0
def main(reactor):
    component = Component(
        transports=u"ws://localhost:8080/ws",
        realm=u"crossbardemo",
    )
    app = Klein()
    webapp = WebApplication(app, component)

    # have our Web site listen on 8090
    site = Site(app.resource())
    server_ep = TCP4ServerEndpoint(reactor, 8090)
    port = yield server_ep.listen(site)
    print("Web application on {}".format(port))

    # we don't *have* to hand over control of the reactor to
    # component.run -- if we don't want to, we call .start()
    # The Deferred it returns fires when the component is "completed"
    # (or errbacks on any problems).
    comp_d = component.start(reactor)

    # When not using run() we also must start logging ourselves.
    import txaio
    txaio.start_logging(level='info')

    # If the Component raises an exception we want to exit. Note that
    # things like failing to connect will be swallowed by the
    # re-connection mechanisms already so won't reach here.

    def _failed(f):
        print("Component failed: {}".format(f))
        done.errback(f)
    comp_d.addErrback(_failed)

    # wait forever (unless the Component raises an error)
    done = Deferred()
    yield done
Example #11
0
        if capability_hash is not None:
            capability_url = append_segments(get_url_root(), api, "execute",
                                             capability_version,
                                             capability_hash, '')

            links.append({"href": capability_url, "rel": "capability"})

        return links
    else:
        return url


def transaction_id(request):
    """
    Extract the transaction id from the given request.

    :param IRequest request: The request we are trying to get the
        transaction id for.

    :returns: A string transaction id.
    """
    return request.responseHeaders.getRawHeaders('X-Response-Id')[0]


app = Klein()
app.route = partial(app.route, strict_slashes=False)

root = Resource()
root.putChild('v1.0', app.resource())
root.putChild('', Data('', 'text/plain'))
Example #12
0
class PlatingTests(TestCase):
    """
    Tests for L{Plating}.
    """

    def setUp(self):
        """
        Create an app and a resource wrapping that app for this test.
        """
        self.app = Klein()
        self.kr = self.app.resource()

    def get(self, uri):
        """
        Issue a virtual GET request to the given path that is expected to
        succeed synchronously, and return the generated request object and
        written bytes.
        """
        request = requestMock(uri)
        d = _render(self.kr, request)
        self.successResultOf(d)
        return request, request.getWrittenData()

    def test_template_html(self):
        """
        Rendering a L{Plating.routed} decorated route results in templated
        HTML.
        """
        @page.routed(self.app.route("/"),
                     tags.span(slot("ok")))
        def plateMe(request):
            return {"ok": "test-data-present"}
        request, written = self.get(b"/")
        self.assertIn(b'<span>test-data-present</span>', written)
        self.assertIn(b'<title>default title unchanged</title>', written)

    def test_template_json(self):
        """
        Rendering a L{Plating.routed} decorated route with a query parameter
        asking for JSON will yield JSON instead.
        """
        @page.routed(self.app.route("/"),
                     tags.span(slot("ok")))
        def plateMe(request):
            return {"ok": "an-plating-test"}
        request, written = self.get(b"/?json=true")
        self.assertEqual(
            request.responseHeaders.getRawHeaders(b'content-type')[0],
            b'text/json; charset=utf-8'
        )
        self.assertEquals({"ok": "an-plating-test",
                           "title": "default title unchanged"},
                          json.loads(written.decode('utf-8')))

    def test_template_numbers(self):
        """
        Data returned from a plated method may include numeric types (integers,
        floats, and possibly longs), which although they are not normally
        serializable by twisted.web.template, will be converted by plating into
        their decimal representation.
        """
        @page.routed(self.app.route("/"),
                     tags.div(tags.span(slot("anInteger")),
                              tags.i(slot("anFloat")),
                              tags.b(slot("anLong")),
                     ))
        def plateMe(result):
            return {"anInteger": 7,
                    "anFloat": 3.2,
                    "anLong": 0x10000000000000001}
        request, written = self.get(b"/")
        self.assertIn(b"<span>7</span>", written)
        self.assertIn(b"<i>3.2</i>", written)
        self.assertIn(b"<b>18446744073709551617</b>", written)

    def test_render_list(self):
        """
        The C{:list} renderer suffix will render the slot named by the renderer
        as a list, filling each slot.
        """
        @page.routed(self.app.route("/"),
                     tags.ul(tags.li(slot("item"),
                                     render="subplating:list")))
        def rsrc(request):
            return {"subplating": [1, 2, 3]}
        request, written = self.get(b"/")
        self.assertIn(b'<ul><li>1</li><li>2</li><li>3</li></ul>', written)
        self.assertIn(b'<title>default title unchanged</title>', written)

    def test_widget_html(self):
        """
        When L{Plating.widgeted} is applied as a decorator, it gives the
        decorated function a C{widget} attribute which is a version of the
        function with a modified return type that turns it into a renderable
        HTML sub-element that may fill a slot.
        """
        @page.routed(self.app.route("/"),
                     tags.div(slot("widget")))
        def rsrc(request):
            return {"widget": enwidget.widget(3, 4)}
        request, written = self.get(b"/")
        self.assertIn(b"<span>a: 3</span>", written)
        self.assertIn(b"<span>b: 4</span>", written)

    def test_widget_json(self):
        """
        When L{Plating.widgeted} is applied as a decorator, and the result is
        serialized to JSON, it appears the same as the returned value despite
        the HTML-friendly wrapping described above.
        """
        @page.routed(self.app.route("/"),
                     tags.div(slot("widget")))
        def rsrc(request):
            return {"widget": enwidget.widget(3, 4)}
        request, written = self.get(b"/?json=1")
        self.assertEqual(json.loads(written.decode('utf-8')),
                         {"widget": {"a": 3, "b": 4},
                          "title": "default title unchanged"})

    def test_prime_directive_return(self):
        """
        Nothing within these Articles Of Federation shall authorize the United
        Federation of Planets to alter the return value of a callable by
        applying a decorator to it...
        """
        exact_result = {"ok": "some nonsense value"}
        @page.routed(self.app.route("/"),
                     tags.span(slot("ok")))
        def plateMe(request):
            return exact_result
        self.assertIdentical(plateMe(None), exact_result)

    def test_prime_directive_arguments(self):
        """
        ... or shall require the function to modify its signature under these
        Articles Of Federation.
        """
        @page.routed(self.app.route("/"),
                     tags.span(slot("ok")))
        def plateMe(request, one, two, three):
            return (one, two, three)
        exact_one = {"one": "and"}
        exact_two = {"two": "and"}
        exact_three = {"three": "and"}
        result_one, result_two, result_three = plateMe(
            None, exact_one, exact_two, three=exact_three
        )
        self.assertIdentical(result_one, exact_one)
        self.assertIdentical(result_two, exact_two)
        self.assertIdentical(result_three, exact_three)

    def test_presentation_only_json(self):
        """
        Slots marked as "presentation only" will not be reflected in the
        output.
        """
        plating = Plating(tags=tags.span(slot("title")),
                          presentation_slots={"title"})
        @plating.routed(self.app.route("/"),
                        tags.span(slot("data")))
        def justJson(request):
            return {"title": "uninteresting", "data": "interesting"}
        request, written = self.get(b"/?json=1")
        self.assertEqual(json.loads(written.decode("utf-8")),
                         {"data": "interesting"})

    def test_missing_renderer(self):
        """
        Missing renderers will result in an exception during rendering.
        """
        def test(missing):
            plating = Plating(tags=tags.span(slot(Plating.CONTENT)))
            @plating.routed(self.app.route("/"),
                            tags.span(tags.span(render=missing)))
            def no(request):
                return {}
            self.get(b"/")
            [fe] = self.flushLoggedErrors(FlattenerError)
            self.assertIsInstance(fe.value.args[0], MissingRenderMethod)
        test("garbage")
        test("garbage:missing")

    def test_json_serialize_unknown_type(self):
        """
        The JSON serializer will raise a L{TypeError} when it can't find an
        appropriate type.
        """
        from klein._plating import json_serialize
        class reprish(object):
            def __repr__(self):
                return '<blub>'
        te = self.assertRaises(TypeError, json_serialize, {"an": reprish()})
        self.assertIn("<blub>", str(te))
                api,
                "execute",
                capability_version,
                capability_hash, '')

            links.append({"href": capability_url, "rel": "capability"})

        return links
    else:
        return url


def transaction_id(request):
    """
    Extract the transaction id from the given request.

    :param IRequest request: The request we are trying to get the
        transaction id for.

    :returns: A string transaction id.
    """
    return request.responseHeaders.getRawHeaders('X-Response-Id')[0]


app = Klein()
app.route = partial(app.route, strict_slashes=False)

root = Resource()
root.putChild('v1.0', app.resource())
root.putChild('', Data('', 'text/plain'))
Example #14
0

@app.route("/bot/start", methods=['POST'])
def bot_start(request):
    body = json.loads(request.content.read())
    world[body['u_id']] = world['base'].clone()
    world[body['u_id']].set_agents(
        [base_agents[0].clone(), base_agents[1].clone()])
    # world.new_user(body['u_id'])
    pprint(world)
    return body['u_id']


world = {}

world['base'] = Interactive.main(
    # world = Interactive.main(
    model_file='zoo:blender/blender_90M/model',
    # single_turn=True,
)

base_agents = world['base'].get_agents()

reactor.suggestThreadPoolSize(20)

# this way reactor logs only print calls
web_server = endpoints.serverFromString(reactor, "tcp:8999")
web_server.listen(Site(app.resource()))
reactor.run()

# python ../../second_pjt/pythonProject/main.py
Example #15
0
class WebInterface(YomboLibrary, FrontendMixin, LoadRoutesMixin, RenderMixin,
                   WebServerMixin):
    """
    Web interface framework.
    """
    starting: ClassVar[bool] = True
    already_starting_web_servers: ClassVar[bool] = False
    hook_listeners: ClassVar[dict] = {
    }  # special way to toss hook calls to routes.
    generic_router_list: ClassVar[dict] = {"libraries": {}, "modules": {}}

    @inlineCallbacks
    def _init_(self, **kwargs):
        setup_webinterface_reference(
            self)  # Sets a reference to this library in auth.py
        self.webapp = Klein()
        self.webapp.webinterface = self

        self.api_key = self._Configs.get("frontend.api_key",
                                         random_string(length=75))
        self.frontend_building: bool = False
        self.web_interface_fully_started: bool = False
        self.enabled = self._Configs.get("webinterface.enabled", True)

        self.fqdn = self._Configs.get("dns.fqdn", None, False, instance=True)

        self.enabled = self._Configs.get("core.enabled", True)
        if not self.enabled:
            return

        self.file_cache = ExpiringDict(
            max_len=100, max_age_seconds=120
        )  # used to load a few static files into memory that are commonly used.
        self.translators = {}
        self.idempotence = self._Cache.ttl(name="lib.webinterface.idempotence",
                                           ttl=300)

        self.wi_dir = "/lib/webinterface"

        self.misc_wi_data = {}

        self.wi_port_nonsecure = self._Configs.get(
            "webinterface.nonsecure_port", 8080, instance=True)
        self.wi_port_secure = self._Configs.get("webinterface.secure_port",
                                                8443,
                                                instance=True)

        self.webapp.templates = jinja2.Environment(
            loader=jinja2.FileSystemLoader(f"{self._app_dir}/yombo"),
            extensions=["jinja2.ext.loopcontrols"])
        self.setup_basic_filters()

        self.web_interface_listener = None
        self.web_interface_ssl_listener = None

        self.api_stream_spectators = {
        }  # Tracks all the spectators connected. An alternative to MQTT listening.

        if self._Configs.get("webinterface.enable_default_routes",
                             default=True,
                             create=False):
            yield self.webinterface_load_routes()  # Loads all the routes.

        self.npm_build_results = None

        self.temp_data = ExpiringDict(max_age_seconds=1800)
        self.web_server_started = False
        self.web_server_ssl_started = False

        self.setup_wizard_map_js = None
        self.web_factory = None
        self.user_login_tokens = self._Cache.ttl(name="lib.users.cache",
                                                 ttl=300)

    @property
    def operating_mode(self):
        return self._Loader.operating_mode

    @inlineCallbacks
    def _load_(self, **kwargs):
        if not self.enabled:
            return

        yield self._Notifications.new(
            notice_id="webinterface:starting",
            title="System still starting",
            message="Still starting up. Please wait.",
            request_context=self._FullName,
            priority="high",
            always_show=True,
            always_show_allow_clear=False)

        if self._Configs.get("webinterface.enable_frontend", True, False):
            self.build_dist()  # Makes the Vue application frontend.

        self.module_config_links = {}

        # self.web_factory = YomboSite(self.webapp.resource(), None, logPath="/dev/null")
        self.web_factory = YomboSite(self,
                                     self.webapp.resource(),
                                     None,
                                     logPath=None)
        self.web_factory.noisy = False  # turn off Starting/stopping message
        self.displayTracebacks = False

        self._display_how_to_access_at = 0  # When the display notice for how to access the web was shown.

        self.misc_wi_data["gateway_label"] = self._Configs.get("core.label",
                                                               "Yombo Gateway",
                                                               False,
                                                               instance=True)
        self.misc_wi_data["operating_mode"] = self._Loader.operating_mode
        self.misc_wi_data["notifications"] = self._Notifications
        self.misc_wi_data[
            "notification_priority_map_css"] = NOTIFICATION_PRIORITY_MAP_CSS
        self.misc_wi_data["breadcrumb"] = []

        self.webapp.templates.globals["yombo"] = self
        self.webapp.templates.globals["_local_gateway"] = self._Gateways.local
        self.webapp.templates.globals["py_time"] = time
        self.webapp.templates.globals["misc_wi_data"] = self.misc_wi_data
        self.webapp.templates.globals["webinterface"] = self
        self.webapp.templates.globals["bg_image_id"] = lambda: int(time(
        ) / 300) % 6  # Used to select a background.
        # self.webapp.templates.globals["get_alerts"] = self.get_alerts

        self._refresh_jinja2_globals_()
        self.starting = False
        yield self.start_web_servers()
        self.clean_idempotence_ids_loop = LoopingCall(
            self.clean_idempotence_ids)
        self.clean_idempotence_ids_loop.start(1806, False)

    def _refresh_jinja2_globals_(self, **kwargs):
        """
        Update various globals for the Jinja2 template.

        :return:
        """
        if self._Loader.operating_mode != "run":
            return
        self.webapp.templates.globals[
            "_location_id"] = self._Locations.location_id
        self.webapp.templates.globals["_area_id"] = self._Locations.area_id
        self.webapp.templates.globals["_location"] = self._Locations.location
        self.webapp.templates.globals["_area"] = self._Locations.area

    @inlineCallbacks
    def _start_(self, **kwargs):
        self.webapp.templates.globals["_"] = _  # i18n
        if self._gateway_id == "local":
            results = yield self._Requests.request("get",
                                                   "https://yg2.in/9id39")
            self.setup_wizard_map_js = results.content.strip()

    def _started_(self, **kwargs):
        """ Perform a couple of small tasks after everything has started. """
        self.web_interface_fully_started = True
        self.display_how_to_access()
        self._Notifications.delete("webinterface:starting")

        self.send_hook_listeners_ping_loop = LoopingCall(
            self.send_hook_listeners_ping_loop)
        self.send_hook_listeners_ping_loop.start(55, True)

    @inlineCallbacks
    def _unload_(self, **kwargs):
        if hasattr(self, "web_factory"):
            if self.web_factory is not None:
                yield self.web_factory.save_log_queue()

    def clean_idempotence_ids(self):
        """
        Removes older idempotence keys.

        :return:
        """
        delete_time = int(time()) - 1800
        for key in self.idempotence.keys():
            if self.idempotence[key] < delete_time:
                del self.idempotence[key]

    def send_hook_listeners_ping_loop(self):
        web_broadcast(self, "ping", int(time()))

    def register_hook(self, name, thecallback):
        if name not in self.hook_listeners:
            self.hook_listeners[name] = []
        self.hook_listeners[name].append(thecallback)

    @inlineCallbacks
    def _yombo_universal_hook_(self, hook_name=None, **kwargs):
        """
        Implements the universal hook.

        :param kwargs:
        :return:
        """
        if hook_name in self.hook_listeners:
            for a_callback in self.hook_listeners[hook_name]:
                d = Deferred()
                d.addCallback(lambda ignored: maybeDeferred(
                    a_callback, self, hook_name=hook_name, **kwargs))
                d.addErrback(self.yombo_universal_hook_failure, hook_name,
                             a_callback)
                d.callback(1)
                yield d

    def yombo_universal_hook_failure(self, failure, hook_name, acallback):
        logger.warn(
            "---==(failure WI:universal hook for hook ({hook_name})==----",
            hook_name=hook_name)
        logger.warn("--------------------------------------------------------")
        logger.warn("{acallback}", acallback=acallback)
        logger.warn("{failure}", failure=failure)
        logger.warn("--------------------------------------------------------")
        raise RuntimeError(f"failure during module invoke for hook: {failure}")

    def check_have_required_nodes(self):
        try:
            node = yield self._Nodes.get("main_page", "webinterface_page")
        except KeyError as e:
            pass
            # add base node...

    def _configs_set_(self, arguments, **kwargs):
        """
        Need to monitor if the web interface port has changed. This will restart the webinterface
        server if needed.

        :param arguments: section, option(key), value
        :return:
        """
        section = arguments["section"]
        option = arguments["option"]
        value = arguments["value"]

        if self.starting is True:
            return

        if section == "webinterface":
            if option == "nonsecure_port":
                self.change_ports(port_nonsecure=value)
            elif option == "secure_port":
                self.change_ports(port_secure=value)

    @property
    def internal_url(self):
        """
        Returns the starting portion of the URL to this host.
        https://i.exmaple.yombo.net

        :return:
        """
        if self.fqdn.value is None:
            internal_hostname = self._Configs.get(
                "networking.localipaddress.v4")
            return f"http://{internal_hostname}:{self.wi_port_nonsecure.value}"
        else:
            return f"https://i.{self.fqdn.value}:{self.wi_port_secure.value}"

    @property
    def external_url(self):
        """
        Returns the starting portion of the URL to this host.
        https://e.exmaple.yombo.net

        :return:
        """
        if self.fqdn.value is None:
            external_hostname = self._Configs.get(
                "networking.externalipaddress.v4")
            return f"https://{external_hostname}:{self.wi_port_secure.value}"
        else:
            return f"https://e.{self.fqdn.value}:{self.wi_port_secure.value}"

    def add_alert(self,
                  session,
                  message,
                  level="info",
                  display_once=True,
                  deletable=True,
                  id=None):
        """
        Add an alert to the stack.
        :param level: info, warning, error
        :param message:
        :return:
        """
        id = session.add_alert(message, level, display_once, deletable, id)
        return id

    def get_alerts(self, session, autodelete=None):
        """
        Retrieve a list of alerts for display.
        """
        if session is None:
            return {}
        return session.get_alerts(autodelete)

    def redirect(self, request, redirect_path):
        return request.redirect(redirect_path)

    def _get_parms(self, request):
        return parse_qs(urlparse(request.uri).query)

    def request_get_default(self, request, name, default, offset=None):
        if offset == None:
            offset = 0
        try:
            return request.args.get(name)[offset]
        except:
            return default

    def home_breadcrumb(self, request):
        self.add_breadcrumb(request, "/", "Home")

    def add_breadcrumb(self,
                       request,
                       url=None,
                       text=None,
                       show=None,
                       style=None,
                       data=None):
        if hasattr(request, "breadcrumb") is False:
            request.breadcrumb = []
            self.misc_wi_data["breadcrumb"] = request.breadcrumb

        if show is None:
            show = True

        if style is None:
            style = "link"
        elif style == "select_groups":
            items = {}
            for option_label, option_data in data.items():
                items[option_label] = []
                for select_text, select_url in option_data.items():
                    selected = ""
                    option_style = "None"
                    if select_url.startswith("$"):
                        selected = "selected"
                        select_url = select_url[1:]
                    elif select_url.startswith("#"):
                        option_style = "divider"

                    items[option_label].append({
                        "option_style": option_style,
                        "text": select_text,
                        "url": select_url,
                        "selected": selected,
                    })
            data = items
        elif style == "select":
            items = []
            for select_text, select_url in data.items():
                selected = ""
                option_style = "None"
                if select_url.startswith("$"):
                    selected = "selected"
                    select_url = select_url[1:]
                elif select_url.startswith("#"):
                    option_style = "divider"

                items.append({
                    "option_style": option_style,
                    "text": select_text,
                    "url": select_url,
                    "selected": selected,
                })
            data = items

        hash = sha256(
            str(
                str(url) + str(text) + str(show) + str(style) +
                json.dumps(data)).encode()).hexdigest()
        breadcrumb = {
            "hash": hash,
            "url": url,
            "text": text,
            "show": show,
            "style": style,
            "data": data,
        }
        request.breadcrumb.append(breadcrumb)

    def setup_basic_filters(self):
        self.webapp.templates.filters["yes_no"] = yombo.utils.is_yes_no
        self.webapp.templates.filters["true_false"] = yombo.utils.is_true_false
        self.webapp.templates.filters["excerpt"] = yombo.utils.excerpt
        self.webapp.templates.filters["make_link"] = yombo.utils.make_link
        self.webapp.templates.filters[
            "status_to_string"] = converters.status_to_string
        self.webapp.templates.filters[
            "public_to_string"] = converters.public_to_string
        self.webapp.templates.filters[
            "epoch_to_string"] = converters.epoch_to_string
        self.webapp.templates.filters[
            "epoch_get_age"] = dt_util.get_age  # yesterday, 5 minutes ago, etc.
        self.webapp.templates.filters[
            "epoch_get_age_exact"] = dt_util.get_age_exact  # yesterday, 5 minutes ago, etc.
        self.webapp.templates.filters[
            "format_markdown"] = yombo.utils.format_markdown
        self.webapp.templates.filters[
            "hide_none"] = yombo.utils.display_hide_none
        self.webapp.templates.filters[
            "display_temperature"] = self._Localize.display_temperature
        self.webapp.templates.filters["yombo"] = self

    def restart(self, request, message=None, redirect=None):
        """
        Restart the gateway. Called by various routes that need to restart the gateway. This will return
        the restarting html with message and redirect to injected into it.

        :param request:
        :param message:
        :param redirect:
        :return:
        """
        if message is None:
            message = ""
        if redirect is None:
            redirect = "/"

        def do_restart():
            try:
                raise YomboRestart("Web Interface setup wizard complete.")
            except:
                pass

        reactor.callLater(0.3, do_restart)
        return self.render_template(
            request,
            self.wi_dir + "/pages/misc/restarting.html",
            message=message,
            redirect=redirect,
        )

    def shutdown(self, request, message=None, redirect=None):
        """
        Shutdown the gateway. Called by various routes that need to shutdownthe gateway. This will return
        the shutting down html with the optional message injected into it.

        :param request:
        :param message:
        :param redirect:
        :return:
        """
        def do_shutdown():
            raise YomboQuit("Requested gateway shutdown from webinterface.")

        reactor.callLater(0.3, do_shutdown)
        return self.render_template(
            request, self.wi_dir + "/pages/misc/shutting_down.html")
Example #16
0
                "Processed cache on server start in %s seconds.             " %
                round(time.time() - start_time))

            if configuration["ENABLE_HTTPS"] == "Y":
                endpoint_description = (
                    "ssl:" + str(configuration["DASHBOARD_WEB_PORT"]) +
                    ":interface=" + configuration["NETWORK_INTERFACE"] +
                    ":privateKey=" + configuration["PRIVATE_KEY"])
            else:
                endpoint_description = (
                    "tcp:port=" + str(configuration["DASHBOARD_WEB_PORT"]) +
                    ":interface=" + configuration["NETWORK_INTERFACE"])

            endpoint = endpoints.serverFromString(reactor,
                                                  endpoint_description)
            endpoint.listen(Site(nserv.resource()))

            syslog_cache_processor_task = task.LoopingCall(
                syslog_cache_processor, redis_syslog_cache, redis_main_db)

            main_server_processor_loop = syslog_cache_processor_task.start(
                configuration["SYSLOG_CACHE_PROCESS_INTERVAL"])

            main_server_processor_loop.addErrback(main_server_loop_failed)

            # reactor.suggestThreadPoolSize(30)
            reactor.run()

    except (IOError, SystemExit):

        raise
Example #17
0
class Master:
    def __init__(self):
        self.config_path: str = ''
        self.main_path: str = ''
        self.root: Union[PBRoot, None] = None
        self.web_root: Union[Klein, None] = None

    def config(self, config_path: str, main_path: str) -> None:
        """
        :param config_path:
        :param main_path:
        :return:
        """
        self.config_path = config_path
        self.main_path = main_path

    def master_app(self):
        with open(self.config_path, 'r') as f:
            GO.json_config = config = json.loads(f.read())

        # config
        master_cnf = config.get('master')
        root_port = master_cnf.get('root_port')
        web_port = master_cnf.get('web_port')
        master_log = master_cnf.get('log')

        self.root = PBRoot()
        root_service = services.Service("root_service")
        self.root.add_service_channel(root_service)
        GO.root = self.root
        # import learn_twist.master.rootapp

        self.web_root = Klein()
        GO.web_root = self.web_root
        # import learn_twist.master.webapp

        if master_log:
            log.addObserver(LogObj(master_log))
        log.startLogging(sys.stdout)

        reactor.listenTCP(web_port, DelaySite(self.web_root.resource()))
        reactor.listenTCP(root_port, BilateralFactory(self.root))

    def start(self):
        sys_args = sys.argv
        if len(sys_args) > 2 and sys_args[1] == "single":
            server_name = sys_args[2]
            if server_name == "master":
                mode = MASTER_SERVER_MODE
            else:
                mode = SINGLE_SERVER_MODE
        else:
            mode = MULTI_SERVER_MODE
            server_name = ""

        if mode == MULTI_SERVER_MODE:
            self.master_app()
            with open(self.config_path, 'r') as f:
                config = json.loads(f.read())
            servers_conf = config.get('servers')
            log.msg(servers_conf)
            for server_name in servers_conf.keys():
                cmd = 'python %s %s %s' % (self.main_path, server_name,
                                           self.config_path)
                log.msg('cmd:', cmd)
                subprocess.Popen(cmd, shell=True)
            reactor.run()
        elif mode == SINGLE_SERVER_MODE:
            sername = server_name
            cmds = 'python %s %s %s' % (self.main_path, sername,
                                        self.config_path)
            subprocess.Popen(cmds, shell=True)
        else:
            self.master_app()
            reactor.run()
Example #18
0
##  See the License for the specific language governing permissions and
##  limitations under the License.
##
###############################################################################

from twisted.internet.defer import inlineCallbacks, returnValue
from klein import Klein
from autobahn.twisted.wamp import Application

app = Klein()
wampapp = Application()


@app.route('/square/submit', methods=['POST'])
@inlineCallbacks
def square_submit(request):
    x = int(request.args.get('x', [0])[0])
    res = yield wampapp.session.call('com.example.square', x)
    returnValue("{} squared is {}".format(x, res))


if __name__ == "__main__":
    import sys
    from twisted.python import log
    from twisted.web.server import Site
    from twisted.internet import reactor
    log.startLogging(sys.stdout)

    reactor.listenTCP(8080, Site(app.resource()))
    wampapp.run("ws://localhost:9000", "realm1", standalone=False)
Example #19
0
    print("unlock: %s" % (imei, ))
    dev = devices.get(imei)
    if dev is None:
        raise NotFound()
    request.setHeader('Content-Type', 'application/json')
    dev.sendUnlock()
    # FIXME: async, get confirmation from lock
    data = {"success": True, "status": "pending"}
    print(jsons.dumps(data))
    return jsons.dumps(data)


@http.route('/<imei>')
def lock(request, imei):
    dev = devices.get(imei)
    if dev is None:
        raise NotFound()
    return 'Hi %s!' % (imei, )


bl10endpoint = endpoints.TCP4ServerEndpoint(reactor,
                                            LOCK_PORT,
                                            interface=LOCK_HOST)
bl10endpoint.listen(BL10Factory())
print("Listening for Lock Traffic on %s:%d" % (LOCK_HOST, LOCK_PORT))

httpendpoint = endpoints.TCP4ServerEndpoint(reactor, PORT, interface=HOST)
httpendpoint.listen(Site(http.resource()))
print("Listening for HTTP on %s:%d" % (HOST, PORT))

reactor.run()
Example #20
0
def main(reactor):
    # Because we're using a self-signed certificate, we need to tell Twisted
    # that it is OK to trust it.
    cert_fname = (".crossbar/server_cert.pem")
    cert = crypto.load_certificate(crypto.FILETYPE_PEM,
                                   six.u(open(cert_fname, 'r').read()))
    opt = ssl.CertificateOptions(\
      trustRoot=OpenSSLCertificateAuthorities([cert]))

    # Set up our sisock component.
    component = Component(
        transports=[{
            u"type": u"websocket",
            u"url": sisock.base.WAMP_URI,
            u"endpoint": {
                u"type": u"tcp",
                u"host": sisock.base.SISOCK_HOST,
                u"port": sisock.base.SISOCK_PORT,
                u"tls": opt
            }
        }],
        authentication={
            u"wampcra": {
                u"authid": u"simonsobs",
                u"secret": u"yW4V2T^bPD&rGFwy"
            }
        },
        realm=sisock.base.REALM,
    )

    # Create our klein webserver, and then our datasource (which also connects
    # our component to the WAMP server).
    app = Klein()
    GrafanaSisockDatasrc(app, component)

    # Have our webserver listen for Grafana requests.
    # TODO: use SSL and authentication.
    site = Site(app.resource())
    #server_ep = SSL4ServerEndpoint(reactor, klein_port, opt)
    server_ep = TCP4ServerEndpoint(reactor, klein_port)
    port = yield server_ep.listen(site)
    print("Web application on {}".format(port))

    # We don't *have* to hand over control of the reactor to
    # component.run -- if we don't want to, we call .start()
    # The Deferred it returns fires when the component is "completed"
    # (or errbacks on any problems).
    comp_d = component.start(reactor)

    # When not using run() we also must start logging ourselves.
    txaio.start_logging(level=environ.get("LOGLEVEL", "info"))

    # If the Component raises an exception we want to exit. Note that
    # things like failing to connect will be swallowed by the
    # re-connection mechanisms already so won't reach here.

    def _failed(f):
        print("Component failed: {}".format(f))
        done.errback(f)

    comp_d.addErrback(_failed)

    # Wait forever (unless the Component raises an error).
    done = Deferred()
    yield done
# coding=utf-8
import os

from klein import Klein
from twisted.internet import reactor
from twisted.web.resource import Resource, ForbiddenResource
from twisted.web.server import Site
from twisted.web.static import File

from server.app import App

class FileNoDir(File):
    def directoryListing(self):
        return ForbiddenResource()

if __name__ == '__main__':
    client_side_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'client_side'))
    server = Klein()
    app = App(server, client_side_dir)
    root = server.resource()
    site = Site(root)
    """
    root.putChild("static", FileNoDir(os.path.join(client_side_dir, 'static')))
    root.putChild("app", FileNoDir(os.path.join(client_side_dir, 'app')))
    root.putChild("", File(os.path.join(client_side_dir, 'templates', 'index.html')))
    root.putChild("templates", File(os.path.join(client_side_dir, 'templates')))
    """
    reactor.listenTCP(8888, site)
    reactor.run()
    webapp.visits += 1
    wampapp.session.publish(u'com.example.onvisit', visits=webapp.visits)
    page = webapp.templates.get_template('index.html')
    return page.render(visits=webapp.visits)


@webapp.route('/square/<int:x>')
@inlineCallbacks
def square(request, x):
    result = yield wampapp.session.call(u'com.example.square', x)
    page = webapp.templates.get_template('result.html')
    content = page.render(x=x, result=result)
    returnValue(content)


@webapp.route('/square/submit', methods=['POST'])
def square_submit(request):
    x = int(request.args.get('x', [0])[0])
    return square(request, x)


if __name__ == "__main__":
    import sys
    from twisted.python import log
    from twisted.web.server import Site
    from twisted.internet import reactor
    log.startLogging(sys.stdout)

    reactor.listenTCP(8080, Site(webapp.resource()))
    wampapp.run(u"ws://127.0.0.1:9000", u"realm1", standalone=True)
Example #23
0
webapp = Klein()


@webapp.route('/', methods=['POST'])
def index(request: Request):
    content = json.loads(request.content.read())
    try:
        new_state = GameState(**content)

    except Exception as e:
        print(content)
        print(e)
        return "wew"

    wamp_component.state = new_state
    print(wamp_component.state.map.game_state)

    return "ok"


if __name__ == "__main__":
    from twisted.web.server import Site
    from twisted.internet import reactor, task

    import sys
    print(sys.path)

    reactor.listenTCP(8016, Site(webapp.resource()))
    run([wamp_component])
Example #24
0
                        action="store",
                        help="Config file (default. %s)" % PROTOCOL_CONFIG,
                        default=PROTOCOL_CONFIG)
    args = parser.parse_args()
    settings.setup(args.config)

    logger.info("Starting api.py")
    logger.debug("Config: %s", args.config)
    logger.debug("Network: %s", settings.net_name)

    # Enable Twisted logging (see also http://twistedmatrix.com/documents/12.0.0/core/howto/logging.html)
    log.startLogging(sys.stdout)

    # # Get the blockchain up and running
    # blockchain = LevelDBBlockchain(settings.LEVELDB_PATH)
    # Blockchain.RegisterBlockchain(blockchain)

    # reactor.suggestThreadPoolSize(15)
    # NodeLeader.Instance().Start()

    # dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks)
    # dbloop.start(.1)
    # Blockchain.Default().PersistBlocks()

    # Hook up Klein API to Twisted reactor
    endpoint_description = "tcp:port=%s:interface=localhost" % API_PORT
    endpoint = endpoints.serverFromString(reactor, endpoint_description)
    endpoint.listen(Site(app.resource()))

    reactor.run()
Example #25
0
                else: self.message('NONE')
            elif command == 'ZAP':
                pos0,_ = self.currentState()
                if self.ammo == 0: self. message('NO AMMO')
                else:
                    self.ammo -= 1
                    for client in self.factory.arena.bots.store:
                        if client == self or client is None: continue
                        pos1,_ = client.currentState()
                        dist = numpy.sqrt(numpy.dot(pos1-pos0,pos1-pos0))
                        if dist <= 0.05: client.battery -= 1.0
                        elif dist <= 0.1: client.battery -= (0.1 - dist) * 20
                        client.checkBattery()
                    self.message('OK')
            elif command == 'BYE':
                self.leave()
            else: raise Exception('Not understood')
        except Exception as e:
            g_trace.debug(self.ip + ':' + self.port + ' | ' + self.name + ' | error: ' + str(e))
            self.message('NOT UNDERSTOOD')

    def message(self, message):
        self.transport.write(message.encode('ascii') + b'\r\n')

factory = protocol.ServerFactory()
factory.protocol = Bot
factory.arena = Arena(len(colours))
endpoints.serverFromString(reactor, "tcp:8000").listen(Site(app.resource()))
reactor.listenTCP(8888,factory)
reactor.run()
Example #26
0
class PlatingTests(TestCase):
    """
    Tests for L{Plating}.
    """
    def setUp(self):
        """
        Create an app and a resource wrapping that app for this test.
        """
        self.app = Klein()
        self.kr = self.app.resource()

    def get(self, uri):
        """
        Issue a virtual GET request to the given path that is expected to
        succeed synchronously, and return the generated request object and
        written bytes.
        """
        request = requestMock(uri)
        d = _render(self.kr, request)
        self.successResultOf(d)
        return request, request.getWrittenData()

    def test_template_html(self):
        """
        Rendering a L{Plating.routed} decorated route results in templated
        HTML.
        """
        @page.routed(self.app.route("/"), tags.span(slot("ok")))
        def plateMe(request):
            return {"ok": "test-data-present"}

        request, written = self.get(b"/")
        self.assertIn(b'<span>test-data-present</span>', written)
        self.assertIn(b'<title>default title unchanged</title>', written)

    def test_template_json(self):
        """
        Rendering a L{Plating.routed} decorated route with a query parameter
        asking for JSON will yield JSON instead.
        """
        @page.routed(self.app.route("/"), tags.span(slot("ok")))
        def plateMe(request):
            return {"ok": "an-plating-test"}

        request, written = self.get(b"/?json=true")
        self.assertEqual(
            request.responseHeaders.getRawHeaders(b'content-type')[0],
            b'text/json; charset=utf-8')
        self.assertEquals(
            {
                "ok": "an-plating-test",
                "title": "default title unchanged"
            }, json.loads(written.decode('utf-8')))

    def test_template_numbers(self):
        """
        Data returned from a plated method may include numeric types (integers,
        floats, and possibly longs), which although they are not normally
        serializable by twisted.web.template, will be converted by plating into
        their decimal representation.
        """
        @page.routed(self.app.route("/"),
                     tags.div(
                         tags.span(slot("anInteger")),
                         tags.i(slot("anFloat")),
                         tags.b(slot("anLong")),
                     ))
        def plateMe(result):
            return {
                "anInteger": 7,
                "anFloat": 3.2,
                "anLong": 0x10000000000000001
            }

        request, written = self.get(b"/")
        self.assertIn(b"<span>7</span>", written)
        self.assertIn(b"<i>3.2</i>", written)
        self.assertIn(b"<b>18446744073709551617</b>", written)

    def test_render_list(self):
        """
        The C{:list} renderer suffix will render the slot named by the renderer
        as a list, filling each slot.
        """
        @page.routed(self.app.route("/"),
                     tags.ul(tags.li(slot("item"), render="subplating:list")))
        def rsrc(request):
            return {"subplating": [1, 2, 3]}

        request, written = self.get(b"/")
        self.assertIn(b'<ul><li>1</li><li>2</li><li>3</li></ul>', written)
        self.assertIn(b'<title>default title unchanged</title>', written)

    def test_widget_html(self):
        """
        When L{Plating.widgeted} is applied as a decorator, it gives the
        decorated function a C{widget} attribute which is a version of the
        function with a modified return type that turns it into a renderable
        HTML sub-element that may fill a slot.
        """
        @page.routed(self.app.route("/"), tags.div(slot("widget")))
        def rsrc(request):
            return {"widget": enwidget.widget(3, 4)}

        request, written = self.get(b"/")
        self.assertIn(b"<span>a: 3</span>", written)
        self.assertIn(b"<span>b: 4</span>", written)

    def test_widget_json(self):
        """
        When L{Plating.widgeted} is applied as a decorator, and the result is
        serialized to JSON, it appears the same as the returned value despite
        the HTML-friendly wrapping described above.
        """
        @page.routed(self.app.route("/"), tags.div(slot("widget")))
        def rsrc(request):
            return {"widget": enwidget.widget(3, 4)}

        request, written = self.get(b"/?json=1")
        self.assertEqual(json.loads(written.decode('utf-8')), {
            "widget": {
                "a": 3,
                "b": 4
            },
            "title": "default title unchanged"
        })

    def test_prime_directive_return(self):
        """
        Nothing within these Articles Of Federation shall authorize the United
        Federation of Planets to alter the return value of a callable by
        applying a decorator to it...
        """
        exact_result = {"ok": "some nonsense value"}

        @page.routed(self.app.route("/"), tags.span(slot("ok")))
        def plateMe(request):
            return exact_result

        self.assertIdentical(plateMe(None), exact_result)

    def test_prime_directive_arguments(self):
        """
        ... or shall require the function to modify its signature under these
        Articles Of Federation.
        """
        @page.routed(self.app.route("/"), tags.span(slot("ok")))
        def plateMe(request, one, two, three):
            return (one, two, three)

        exact_one = {"one": "and"}
        exact_two = {"two": "and"}
        exact_three = {"three": "and"}
        result_one, result_two, result_three = plateMe(None,
                                                       exact_one,
                                                       exact_two,
                                                       three=exact_three)
        self.assertIdentical(result_one, exact_one)
        self.assertIdentical(result_two, exact_two)
        self.assertIdentical(result_three, exact_three)

    def test_presentation_only_json(self):
        """
        Slots marked as "presentation only" will not be reflected in the
        output.
        """
        plating = Plating(tags=tags.span(slot("title")),
                          presentation_slots={"title"})

        @plating.routed(self.app.route("/"), tags.span(slot("data")))
        def justJson(request):
            return {"title": "uninteresting", "data": "interesting"}

        request, written = self.get(b"/?json=1")
        self.assertEqual(json.loads(written.decode("utf-8")),
                         {"data": "interesting"})

    def test_missing_renderer(self):
        """
        Missing renderers will result in an exception during rendering.
        """
        def test(missing):
            plating = Plating(tags=tags.span(slot(Plating.CONTENT)))

            @plating.routed(self.app.route("/"),
                            tags.span(tags.span(render=missing)))
            def no(request):
                return {}

            self.get(b"/")
            [fe] = self.flushLoggedErrors(FlattenerError)
            self.assertIsInstance(fe.value.args[0], MissingRenderMethod)

        test("garbage")
        test("garbage:missing")

    def test_json_serialize_unknown_type(self):
        """
        The JSON serializer will raise a L{TypeError} when it can't find an
        appropriate type.
        """
        from klein._plating import json_serialize

        class reprish(object):
            def __repr__(self):
                return '<blub>'

        te = self.assertRaises(TypeError, json_serialize, {"an": reprish()})
        self.assertIn("<blub>", str(te))
Example #27
0
    pass

@webapp.route('/msg', methods=['POST'])
def do_post(request):
    content = json.loads(request.content.read())

    token = request.requestHeaders.getRawHeaders('authorization')

    webapp.msgs.append( dict( text=content["msg"] ) )
    wampapp.session.publish('com.example.msg', webapp.msgs )
    response = json.dumps(dict(the_data=content), indent=4)
    return response

@webapp.route('/')
def home(request):
    webapp.visits += 1
    wampapp.session.publish('com.example.msg', webapp.msgs)
    page = webapp.templates.get_template('index.html')
    return page.render(visits=webapp.visits)



if __name__ == "__main__":
    import sys
    from twisted.python import log
    from twisted.web.server import Site
    from twisted.internet import reactor
    log.startLogging(sys.stdout)

    reactor.listenTCP(5000, Site(webapp.resource()))
    wampapp.run("ws://crossbar:8080/ws", "realm1")