Ejemplo n.º 1
0
    def theme(self, theme):
        """
Sets the theme to use.

:param theme: Output theme

:since: v1.0.0
        """

        theme = Binary.str(theme)

        """
Set theme or reset to None to use the default one configured
        """

        if (theme is None): self._theme = None
        else:
            theme_path = InputFilter.filter_file_path(theme).replace(".", path.sep)
            file_path_name = path.join(self.path, theme_path, "site.tsc")

            if (os.access(file_path_name, os.R_OK)): self._theme = theme
            else: self._theme = None
        #

        """
Read corresponding theme configuration
        """

        if (self._theme is None): file_path_name = path.join(self.path, self.theme.replace(".", path.sep), "site.tsc")

        file_path_name = file_path_name[:-3] + "json"
        Settings.read_file(file_path_name)
Ejemplo n.º 2
0
    def __init__(self):
        """
Constructor __init__(GstVideo)

:since: v0.2.00
        """

        AbstractVideo.__init__(self)
        Gstreamer.__init__(self)

        self.playback_control_timeout = 5
        """
Playback control command timeout.
        """
        self.thumbnail_position_percentage = 0.05
        """
Position in percent where to generate a thumbnail from.
        """

        playback_control_timeout = float(Settings.get("pas_gapi_gstreamer_playback_control_timeout", 0))
        if (playback_control_timeout > 0): self.playback_control_timeout = playback_control_timeout

        self.supported_features['thumbnail'] = True

        thumbnail_position_percentage = Settings.get("pas_gapi_gstreamer_thumbnail_position_percentage", 0)

        if (thumbnail_position_percentage > 0
            and thumbnail_position_percentage <= 100
           ): self.thumbnail_position_percentage = (thumbnail_position_percentage / 100)
Ejemplo n.º 3
0
    def _configure(self):
        """
Configures the server

:since: v1.0.0
        """

        listener_host = Settings.get("pas_http_twisted_server_host", self.socket_hostname)
        self.port = int(Settings.get("pas_http_twisted_server_port", 8080))

        self.reactor = reactor
        self.reactor.addSystemEventTrigger('before', 'shutdown', self.stop)

        server_description = "tcp:{0:d}".format(self.port)

        if (listener_host == ""): self.host = Settings.get("pas_http_server_preferred_hostname", self.socket_hostname)
        else:
            self.host = listener_host
            server_description += ":interface={0}".format(self.host)
        #

        self.thread_pool = ThreadPool()
        self.thread_pool.start()

        if (self._log_handler is not None): self._log_handler.info("pas.http.core Twisted server starts at '{0}:{1:d}'", listener_host, self.port, context = "pas_http_core")

        server = serverFromString(self.reactor, server_description)
        server.listen(Site(WSGIResource(reactor, self.thread_pool, HttpWsgi1Request)))

        """
Configure common paths and settings
        """

        AbstractServer._configure(self)
Ejemplo n.º 4
0
    def get_user_agent_identifiers(user_agent):
        """
Returns a UPnP client based on the given HTTP or SSDP user agent value.

:param user_agent: HTTP or SSDP user agent value

:return: (object) UPnP client; None on error
:since:  v0.2.00
        """

        _return = ""

        if (not Settings.is_defined("pas_upnp_client_replacement_list")): Settings.read_file("{0}/settings/pas_upnp.json".format(Settings.get("path_data")))
        replacement_list = Settings.get("pas_upnp_client_replacement_list", None)

        if (type(replacement_list) is dict):
            replacement_list_keys = sorted(replacement_list.keys(), reverse = True)
            for upnp_value in replacement_list_keys: user_agent = user_agent.replace(upnp_value, replacement_list[upnp_value])
        #

        for re_result in re.finditer("([\\d\\w\\.]+/([0-9\\.]+(\\W|$))+)", user_agent):
            if (_return != ""): _return += "_"
            _return += re.sub("\\W+", "_", re_result.group(1)).strip("_")
        #

        if (_return == ""): _return = re.sub("\\W+", "_", user_agent).lower()
        else: _return = _return.lower()

        return _return
Ejemplo n.º 5
0
    def _is_file_access_allowed(self, file_path_name):
        """
Checks if the file access is allowed for streaming.

:param file_path_name: Path to the requested file

:return: (bool) True if allowed
:since:  v0.2.00
        """

        _return = False

        if Settings.is_defined("pas_streamer_file_basedir_list"):
            basedir_list = Settings.get("pas_streamer_file_basedir_list")

            if type(basedir_list) is list:
                file_absolute_path_name = path.abspath(file_path_name)

                for basedir in basedir_list:
                    if file_absolute_path_name.startswith(basedir):
                        _return = True
                        break
                    #
                #

                if (not _return) and self.log_handler is not None:
                    self.log_handler.warning(
                        "streamer.File denied access to {0}", file_path_name, context="pas_streamer"
                    )
            #
        else:
            _return = True

        return _return
Ejemplo n.º 6
0
    def __init__(self, scheme = None, host = None, port = None, path = None):
        """
Constructor __init__(Link)

:param scheme: URL scheme
:param host: URL host
:param port: URL port
:param path: URL path

:since: v0.2.00
        """

        self.host = host
        """
Override for the URL host
        """
        self.path = path
        """
Override for the URL path
        """
        self.port = port
        """
Override for the URL port
        """
        self.scheme = scheme
        """
Override for the URL scheme
        """

        if (not Settings.is_defined("pas_http_site_preferred_url_base")): Settings.read_file("{0}/settings/pas_http.json".format(Settings.get("path_data")))
Ejemplo n.º 7
0
    def __init__(self):
        """
Constructor __init__(Module)

:since: v0.2.00
        """

        AbstractHttpController.__init__(self)

        Settings.read_file("{0}/settings/pas_http_user.json".format(Settings.get("path_data")))
Ejemplo n.º 8
0
    def get_user_agent_settings(user_agent):
        """
Returns the user agent specific client settings dictionary.

:param user_agent: User agent

:return: (dict) User agent specific client settings; None on error
:since:  v0.2.00
        """

        _return = { }

        settings = None
        user_agent = Binary.str(user_agent)

        if (type(user_agent) is str):
            settings = Hook.call("dNG.pas.upnp.Client.getUserAgentSettings", user_agent = user_agent)

            if (not isinstance(settings, dict)):
                identifier = ClientSettings.get_user_agent_identifiers(user_agent)
                settings_file_name = "{0}.json".format(identifier)

                settings = JsonFileContent.read(path.join(Settings.get("path_data"),
                                                          "upnp",
                                                          "user_agents",
                                                          settings_file_name
                                                         )
                                               )

                if (settings is None):
                    log_line = "pas.upnp.ClientSettings reporting: No client settings found for user agent '{0}' with identifier '{1}'"

                    if (Settings.get("pas_upnp_log_missing_user_agent", False)): LogLine.warning(log_line, user_agent, identifier, context = "pas_upnp")
                    else: LogLine.debug(log_line, user_agent, identifier, context = "pas_upnp")
                #
            #
        #

        if (settings is not None):
            if ("client_file" in settings):
                base_settings = JsonFileContent.read(path.join(Settings.get("path_data"),
                                                               "upnp",
                                                               "user_agents",
                                                               InputFilter.filter_file_path(settings['client_file'])
                                                              )
                                                    )

                if (type(base_settings) is dict): _return.update(base_settings)
                del(settings['client_file'])
            #

            _return.update(settings)
        #

        return _return
Ejemplo n.º 9
0
    def oset(self, oset):
        """
Sets the OSet to use.

:param oset: OSet name

:since: v1.0.0
        """

        self._oset = oset
        Settings.set("x_pas_http_oset", self._oset)
Ejemplo n.º 10
0
    def send(self):
        """
Sends a message.

:since: v1.0.0
        """

        if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}.send()- (#echo(__LINE__)#)", self, context = "pas_email")

        if (self.message is None): raise IOException("No message defined to be send")
        if (not self.message.is_recipient_set): raise ValueException("No recipients defined for e-mail")
        if (not self.message.is_subject_set): raise IOException("No subject defined for e-mail")

        bcc_list = self.message.bcc
        cc_list = self.message.cc
        to_list = self.message.to

        rcpt_list = to_list
        if (len(bcc_list) > 0): rcpt_list = Client._filter_unique_list(rcpt_list, bcc_list)
        if (len(cc_list) > 0): rcpt_list = Client._filter_unique_list(rcpt_list, cc_list)

        is_auth_possible = False
        smtp_user = None
        smtp_password = None

        if (Settings.is_defined("pas_smtp_client_user") and Settings.is_defined("pas_smtp_client_password")):
            is_auth_possible = True
            smtp_user = Settings.get("pas_smtp_client_user")
            smtp_password = Settings.get("pas_smtp_client_password")
        #

        smtp_connection = None

        try:
            smtp_connection = (self._get_lmtp_connection()
                               if (Settings.is_defined("pas_smtp_client_lmtp_host")
                                   or Settings.is_defined("pas_smtp_client_lmtp_path_name")
                                  )
                               else self._get_smtp_connection()
                              )

            if (is_auth_possible): smtp_connection.login(smtp_user, smtp_password)

            if (not self.message.is_sender_set):
                self.message.sender = (Settings.get("pas_email_sender_public")
                                       if (Settings.is_defined("pas_email_sender_public")) else
                                       Settings.get("pas_email_address_public")
                                      )
            #

            sender = self.message.sender

            smtp_connection.sendmail(sender, rcpt_list, self.message.as_string())

            self.message = None
        finally:
            try:
                if (smtp_connection is not None): smtp_connection.quit()
            except SMTPServerDisconnected: pass
Ejemplo n.º 11
0
    def is_available():
        """
True if a persistent tasks executing scheduler is available.

:return: (bool) True if available
:since:  v0.2.00
        """

        if (not Settings.is_defined("pas_tasks_daemon_listener_address")):
            Settings.read_file("{0}/settings/pas_tasks_daemon.json".format(Settings.get("path_data")))
        #

        return Settings.is_defined("pas_tasks_daemon_listener_address")
Ejemplo n.º 12
0
    def execute_logout(self):
        """
Action for "logout"

:since: v0.2.00
        """

        source_iline = InputFilter.filter_control_chars(self.request.get_dsd("source", "")).strip()
        target_iline = InputFilter.filter_control_chars(self.request.get_dsd("target", "")).strip()

        if (target_iline == ""):
            if (Settings.is_defined("pas_http_user_logout_default_target_lang_{0}".format(self.request.get_lang()))): target_iline = Settings.get("pas_http_user_logout_default_target_lang_{0}".format(self.request.get_lang()))
            elif (Settings.is_defined("pas_http_user_logout_default_target")): target_iline = Settings.get("pas_http_user_logout_default_target")
            else: target_iline = source_iline
        #

        L10n.init("pas_http_user")

        if (self.response.is_supported("html_css_files")): self.response.add_theme_css_file("mini_default_sprite.min.css")

        Link.set_store("servicemenu",
                       Link.TYPE_RELATIVE_URL,
                       L10n.get("core_back"),
                       { "__query__": re.sub("\\_\\_\\w+\\_\\_", "", source_iline) },
                       icon = "mini-default-back",
                       priority = 7
                      )

        if (not self.request.is_supported("session")): raise TranslatableError("core_unknown_error", 500)

        session = Session.load(session_create = False)

        if (session is not None):
            session.delete()
            self.request.set_session(None)
        #

        Link.clear_store("servicemenu")

        target_iline = re.sub("\\_\\_\\w+\\_\\_", "", target_iline)

        redirect_request = PredefinedHttpRequest()
        redirect_request.set_module("output")
        redirect_request.set_service("http")
        redirect_request.set_action("done")

        redirect_request.set_parameter_chained("title", L10n.get("pas_http_user_logout"))
        redirect_request.set_parameter_chained("message", L10n.get("pas_http_user_done_logout"))
        redirect_request.set_parameter_chained("target_iline", target_iline)

        self.request.redirect(redirect_request)
Ejemplo n.º 13
0
    def _get_implementation_class_name():
        """
Returns the media implementation class name based on the configuration set.

:return: (str) Media implementation class name
:since:  v0.2.00
        """

        Settings.read_file("{0}/settings/pas_media.json".format(Settings.get("path_data")))

        _return = Settings.get("pas_media_video_implementation", "")
        if (_return == ""): LogLine.warning("Media video implementation class is not configured")

        return _return
Ejemplo n.º 14
0
    def __init__(self, _type, control_point = None):
        """
Constructor __init__(ControlPointEvent)

:param _type: Event to be delivered
:param control_point: Control point scheduling delivery

:since: v0.2.00
        """

        AbstractEvent.__init__(self, _type)

        self.announcement_divider = None
        """
Divider for the announcements interval to set how many announcements will be within the interval
        """
        self.announcement_interval = None
        """
Announcement interval
        """
        self.configid = None
        """
UPnP configId value (configid.upnp.org)
        """
        self.location = None
        """
UPnP HTTP location URL
        """
        self.search_target = None
        """
M-SEARCH ST value
        """
        self.target_host = None
        """
M-SEARCH response target host
        """
        self.target_port = None
        """
M-SEARCH response target port
        """
        self.usn = None
        """
UPnP USN
        """

        Settings.read_file("{0}/settings/pas_upnp.json".format(Settings.get("path_data")))

        self.announcement_divider = int(Settings.get("pas_upnp_announcement_divider", 3))
        self.announcement_interval = int(Settings.get("pas_upnp_announcement_interval", 3600))
        self.control_point = control_point
Ejemplo n.º 15
0
    def get_view(self):
        """
Action for "view"

:since: v1.0.0
        """

        cid = InputFilter.filter_file_path(self.request.get_parameter("cid", ""))

        source_iline = InputFilter.filter_control_chars(self.request.get_parameter("source", "")).strip()

        L10n.init("pas_http_core_contentfile")

        Settings.read_file("{0}/settings/pas_http_contentfiles.json".format(Settings.get("path_data")))

        contentfiles = Settings.get("pas_http_contentfiles_list", { })
        if (type(contentfiles) is not dict): raise TranslatableError("pas_http_core_contentfile_cid_invalid", 404)

        if (source_iline != ""):
            if (self.response.is_supported("html_css_files")): self.response.add_theme_css_file("mini_default_sprite.css")

            Link.set_store("servicemenu",
                           Link.TYPE_RELATIVE_URL,
                           L10n.get("core_back"),
                           { "__query__": re.sub("\\_\\_\\w+\\_\\_", "", source_iline) },
                           icon = "mini-default-back",
                           priority = 7
                          )
        #

        if (cid not in contentfiles
            or "title" not in contentfiles[cid]
            or "filepath" not in contentfiles[cid]
           ): raise TranslatableError("pas_http_core_contentfile_cid_invalid", 404)

        file_content = FileContent.read(contentfiles[cid]['filepath'])
        if (file_content is None): raise TranslatableError("pas_http_core_contentfile_cid_invalid", 404)

        if (path.splitext(contentfiles[cid]['filepath'])[1].lower() == ".ftg"): file_content = FormTags.render(file_content)

        content = { "title": contentfiles[cid]['title'],
                    "content": file_content
                  }

        self.response.init()
        self.response.page_title = contentfiles[cid]['title']

        self.response.add_oset_content("core.simple_content", content)
Ejemplo n.º 16
0
    def _parse_gst_caps_codec(self, caps, codec):
        """
Parses the GStreamer caps codec for a matching mimetype identifier.

:param caps: GStreamer caps dict
:param codec: GStreamer codec name

:return: (str) GStreamer codec / Mimetype identifier
:since:  v0.2.00
        """

        _return = codec

        if (type(caps) is dict and type(codec) is str):
            gst_mimetypes = Settings.get("pas_gapi_gstreamer_mimetypes", { })

            if (codec in gst_mimetypes):
                if (type(gst_mimetypes[codec]) is str): _return = gst_mimetypes[codec]
                else:
                    codec = self._parse_gst_caps_dependencies(caps, gst_mimetypes[codec])
                    if (codec is not None): _return = codec
                #
            #
        #

        return _return
    def _get_blake2_password(self, variant, password, username = None):
        """
Returns the BLAKE2 generated password hash.

:param password: User profile password
:param username: User name used while generating BLAKE2 hash

:return: (str) Hash on success; None if not supported
:since:  v0.2.00
        """

        blake2 = None
        blake2_person = None
        blake2_salt = None

        salt = Settings.get("pas_user_profile_password_salt")
        if (salt is None): raise ValueException("User profile password salt is not defined")

        if (variant == PasswordGeneratorsMixin.PASSWORD_TYPE_BLAKE2B):
            blake2 = blake2b
            blake2_salt = Binary.bytes(salt[:blake2b.SALT_SIZE])
            blake2_person = Binary.utf8_bytes(username[:blake2b.PERSON_SIZE])
        #

        if (variant == PasswordGeneratorsMixin.PASSWORD_TYPE_BLAKE2S):
            blake2 = blake2s
            blake2_salt = Binary.bytes(salt[:blake2s.SALT_SIZE])
            blake2_person = Binary.utf8_bytes(username[:blake2s.PERSON_SIZE])
        #

        if (blake2 is None): raise ValueException("BLAKE2 variant given is invalid")

        return blake2(Binary.utf8_bytes(password), salt = blake2_salt, person = blake2_person).hexdigest()
Ejemplo n.º 18
0
    def execute_index(self):
        """
Action for "index" (most likely root requested)

:since: v1.0.0
        """

        default_page_settings = Settings.get_lang_associated("pas_http_site_page_default", self.request.lang)

        if (type(default_page_settings) is not dict
            or ("module" not in default_page_settings
                and "service" not in default_page_settings
                and "action" not in default_page_settings
               )
           ): raise TranslatableError("pas_http_core_site_unconfigured", 201)

        redirect_request = PredefinedHttpRequest()

        if ("module" in default_page_settings): redirect_request.module_package = default_page_settings['module']
        if ("service" in default_page_settings): redirect_request.service_package_and_module = default_page_settings['service']
        if ("action" in default_page_settings): redirect_request.action = default_page_settings['action']

        if ("parameters" in default_page_settings): redirect_request.parameters = default_page_settings['parameters']

        self.request.redirect(redirect_request)
    def _handle_host_definition_headers(self, headers, default_host_definition_headers):
        """
Handles headers containing the server host name and port.

:param headers: Headers to search
:param default_host_definition_headers: Default list of HOST header names

:since: v1.0.0
        """

        host_definition_headers = Settings.get("pas_http_server_host_definition_headers",
                                               default_host_definition_headers
                                              )

        for host_definition_header in host_definition_headers:
            if (host_definition_header in headers):
                host_definition_header = host_definition_header.upper()

                host_parts = headers[host_definition_header].rsplit(":", 2)

                if (len(host_parts) < 2 or host_parts[1][-1:] == "]"): self._server_host = headers[host_definition_header]
                else:
                    self._server_host = host_parts[0]
                    if (self.server_port is None): self._server_port = int(host_parts[1])
                #

                del(headers[host_definition_header])
                break
Ejemplo n.º 20
0
    def __init__(self, db_instance = None):
        """
Constructor __init__(Uuids)

:since: v0.2.00
        """

        Abstract.__init__(self)

        if (db_instance is None): db_instance = _DbUuids()
        Instance.__init__(self, db_instance)

        self.session_time = int(Settings.get("pas_session_uuids_session_time", 900))
        """
Max age of the session
        """
        self.uuid = db_instance.uuid
        """
Database uuID used for reloading
        """
        self.validity = None
        """
Validity of the session
        """

        if (self.local.db_instance.data is not None and self.local.db_instance.data != ""): self.cache = JsonResource().json_to_data(self.local.db_instance.data)
        if (self.local.db_instance.session_timeout is None): self.local.db_instance.session_timeout = int(time() + self.session_time)
Ejemplo n.º 21
0
    def __init__(self):
        """
Constructor __init__(Multipart)

:since: v1.0.0
        """

        Data.__init__(self)

        self.parts = None
        """
Parts found in the "multipart/form_data" submission.
        """
        self.pending_buffer = None
        """
Currently receiving buffer.
        """
        self.pending_buffer_header_size_max = int(Settings.get("pas_http_site_request_body_multipart_pending_buffer_header_size_max", 65536))
        """
Maximum size in bytes for a part header
        """
        self.pending_mime_parts = [ ]
        """
MIME parts currently opened.
        """
        self.pending_received_data = None
        """
Data received but not yet completely parsed.
        """

        self.supported_features['body_parser'] = True
Ejemplo n.º 22
0
    def _get_default_list_condition_definition():
        """
Returns the default condition definition used for listings.

:return: (object) ConditionDefinition instance
:since:  v0.2.00
        """

        _return = ConditionDefinition()

        archive_timeout = int(Settings.get("pas_tasks_database_tasks_archive_timeout", 28)) * 86400
        completed_condition_definition = ConditionDefinition(ConditionDefinition.AND)
        timestamp = int(time())
        timestamp_archive = timestamp - archive_timeout

        completed_condition_definition.add_exact_match_condition("status", DatabaseTask.STATUS_COMPLETED)
        completed_condition_definition.add_greater_than_match_condition("time_scheduled", 0)
        completed_condition_definition.add_less_than_match_condition("time_scheduled", timestamp_archive)

        _return.add_sub_condition(completed_condition_definition)
        _return.add_exact_no_match_condition("status", DatabaseTask.STATUS_COMPLETED)

        _return.add_exact_match_condition("timeout", 0)
        _return.add_greater_than_match_condition("timeout", timestamp)

        return _return
Ejemplo n.º 23
0
    def _enter_context(self):
        """
Enters the connection context.

:since: v1.0.0
        """

        if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._enter_context()- (#echo(__LINE__)#)", self, context = "pas_database")

        self._ensure_thread_local()

        if (self.local.context_depth < 1):
            if (Connection.is_serialized()): Connection._serialized_lock.acquire()

            if (self._log_handler is not None
                and Settings.get("pas_database_threaded_debug", False)
               ): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._enter_context()- reporting: Connection acquired for thread ID {1:d}", self, current_thread().ident, context = "pas_database")
        #

        try:
            self._ensure_thread_local_session()
            self.local.context_depth += 1
        except Exception:
            if (self.local.context_depth < 1
                and Connection.is_serialized()
               ): Connection._serialized_lock.release()

            raise
Ejemplo n.º 24
0
    def is_preferred_defined(context = None):
        """
Returns true if a defined preferred URL exists for the given context.

:param context: Context for the preferred link

:return: (bool) True if defined
:since:  v0.2.00
        """

        url = None

        if (context is not None): url = Settings.get("pas_http_site_preferred_url_base_{0}".format(re.sub("\\W+", "_", context)))
        if (url is None): url = Settings.get("pas_http_site_preferred_url_base")

        return (url is not None)
Ejemplo n.º 25
0
    def schedule(self, wait_timeout = 0):
        """
Activates all relevant multicast listeners based on the IP address given.

:param wait_timeout: Time to wait before delivery

:since: v0.2.00
        """

        # pylint: disable=star-args

        if (self.type == ControlPointEvent.TYPE_DEVICE_ALIVE):
            event = ControlPointEvent(ControlPointEvent.TYPE_DEVICE_SHUTDOWN, control_point = self.control_point)
            if (self.configid is not None): event.set_configid(self.configid)
            event.set_usn(self.usn)
            event.deliver()
        elif (self.type == ControlPointEvent.TYPE_DEVICE_UPDATE
              and (not Settings.get("pas_upnp_ssdp_update_disabled", False))
             ):
            event = ControlPointEvent(ControlPointEvent.TYPE_DEVICE_SHUTDOWN, control_point = self.control_point)
            if (self.configid is not None): event.set_configid(self.configid)
            event.set_usn(self.usn)
            event.set_location(self.location)
            event.schedule()

            self.type = ControlPointEvent.TYPE_DEVICE_ALIVE
            if (wait_timeout < 0.3): wait_timeout = 0.3
        #

        AbstractEvent.schedule(self, wait_timeout)
Ejemplo n.º 26
0
    def _run_hook(self, **kwargs):
        """
Hook execution

:return: (mixed) Task result
:since:  v0.2.00
        """

        condition_definition = self._get_condition_definition()
        _return = MpEntry.get_entries_count_with_condition(condition_definition)

        limit = Settings.get("pas_database_delete_iterator_limit", 50)
        entry_iterator_count = ceil(_return / limit)

        LogLine.info("{0!r} removes {1:d} matches", self, _return, context = "mp_server")

        for _ in range(0, entry_iterator_count):
            with TransactionContext():
                entries = MpEntry.load_entries_list_with_condition(condition_definition, limit = limit)

                for entry in entries:
                    parent_entry = entry.load_parent()

                    if (isinstance(parent_entry, MpEntry)): parent_entry.remove_content(entry)
                    entry.delete()
                #
            #
        #

        return _return
Ejemplo n.º 27
0
    def _exit_context(self, exc_type, exc_value, traceback):
        """
Exits the connection context.

:since: v1.0.0
        """

        if (self._log_handler is not None): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._exit_context()- (#echo(__LINE__)#)", self, context = "pas_database")

        self.local.context_depth -= 1

        try:
            if (self.local.context_depth < 1):
                if (self.local.transactions > 0 and self._log_handler is not None):
                    self._log_handler.warning("{0!r} has active transactions ({1:d}) while exiting the connection context", self, self.local.transactions, context = "pas_database")
                #

                if (self.local.sa_session is not None):
                    if (exc_type is None and exc_value is None and self.local.sa_session.is_active): self.local.sa_session.commit()
                    else: self.local.sa_session.rollback()
                #

                self.local.transactions = 0

                if (self._log_handler is not None
                    and Settings.get("pas_database_threaded_debug", False)
                   ): self._log_handler.debug("#echo(__FILEPATH__)# -{0!r}._exit_context()- reporting: Cleared session instances for thread ID {1:d}", self, current_thread().ident, context = "pas_database")
            #
        #
        finally:
            if (Connection.is_serialized() and
                self.local.context_depth < 1
               ): Connection._serialized_lock.release()
Ejemplo n.º 28
0
    def _get_lmtp_connection(self):
        """
Returns an established LMTP connection.

:return: (object) LMTP connection
:since:  v1.0.0
        """

        smtp_options = { }
        if (Settings.is_defined("pas_smtp_client_sender_hostname")): smtp_options['local_hostname'] = Settings.get("pas_smtp_client_sender_hostname")

        _return = (LMTP(Settings.get("pas_smtp_client_lmtp_host"), int(Settings.get("pas_smtp_client_lmtp_port", 24)))
                   if (Settings.is_defined("pas_smtp_client_lmtp_host")) else
                   LMTP(Settings.get("pas_smtp_client_lmtp_path_name"))
                  )

        return _return
Ejemplo n.º 29
0
    def __init__(self):
        """
Constructor __init__(Client)

:since: v1.0.0
        """

        self._log_handler = NamedLoader.get_singleton("dNG.data.logging.LogHandler", False)
        """
The LogHandler is called whenever debug messages should be logged or errors
happened.
        """
        self._message = None
        """
e-mail message instance
        """
        self.timeout = 0
        """
Request timeout value
        """

        Settings.read_file("{0}/settings/pas_email.json".format(Settings.get("path_data")), True)
        Settings.read_file("{0}/settings/pas_smtp_client.json".format(Settings.get("path_data")), True)

        self.timeout = int(Settings.get("pas_smtp_client_timeout", 30))
Ejemplo n.º 30
0
    def _apply_form(self, form, document = None):
        """
Applies document form fields to given form instance.

:param form: Form instance
:param document: Document to get default data values from

:since: v0.2.00
        """

        document_data = ({ "title": None, "tag": None, "content": None, "description": None }
                         if (document is None) else
                         document.get_data_attributes("title", "tag", "content", "description")
                        )

        field = TextField("ctitle")
        field.set_title(L10n.get("pas_http_contentor_document_title"))
        field.set_value(document_data['title'])
        field.set_required()
        field.set_size(TextField.SIZE_LARGE)
        field.set_limits(int(Settings.get("pas_http_contentor_document_title_min", 3)))
        form.add(field)

        field = TextField("ctag")
        field.set_title(L10n.get("pas_http_contentor_document_tag"))
        field.set_value(document_data['tag'])
        field.set_size(TextField.SIZE_SMALL)
        field.set_limits(_max = 255)
        field.set_validators([ self._check_tag_unique ])
        form.add(field)

        field = FormTagsTextareaField("cdescription")
        field.set_title(L10n.get("pas_http_contentor_document_description"))
        field.set_value(document_data['description'])
        field.set_size(FormTagsTextareaField.SIZE_SMALL)
        field.set_limits(_max = 255)
        form.add(field)

        field = FormTagsTextareaField("ccontent")
        field.set_title(L10n.get("pas_http_contentor_document_content"))
        field.set_value(document_data['content'])
        field.set_required()
        field.set_size(FormTagsTextareaField.SIZE_LARGE)
        field.set_limits(int(Settings.get("pas_http_contentor_document_content_min", 6)))
        form.add(field)
Ejemplo n.º 31
0
def _ensure_administrative_user_account():
    """
Checks if at least one active administrative user profile exists. Creates
one if this is not the case.

:since: v0.2.00
    """

    cli = InteractiveCli.get_instance()
    cli.output_info("Validating administrative account ...")

    user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")

    if (next(user_profile_class.load_list(limit = 1, _type = "ad"), None) is not None): cli.output_info("Administrative account is available")
    else:
        cli.output_info("No valid administrative account found")

        Settings.read_file("{0}/settings/pas_user_profile.json".format(Settings.get("path_data")))
        password = "".join(choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for _ in range(20))
        password_encrypted = Tmd5.password_hash(password, Settings.get("pas_user_profile_password_salt"), "root")

        cli.output("")
        cli.output("A new default account will be generated.")
        cli.output("")
        cli.output("---------------------------------")
        cli.output("User name: root")
        cli.output("   e-mail: [email protected]")
        cli.output(" Password: {0}", password)
        cli.output("---------------------------------")
        cli.output("")
        cli.output("Please change this account as soon as possible.")
        cli.output("")

        user_profile = user_profile_class()

        user_profile.set_data_attributes(type = user_profile_class.get_type_int("ad"),
                                         name = "root",
                                         password = password_encrypted,
                                         locked = False,
                                         email = "*****@*****.**"
                                        )

        user_profile.save()
Ejemplo n.º 32
0
    def _generate_secid_value():
        """
Generates a list of "Security ID string elements" usually joined and saved
in a hashed form in a database.

:return: (generator) Security ID string element generator
:since:  v0.2.00
        """

        elements = int(Settings.get("pas_user_profile_secid_elements", 10))
        for _ in range(0, elements): yield "{0}{1:0>3d}".format(chr(randrange(65, 71)), randrange(1, 1000))
Ejemplo n.º 33
0
    def __init__(self, db_instance=None):
        """
Constructor __init__(Profile)

:since: v0.2.00
        """

        if (db_instance is None): db_instance = _DbUserProfile()

        AbstractProfile.__init__(self)
        Instance.__init__(self, db_instance)
        LockableMixin.__init__(self)
        PasswordGeneratorsMixin.__init__(self)

        self.db_id = (None if (db_instance is None) else self.get_id())
        """
Database ID used for reloading
        """

        Settings.read_file("{0}/settings/pas_user_profile.json".format(
            Settings.get("path_data")))

        self.supported_features['password_missed'] = True
    def _get_tmd5_password(self, password, username = None):
        """
Returns the triple MD5 generated password hash.

:param password: User profile password
:param username: User name used while generating the triple MD5 hash

:return: (str) Hash on success; None if not supported
:since:  v0.2.00
        """

        salt = Settings.get("pas_user_profile_password_salt")
        if (salt is None): raise ValueException("User profile password salt is not defined")

        return Tmd5.password_hash(password, salt, username)