Ejemplo n.º 1
0
    def _init_(self, **kwargs):
        self.custom_agent = Agent(reactor, connectTimeout=20)
        self.contentType = self._Configs.get('yomboapi', 'contenttype',
                                             'application/json',
                                             False)  # TODO: Msgpack later
        self.base_url = self._Configs.get('yomboapi', 'baseurl',
                                          "https://api.yombo.net/api", False)
        self.allow_system_session = self._Configs.get('yomboapi',
                                                      'allow_system_session',
                                                      True)
        self.init_defer = None

        self.api_key = self._Configs.get('yomboapi', 'api_key',
                                         'aBMKp5QcQoW43ipauw88R0PT2AohcE',
                                         False)
        self.valid_system_session = None
        self.valid_login_key = None
        self.session_validation_cache = ExpiringDict()

        try:
            self.system_session = self._Configs.get(
                'yomboapi', 'auth_session')  # to be encrypted with gpg later
            self.system_login_key = self._Configs.get(
                'yomboapi', 'login_key')  # to be encrypted with gpg later
        except KeyError:
            self.system_session = None
            self.system_login_key = None

        if self._Loader.operating_mode == 'run':
            self.init_defer = Deferred()
            self.validate_system_login()
            return self.init_defer
Ejemplo n.º 2
0
    def _init_(self, **kwargs):
        self.enabled = self._Configs.get('webinterface', 'enabled', True)
        if not self.enabled:
            return

        self.gateway_id = self._Configs.get2('core', 'gwid', 'local', False)
        # self._LocalDB = self._Loader.loadedLibraries['localdb']
        self._current_dir = self._Atoms.get('yombo.path') + "/yombo"
        self._dir = '/lib/webinterface/'
        self._build_dist()  # Make all the JS and CSS files
        self.secret_pin_totp = self._Configs.get2(
            'webinterface', 'auth_pin_totp',
            yombo.utils.random_string(
                length=16, letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'))
        self.api = self._Loader.loadedLibraries['yomboapi']
        self._VoiceCmds = self._Loader.loadedLibraries['voicecmds']
        self.misc_wi_data = {}
        self.sessions = Sessions(self._Loader)

        self.wi_port_nonsecure = self._Configs.get2('webinterface',
                                                    'nonsecure_port', 8080)
        self.wi_port_secure = self._Configs.get2('webinterface', 'secure_port',
                                                 8443)

        self.webapp.templates = jinja2.Environment(
            loader=jinja2.FileSystemLoader(self._current_dir))
        self.setup_basic_filters()

        route_atoms(self.webapp)
        route_automation(self.webapp)
        route_api_v1(self.webapp)
        route_configs(self.webapp)
        route_devices(self.webapp)
        route_locations(self.webapp)
        route_devtools_debug(self.webapp)
        route_devtools_config(self.webapp)
        route_gateways(self.webapp)
        route_home(self.webapp)
        route_misc(self.webapp)
        route_modules(self.webapp)
        route_notices(self.webapp)
        route_panel(self.webapp)
        route_setup_wizard(self.webapp)
        route_statistics(self.webapp)
        route_states(self.webapp)
        route_system(self.webapp)
        route_voicecmds(self.webapp)

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

        self.already_start_web_servers = False
        self.web_factory = None

        # just here to set a password if it doesn't exist.
        mqtt_password = self._Configs.get('mqtt_users', 'panel.webinterface',
                                          yombo.utils.random_string())
Ejemplo n.º 3
0
    def _init_(self, **kwargs):
        """
        On startup, various libraries will need certs (webinterface, MQTT) for encryption. This
        module stores certificates in a directory so other programs can use certs as well. It's
        working data is stored in the database, while a backup is kept in the file system as well
        and is only used if the data is missing from the database.

        If a cert isn't avail for the requested sslname, it will receive a self-signed certificate.

        :return:
        """
        # Since SSL generation can take some time on slower devices, we use a simple queue system.
        self.generate_csr_queue = self._Queue.new(
            'library.sslcerts.generate_csr', self.generate_csr)
        self.hostname = gethostname()

        self.gateway_id = self._Configs.get('core', 'gwid', 'local', False)
        self.fqdn = self._Configs.get2('dns', 'fqdn', None, False)

        self.received_message_for_unknown = ExpiringDict(100, 600)
        self.self_signed_cert_file = self._Atoms.get(
            'yombo.path') + "/usr/etc/certs/sslcert_selfsigned.cert.pem"
        self.self_signed_key_file = self._Atoms.get(
            'yombo.path') + "/usr/etc/certs/sslcert_selfsigned.key.pem"
        self.self_signed_expires = self._Configs.get("sslcerts",
                                                     "self_signed_expires",
                                                     None, False)
        self.self_signed_created = self._Configs.get("sslcerts",
                                                     "self_signed_created",
                                                     None, False)

        if os.path.exists(self.self_signed_cert_file) is False or \
                self.self_signed_expires is None or \
                self.self_signed_expires < int(time() + (60*60*24*60)) or \
                self.self_signed_created is None or \
                not os.path.exists(self.self_signed_key_file):
            logger.info(
                "Generating a self signed cert for SSL. This can take a few moments."
            )
            yield self._create_self_signed_cert()

        self.self_signed_cert = yield read_file(self.self_signed_cert_file)
        self.self_signed_key = yield read_file(self.self_signed_key_file)

        self.managed_certs = yield self._SQLDict.get(
            self,
            "managed_certs",
            serializer=self.sslcert_serializer,
            unserializer=self.sslcert_unserializer)
        # for name, data in self.managed_certs.items():
        #     print("cert name: %s" % name)
        #     print("  cert data: %s" % data.__dict__)

        self.check_if_certs_need_update_loop = None
Ejemplo n.º 4
0
class SSLCerts(YomboLibrary):
    """
    Responsible for managing various encryption and TLS (SSL) certificates.
    """
    managed_certs = {}
    received_message_for_unknown = ExpiringDict(100, 600)

    def __contains__(self, cert_requested):
        """
        Looks for an sslkey with the given sslname.

            >>> if "webinterface" in self._SSLCerts["library_webinterface"]:  #by uuid

        :param cert_requested: The ssl cert sslname to search for.
        :type cert_requested: string
        :return: Returns true if exists, otherwise false.
        :rtype: bool
        """
        if cert_requested in self.managed_certs:
            return True
        else:
            return False

    @inlineCallbacks
    def _init_(self, **kwargs):
        """
        On startup, various libraries will need certs (webinterface, MQTT) for encryption. This
        module stores certificates in a directory so other programs can use certs as well. It's
        working data is stored in the database, while a backup is kept in the file system as well
        and is only used if the data is missing from the database.

        If a cert isn't avail for the requested sslname, it will receive a self-signed certificate.

        :return:
        """
        # Since SSL generation can take some time on slower devices, we use a simple queue system.
        self.generate_csr_queue = self._Queue.new(
            "library.sslcerts.generate_csr", self.generate_csr)
        self.hostname = gethostname()

        self.local_gateway = self._Gateways.local

        self.self_signed_cert_file = self._Atoms.get(
            "working_dir") + "/etc/certs/sslcert_selfsigned.cert.pem"
        self.self_signed_key_file = self._Atoms.get(
            "working_dir") + "/etc/certs/sslcert_selfsigned.key.pem"
        self.self_signed_expires_at = self._Configs.get(
            "sslcerts", "self_signed_expires_at", None, False)
        self.self_signed_created_at = self._Configs.get(
            "sslcerts", "self_signed_created_at", None, False)
        self.default_key_size = self._Configs.get("sslcerts",
                                                  "default_key_size", 2048)

        if os.path.exists(self.self_signed_cert_file) is False or \
                self.self_signed_expires_at is None or \
                self.self_signed_expires_at < int(time() + (60*60*24*60)) or \
                self.self_signed_created_at is None or \
                not os.path.exists(self.self_signed_key_file):
            logger.info(
                "Generating a self signed cert for SSL. This can take a few moments."
            )
            yield self._create_self_signed_cert()

        self.self_signed_cert = yield read_file(self.self_signed_cert_file)
        self.self_signed_key = yield read_file(self.self_signed_key_file)

        self.managed_certs = yield self._SQLDict.get(
            self,
            "managed_certs",
            serializer=self.sslcert_serializer,
            unserializer=self.sslcert_unserializer)
        for key, item in self.managed_certs.items():
            print(f"Managed certs: {self.managed_certs}")

        self.check_if_certs_need_update_loop = None

    @inlineCallbacks
    def _load_(self, **kwargs):
        """
        Starts the loop to check if any certs need to be updated.

        :return:
        """
        self.check_if_certs_need_update_loop = LoopingCall(
            self.check_if_certs_need_update)
        self.check_if_certs_need_update_loop.start(
            self._Configs.get("sqldict", "save_interval",
                              random_int(60 * 60 * 24, .1), False), False)

        # Check if any libraries or modules need certs.
        if self.local_gateway.dns_name is None:
            logger.warn(
                "Unable to generate sign ssl/tls certs, gateway has no domain name."
            )
            return

        if self._Loader.operating_mode != "run":
            return
        sslcerts = yield global_invoke_all(
            "_sslcerts_",
            called_by=self,
        )
        for component_name, ssl_certs in sslcerts.items():
            logger.debug(
                f"Adding new managed certs from hook: {component_name}")
            if isinstance(ssl_certs, tuple) is False and isinstance(
                    ssl_certs, list) is False:
                ssl_certs = [ssl_certs]
            for ssl_item in ssl_certs:
                yield self.add_sslcert(ssl_item)

    def _stop_(self, **kwargs):
        """
        Simply stop any loops, tell all the certs to save themselves to disk as a backup.
        :return:
        """
        if hasattr(self, "check_if_certs_need_update_loop"):
            if self.check_if_certs_need_update_loop is not None and self.check_if_certs_need_update_loop.running:
                self.check_if_certs_need_update_loop.stop()

        if hasattr(self, "managed_certs"):
            for sslname, cert in self.managed_certs.items():
                cert.stop()

    def sslcert_serializer(self, item):
        """
        Used to hydrate the list of certs. Somethings shouldn't be stored in the SQLDict.

        :param item:
        :return:
        """
        return item.asdict()

    @inlineCallbacks
    def sslcert_unserializer(self, item):
        """
        Used by SQLDict to hydrate an item stored.

        :param item:
        :return:
        """
        # print(f"sslcert unserialze: {item}")
        results = SSLCert(self, "sqldict", DictObject(item))
        yield results.start()
        return results

    @inlineCallbacks
    def check_if_certs_need_update(self):
        """
        Called periodically to see if any certs need to be updated. Once a day is enough, we have 30 days to get this
        done.
        """
        for sslname, cert in self.managed_certs.items():
            yield cert.check_if_rotate_needed()

    @inlineCallbacks
    def add_sslcert(self, ssl_data):
        """
        Called when new SSL Certs need to be managed.
        
        :param sslcerts:
        :param bypass_checks: For internal use only.
        :return: 
        """
        logger.debug("add_sslcert: {ssl_data}", ssl_data=ssl_data)
        if self.local_gateway.dns_name is None:
            logger.warn(
                "Unable to generate sign ssl/tls certs, gateway has no domain name."
            )
            return

        try:
            ssl_data = self.check_csr_input(
                ssl_data)  # Clean up module developers input.
        except YomboWarning as e:
            logger.warn(f"Cannot add cert: {e}")
            return

        if ssl_data["sslname"] in self.managed_certs:
            self.managed_certs[ssl_data["sslname"]].update_attributes(ssl_data)
        else:
            yield self._import_cert(ssl_data["sslname"], DictObject(ssl_data))

    @inlineCallbacks
    def _import_cert(self, cert_name, data, source=None):
        if source is None:
            source = "sslcerts"
        self.managed_certs[cert_name] = SSLCert(self, source, DictObject(data))
        yield self.managed_certs[cert_name].start()

    def get(self, sslname_requested):
        """
        Gets a cert for the request name.

        .. note::

           self._SSLCerts("library_webinterface", self.have_updated_ssl_cert)
        """
        # logger.debug("looking for: {sslname_requested}", sslname_requested=sslname_requested)
        if sslname_requested in self.managed_certs:
            # logger.debug("found by cert! {sslname_requested}", sslname_requested=sslname_requested)
            return self.managed_certs[sslname_requested].get()
        else:
            if sslname_requested != "selfsigned":
                logger.info(
                    "Could not find cert for '{sslname}', sending self signed. Library or module should implement _sslcerts_ with a callback method.",
                    sslname=sslname_requested)
            return self.get_self_signed()

    def get_self_signed(self):
        key_crypt = crypto.load_privatekey(crypto.FILETYPE_PEM,
                                           self.self_signed_key)
        if isinstance(key_crypt, tuple):
            key_crypt = key_crypt[0]
        cert_crypt = crypto.load_certificate(crypto.FILETYPE_PEM,
                                             self.self_signed_cert)
        if isinstance(cert_crypt, tuple):
            cert_crypt = cert_crypt[0]

        return {
            "key": self.self_signed_key,
            "cert": self.self_signed_cert,
            "chain": None,
            "key_crypt": key_crypt,
            "cert_crypt": cert_crypt,
            "chain_crypt": None,
            "expires_at": self.self_signed_expires_at,
            "created_at": self.self_signed_created_at,
            "signed_at": self.self_signed_created_at,
            "self_signed": True,
            "cert_file": self.self_signed_cert_file,
            "key_file": self.self_signed_key_file,
            "chain_file": None,
        }

    def check_csr_input(self, csr_request):
        results = {}

        if "sslname" not in csr_request:
            raise YomboWarning("'sslname' is required.")
        results["sslname"] = csr_request["sslname"]

        if self.local_gateway.dns_name is None:
            raise YomboWarning(
                "Unable to create SSL Certs, no system domain set.")

        if "cn" not in csr_request:
            raise YomboWarning(
                f"'cn' must be included, and must end with our local FQDN: {self.local_gateway.dns_name}"
            )
        elif csr_request["cn"].endswith(self.local_gateway.dns_name) is False:
            results[
                "cn"] = csr_request["cn"] + "." + self.local_gateway.dns_name
        else:
            results["cn"] = csr_request["cn"]

        if "sans" not in csr_request:
            results["sans"] = None
        else:
            san_list = []
            for san in csr_request["sans"]:
                if san.endswith(self.local_gateway.dns_name) is False:
                    san_list.append(
                        str(san + "." + self.local_gateway.dns_name))
                else:
                    san_list.append(str(san))

            results["sans"] = san_list

        # if "key_type" in csr_request:  # allow changing default, might change in the future.
        #     if csr_request["key_type"] != "rsa":
        #         raise YomboWarning("key_type must be 'rsa', received: %s" % csr_request["key_type"])
        #     results["key_type"] = csr_request["key_type"]
        # else:
        #
        if "key_size" in csr_request:
            if csr_request["key_size"] < 2048:
                csr_request["key_size"] = 2048
            if csr_request["key_size"] > 4096:
                csr_request["key_size"] = 4096
        else:
            csr_request["key_size"] = self.default_key_size
        results["key_type"] = "rsa"
        results["key_size"] = csr_request["key_size"]

        if "csr_file" not in csr_request:
            csr_request["csr_file"] = None
        results["csr_file"] = csr_request["csr_file"]

        if "key_file" not in csr_request:
            csr_request["key_file"] = None
        results["key_file"] = csr_request["key_file"]

        if "callback" in csr_request:
            results["update_callback"] = csr_request["callback"]
        elif "update_callback" in csr_request:
            results["update_callback"] = csr_request["update_callback"]

        if "callback_type" in csr_request:
            results["update_callback_type"] = csr_request["callback_type"]
        elif "update_callback_type" in csr_request:
            results["update_callback_type"] = csr_request[
                "update_callback_type"]

        if "callback_component" in csr_request:
            results["update_callback_component"] = csr_request[
                "callback_component"]
        elif "update_callback_component" in csr_request:
            results["update_callback_component"] = csr_request[
                "update_callback_component"]

        if "callback_function" in csr_request:
            results["update_callback_function"] = csr_request[
                "callback_function"]
        elif "update_callback_function" in csr_request:
            results["update_callback_function"] = csr_request[
                "update_callback_function"]
        return results

    @inlineCallbacks
    def generate_csr(self, args):
        """
        This function shouldn't be called directly. Instead, use the queue
        "self.generate_csr_queue.put(request, callback, callback_args)" or
        "self._SSLCerts.generate_csr_queue.put()".
        
        Requests certs to be made. Will return right away with a request ID. A callback can be set to return
        the cert once it's complete.

        :return:
        """
        logger.debug("Generate_CSR called with args: {args}", args=args)
        kwargs = self.check_csr_input(args)

        if kwargs["key_type"] == "rsa":
            kwargs["key_type"] = crypto.TYPE_RSA
        else:
            kwargs["key_type"] = crypto.TYPE_DSA

        req = crypto.X509Req()
        req.get_subject().CN = kwargs["cn"]
        req.get_subject().countryName = "US"
        req.get_subject().stateOrProvinceName = "California"
        req.get_subject().localityName = "Sacramento"
        req.get_subject().organizationName = "Yombo"
        req.get_subject(
        ).organizationalUnitName = "Gateway " + self.gateway_id[0:15]

        # Appends SAN to have "DNS:"
        if kwargs["sans"] is not None:
            san_string = []
            for i in kwargs["sans"]:
                san_string.append(f"DNS: {i}")
            san_string = ", ".join(san_string)
            x509_extensions = [
                crypto.X509Extension(b"subjectAltName", False,
                                     unicode_to_bytes(san_string))
            ]
            req.add_extensions(x509_extensions)

        start = time()
        key = yield threads.deferToThread(
            self._generate_key, **{
                "key_type": kwargs["key_type"],
                "key_size": kwargs["key_size"]
            })
        duration = round(float(time()) - start, 4)
        self._Events.new("sslcerts", "generate_new",
                         (args["sslname"], kwargs["cn"], san_string, duration))

        req.set_pubkey(key)

        req.sign(key, "sha256")

        csr = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
        key_file = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)

        if kwargs["csr_file"] is not None:
            yield save_file(kwargs["csr_file"], csr)
        if kwargs["key_file"] is not None:
            yield save_file(kwargs["key_file"], key_file)

        return {
            "csr": csr,
            "csr_hash": sha256_compact(unicode_to_bytes(csr)),
            "key": key_file
        }

    @inlineCallbacks
    def _create_self_signed_cert(self):
        """
        Creates a self signed cert. Shouldn't be called directly except by this library for its
        own use.
        """
        logger.debug("Creating self signed cert.")
        req = crypto.X509()

        req.get_subject().CN = "localhost"
        req.get_subject().countryName = "US"
        req.get_subject().stateOrProvinceName = "California"
        req.get_subject().localityName = "Self Signed"
        req.get_subject().organizationName = "Yombo"
        req.get_subject(
        ).organizationalUnitName = f"Gateway {self.gateway_id[0:15]} Self Signed"

        req.set_serial_number(int(time()))
        req.gmtime_adj_notBefore(0)
        req.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
        self.self_signed_expires_at = time() + (10 * 365 * 24 * 60 * 60)
        self.self_signed_created_at = time()
        self._Configs.set("sslcerts", "self_signed_expires_at",
                          self.self_signed_expires_at)
        self._Configs.set("sslcerts", "self_signed_created_at",
                          self.self_signed_created_at)
        req.set_issuer(req.get_subject())
        key = yield threads.deferToThread(
            self._generate_key, **{
                "key_type": crypto.TYPE_RSA,
                "key_size": self.default_key_size
            })
        req.set_pubkey(key)
        req.sign(key, "sha256")

        csr_key = crypto.dump_certificate(crypto.FILETYPE_PEM, req)
        key_file = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)

        yield save_file(self.self_signed_cert_file, csr_key)
        yield save_file(self.self_signed_key_file, key_file)

        return {"csr_key": csr_key, "key": key_file}

    def _generate_key(self, **kwargs):
        """
        This is a blocking function and should only be called by the sslcerts library. This is called
        in a seperate thread.

        Responsible for generating a key and csr.

        :return:
        """
        # logger.debug("About to generate key: {kwargs}", kwargs=kwargs)
        key = crypto.PKey()
        key.generate_key(kwargs["key_type"], kwargs["key_size"])
        return key

    def send_csr_request(self, csr_text, sslname):
        """
        Submit CSR request to Yombo. The sslname is also sent to be used for tracking. This will be returned
        directly back to us. This allows us to get out signed cert back if we happen to restart
        between sending the CSR and getting the signed key back.
        
        :param csr_text: CSR request text
        :param sslname: Name of the ssl for tracking.
        :return:
        """
        logger.info("Sending CSR request for cert: {sslname}", sslname=sslname)
        if len(sslname) > 100:
            raise YomboWarning("'sslname' too long, limit is 100 characters.")

        body = {
            "csr_text": csr_text,
            "sslname": sslname,
        }

        request_msg = self._AMQPYombo.generate_message_request(
            exchange_name="ysrv.e.gw_sslcerts",
            source="yombo.gateway.lib.amqpyobo",
            destination="yombo.server.sslcerts",
            request_type="csr_request",
            body=body,
        )
        self._AMQPYombo.publish(**request_msg)
        return request_msg

    def amqp_incoming_request(self, headers, body, **kwargs):
        """
        Signed SSL certs comes as requests, even though it's really a response. This avoids the requirement
        that all "responses" have a sent correlation ID.

        :param headers:
        :param body:
        :param kwargs:
        :return:
        """
        # print(f"sslcerts: amqp_incoming: {body}")
        # print(f"sslcerts: amqp_incoming: {headers}")
        request_type = headers["request_type"]
        kwargs["headers"] = headers
        kwargs["body"] = body
        if request_type == "csr_response":
            self.amqp_incoming_response_to_csr_request(**kwargs)
        else:
            logger.warn(
                "AMQP:Handler:Control - Received unknown request_type: {request_type}",
                request_type=request_type)

    def amqp_incoming_response_to_csr_request(self,
                                              body=None,
                                              properties=None,
                                              correlation_info=None,
                                              **kwargs):
        """
        Called when we get a signed cert back from a CSR.
        
        :param body:
        :param properties: 
        :param correlation_info: 
        :param kwargs: 
        :return: 
        """
        logger.debug("Received CSR response message: {body}", body=body)
        if "sslname" not in body:
            logger.warn(
                "Discarding response, doesn't have an sslname attached."
            )  # can't raise exception due to AMPQ processing.
            return
        logger.info("Received a new signed SSL/TLS certificate for: {sslname}",
                    sslname=body["sslname"])
        sslname = bytes_to_unicode(body["sslname"])
        if sslname not in self.managed_certs:
            logger.warn(
                "It doesn't appear we have a managed cert for the given SSL name. Lets store it for a few minutes: {sslname}",
                sslname=sslname)
            if sslname in self.received_message_for_unknown:
                self.received_message_for_unknown[sslname].append(body)
            else:
                self.received_message_for_unknown[sslname] = [body]
        else:
            self.managed_certs[sslname].amqp_incoming_response_to_csr_request(
                properties, body, correlation_info)

    def validate_csr_private_certs_match(self, csr_text, key_text):
        csr = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr_text)
        key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_text)
        return csr.verify(key)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    def _init_(self, **kwargs):
        self.frontend_building = False
        self.web_interface_fully_started = False
        self.enabled = self._Configs.get("webinterface", "enabled", True)

        self.fqdn = self._Configs.get2("dns", "fqdn", None, False)

        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.working_dir = self._Atoms.get("working_dir")
        self.app_dir = self._Atoms.get("app_dir")
        self.wi_dir = "/lib/webinterface"

        self.misc_wi_data = {}

        self.wi_port_nonsecure = self._Configs.get2("webinterface",
                                                    "nonsecure_port", 8080)
        self.wi_port_secure = self._Configs.get2("webinterface", "secure_port",
                                                 8443)

        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 = {}

        # Load API routes
        route_api_v1_atoms(self.webapp)
        route_api_v1_automation_rules(self.webapp)
        # route_api_v1_camera(self.webapp)
        route_api_v1_debug(self.webapp)
        route_api_v1_device(self.webapp)
        route_api_v1_device_command(self.webapp)
        # route_api_v1_events(self.webapp)
        # route_api_v1_gateway(self.webapp)
        # route_api_v1_module(self.webapp)
        route_api_v1_mqtt(self.webapp)
        # route_api_v1_notification(self.webapp)
        route_api_v1_scenes(self.webapp)
        # route_api_v1_server(self.webapp)
        # route_api_v1_statistics(self.webapp)
        # route_api_v1_stream(self.webapp, self)
        route_api_v1_states(self.webapp)
        route_api_v1_system(self.webapp)
        # route_api_v1_storage(self.webapp)
        route_api_v1_user(self.webapp)
        # route_api_v1_webinterface_logs(self.webapp)

        # Load web server routes
        route_home(self.webapp)
        route_misc(self.webapp)
        route_system(self.webapp)
        route_user(self.webapp)
        if self.operating_mode != "run":
            from yombo.lib.webinterface.routes.restore import route_restore
            from yombo.lib.webinterface.routes.setup_wizard import route_setup_wizard
            route_setup_wizard(self.webapp)
            route_restore(self.webapp)

        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.web_factory = None
        self.user_login_tokens = self._Cache.ttl(name="lib.users.cache",
                                                 ttl=300)
Ejemplo n.º 7
0
 def _init_(self):
     """
     Setups up the basic framework.
     """
     # We only cache the last few events, and only for certain time.
     self.notifications = ExpiringDict(max_len=100, max_age_seconds=600)