Exemplo n.º 1
0
def after_apply_schema(params, last_return = None):
    """
Called for "dNG.pas.Database.applySchema.after"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

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

    if (issubclass(user_profile_class, Profile)):
        db_user_profile_class = NamedLoader.get_class("dNG.database.instances.UserProfile")
        Schema.apply_version(db_user_profile_class)

        cli = InteractiveCli.get_instance()

        if (isinstance(cli, InteractiveCli)
            and hasattr(cli, "is_cli_setup")
            and cli.is_cli_setup()
           ): _ensure_administrative_user_account()
    #

    return last_return
Exemplo n.º 2
0
def load_all(params, last_return = None):
    """
Load and register all SQLAlchemy objects to generate database tables.

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:since: v0.1.00
    """

    NamedLoader.get_class("dNG.database.instances.FileCenterEntry")

    return last_return
Exemplo n.º 3
0
def load_all(params, last_return = None):
    """
Load and register all SQLAlchemy objects to generate database tables.

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    NamedLoader.get_class("dNG.database.instances.DataLinker")
    NamedLoader.get_class("dNG.database.instances.DataLinkerMeta")

    return last_return
Exemplo n.º 4
0
def load_all(params, last_return = None):
    """
Load and register all SQLAlchemy objects to generate database tables.

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
    if (issubclass(user_profile_class, Profile)): NamedLoader.get_class("dNG.database.instances.UserProfile")

    return last_return
Exemplo n.º 5
0
def delete(params, last_return=None):
    """
Called for "dNG.pas.user.Profile.delete"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    # pylint: disable=star-args

    if ("username" not in params):
        raise ValueException("Missing required argument")
    else:
        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")

        try:
            user_profile = user_profile_class.load_username(params['username'])

            Hook.call("dNG.pas.user.Profile.onDelete",
                      user_profile_id=user_profile.get_id())
            user_profile.delete()
        except NothingMatchedException:
            pass
    #

    return last_return
Exemplo n.º 6
0
def delete(params, last_return = None):
    """
Called for "dNG.pas.user.Profile.delete"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    # pylint: disable=star-args

    if ("username" not in params): raise ValueException("Missing required argument")
    else:
        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")

        try:
            user_profile = user_profile_class.load_username(params['username'])

            Hook.call("dNG.pas.user.Profile.onDelete", user_profile_id = user_profile.get_id())
            user_profile.delete()
        except NothingMatchedException: pass
    #

    return last_return
Exemplo n.º 7
0
    def _get_user_profile(self, user_id):
        """
Returns the user profile instance for the given user ID.

:param user_id: User ID

:return: (object) User profile instance; None if not found
:since:  v0.2.00
        """

        _return = None

        if (user_id is not None):
            _return = self.permission_user_profile_cache.get(user_id)

            if (_return is None):
                user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")

                _return = (None if (user_profile_class is None) else user_profile_class.load_id(user_id))
                if (_return is not None): self.permission_user_profile_cache[user_id] = _return
            #

            if (_return is not None and (not _return.is_valid())): _return = None
        #

        return _return
def after_apply_schema(params, last_return = None):
    """
Called for "dNG.pas.Database.applySchema.after"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    acl_entry_class = NamedLoader.get_class("dNG.database.instances.AclEntry")
    Schema.apply_version(acl_entry_class)

    permission_class = NamedLoader.get_class("dNG.database.instances.Permission")
    Schema.apply_version(permission_class)

    return last_return
Exemplo n.º 9
0
def after_apply_schema(params, last_return = None):
    """
Called for "dNG.pas.Database.applySchema.after"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    category_class = NamedLoader.get_class("dNG.database.instances.ContentorCategory")
    Schema.apply_version(category_class)

    document_class = NamedLoader.get_class("dNG.database.instances.ContentorDocument")
    Schema.apply_version(document_class)

    return last_return
Exemplo n.º 10
0
def after_apply_schema(params, last_return = None):
    """
Called for "dNG.pas.Database.applySchema.after"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    datalinker_class = NamedLoader.get_class("dNG.database.instances.DataLinker")
    Schema.apply_version(datalinker_class)

    datalinker_meta_class = NamedLoader.get_class("dNG.database.instances.DataLinkerMeta")
    Schema.apply_version(datalinker_meta_class)

    return last_return
Exemplo n.º 11
0
def before_apply_schema(params, last_return = None):
    """
Called for "dNG.pas.Database.applySchema.before"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    audio_class = NamedLoader.get_class("dNG.database.instances.MpUpnpAudioResource")
    if (audio_class is not None): audio_class.before_apply_schema()

    image_class = NamedLoader.get_class("dNG.database.instances.MpUpnpImageResource")
    if (image_class is not None): image_class.before_apply_schema()

    video_class = NamedLoader.get_class("dNG.database.instances.MpUpnpVideoResource")
    if (video_class is not None): video_class.before_apply_schema()

    return last_return
Exemplo n.º 12
0
def after_apply_schema(params, last_return = None):
#
	"""
Called for "dNG.pas.Database.applySchema.after"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.1.00
	"""

	list_class = NamedLoader.get_class("dNG.database.instances.DiscussList")
	Schema.apply_version(list_class)

	topic_class = NamedLoader.get_class("dNG.database.instances.DiscussTopic")
	Schema.apply_version(topic_class)

	post_class = NamedLoader.get_class("dNG.database.instances.DiscussPost")
	Schema.apply_version(post_class)

	return last_return
Exemplo n.º 13
0
    def run(self):
        """
Task execution

:since: v0.2.00
        """

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

        user_profile = user_profile_class.load_username(self.username)

        original_user_profile_data = user_profile.get_data_attributes(*self.values_changed.keys())

        user_profile.set_data_attributes(**self.values_changed)
        user_profile.save()

        DatabaseTasksProxy.get_instance().add("dNG.pas.user.Profile.onEdited.{0}".format(self.username),
                                              "dNG.pas.user.Profile.onEdited",
                                              1,
                                              user_profile_id = user_profile.get_id(),
                                              user_profile_data_changed = self.values_changed,
                                              original_user_profile_data = original_user_profile_data
                                             )

        task_data = DatabaseTasks.get_instance().get(self.vid)

        if (task_data is not None and "_task" in task_data):
            task_data['_task'].set_status_completed()
            task_data['_task'].save()
        #

        user_profile_data = user_profile.get_data_attributes("id", "name", "lang")

        L10n.init("core", user_profile_data['lang'])
        L10n.init("pas_core", user_profile_data['lang'])
        L10n.init("pas_http_user", user_profile_data['lang'])

        l10n = L10n.get_instance(user_profile_data['lang'])

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

        _return.set_parameter_chained("title", l10n.get("pas_http_user_title_change_profile"))
        _return.set_parameter_chained("message", l10n.get("pas_http_user_done_change_profile"))
        _return.set_parameter_chained("lang", l10n.get_lang())
        _return.set_parameter_chained("target_iline", "m=user;s=profile;lang={0};dsd=upid+{1}".format(user_profile_data['lang'], user_profile_data['id']))

        return _return
Exemplo n.º 14
0
def load_all(params, last_return = None):
    """
Load and register all SQLAlchemy objects to generate database tables.

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:since: v0.2.00
    """

    NamedLoader.get_class("dNG.database.instances.MpUpnpAudioResource")
    NamedLoader.get_class("dNG.database.instances.MpUpnpImageResource")
    NamedLoader.get_class("dNG.database.instances.MpUpnpResource")
    NamedLoader.get_class("dNG.database.instances.MpUpnpVideoResource")

    return last_return
Exemplo n.º 15
0
    def run(self):
        """
Task execution

:since: v0.2.00
        """

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

        user_profile = user_profile_class.load_username(self.username)
        user_profile.unlock()
        user_profile.save()

        database_tasks_proxy = DatabaseTasksProxy.get_instance()

        database_tasks_proxy.add("dNG.pas.user.Profile.updateSecID.{0}".format(self.username),
                                 "dNG.pas.user.Profile.updateSecID",
                                 1,
                                 username = self.username
                                )

        database_tasks_proxy.remove("dNG.pas.user.Profile.delete.{0}".format(self.username))

        task_data = DatabaseTasks.get_instance().get(self.vid)

        if (task_data is not None and "_task" in task_data):
            task_data['_task'].set_status_completed()
            task_data['_task'].save()
        #

        user_profile_data = user_profile.get_data_attributes("name", "lang")

        L10n.init("core", user_profile_data['lang'])
        L10n.init("pas_core", user_profile_data['lang'])
        L10n.init("pas_http_user", user_profile_data['lang'])

        l10n = L10n.get_instance(user_profile_data['lang'])

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

        _return.set_parameter_chained("title", l10n.get("pas_http_user_title_registration"))
        _return.set_parameter_chained("message", l10n.get("pas_http_user_done_registration"))
        _return.set_parameter_chained("lang", l10n.get_lang())
        _return.set_parameter_chained("target_iline", "m=user;s=status;a=login;lang={0}".format(user_profile_data['lang']))

        return _return
Exemplo n.º 16
0
def after_apply_schema(params, last_return = None):
    """
Called for "dNG.pas.Database.applySchema.after"

:param params: Parameter specified
:param last_return: The return value from the last hook called.

:return: (mixed) Return value
:since:  v0.2.00
    """

    resource_class = NamedLoader.get_class("dNG.database.instances.MpUpnpResource")
    Schema.apply_version(resource_class)

    audio_class = NamedLoader.get_class("dNG.database.instances.MpUpnpAudioResource")
    Schema.apply_version(audio_class)

    image_class = NamedLoader.get_class("dNG.database.instances.MpUpnpImageResource")
    Schema.apply_version(image_class)

    video_class = NamedLoader.get_class("dNG.database.instances.MpUpnpVideoResource")
    Schema.apply_version(video_class)

    return last_return
Exemplo n.º 17
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()
    def run(self):
        """
Task execution

:since: v0.2.00
        """

        if (self.__class__.EMAIL_RENDERER is None): raise ValueException("Defined e-mail renderer is invalid")

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        user_profile = user_profile_class.load_username(self.username)

        user_profile_data = user_profile.get_data_attributes("name", "lang", "email")

        email = self.get_email_recipient()
        if (email is None): email = user_profile_data['email']

        L10n.init("core", user_profile_data['lang'])
        L10n.init("pas_core", user_profile_data['lang'])
        L10n.init("pas_http_user", user_profile_data['lang'])

        l10n = L10n.get_instance(user_profile_data['lang'])

        email_renderer = NamedLoader.get_instance(self.__class__.EMAIL_RENDERER, l10n = l10n)
        content = email_renderer.render(user_profile_data, self.vid, self.vid_timeout_days)

        subject = self.get_email_subject(l10n)
        if (subject is None): subject = l10n.get("pas_http_user_title_verification")

        part = Part(Part.TYPE_MESSAGE_BODY, "text/plain", content)

        message = Message()
        message.add_body(part)
        message.set_subject(subject)
        message.set_to(Message.format_address(user_profile_data['name'], email))

        smtp_client = SmtpClient()
        smtp_client.set_message(message)
        smtp_client.send()
Exemplo n.º 19
0
    def get_executing_class(is_not_implemented_class_aware = False):
        """
Returns the persistent tasks implementation class responsible for scheduling
and execution based on the configuration set.

:param is_not_implemented_class_aware: True to return
       "dNG.runtime.NotImplementedClass" instead of None

:return: (object) Tasks implementation class; None if not 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")))
        #

        implementation_class_name = Settings.get("pas_tasks_persistent_implementation", "Database")

        _return = NamedLoader.get_class("dNG.data.tasks.{0}".format(implementation_class_name))
        if (_return is None and is_not_implemented_class_aware): _return = NotImplementedClass

        return _return
Exemplo n.º 20
0
    def run(self):
        """
Task execution

:since: v0.2.00
        """

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        user_profile = user_profile_class.load_username(self.username)

        secid = user_profile_class.generate_secid()
        secid_hashed = Tmd5.password_hash(re.sub("\\W+", "", secid), Settings.get("pas_user_profile_password_salt"), self.username)

        user_profile.set_data_attributes(secid = secid_hashed)
        user_profile.save()

        user_profile_data = user_profile.get_data_attributes("name", "lang", "email")

        L10n.init("core", user_profile_data['lang'])
        L10n.init("pas_core", user_profile_data['lang'])
        L10n.init("pas_http_user", user_profile_data['lang'])

        l10n = L10n.get_instance(user_profile_data['lang'])

        email_renderer = NamedLoader.get_instance("dNG.data.text.user.SecIDUpdatedEMailRenderer", l10n = l10n)
        content = email_renderer.render(user_profile_data, secid)
        subject = l10n.get("pas_http_user_title_sec_id_updated")

        part = Part(Part.TYPE_MESSAGE_BODY, "text/plain", content)

        message = Message()
        message.add_body(part)
        message.set_subject(subject)
        message.set_to(Message.format_address(user_profile_data['name'], user_profile_data['email']))

        smtp_client = SmtpClient()
        smtp_client.set_message(message)
        smtp_client.send()
Exemplo n.º 21
0
    def _add_default_parameters(self, parameters):
        """
This method appends default parameters if not already set.

:param parameters: Parameters dict

:return: (dict) Appended parameters dict
:since:  v0.2.00
        """

        _return = _Link._add_default_parameters(self, parameters)

        if ("theme" not in _return):
            response = HttpXhtmlResponse.get_instance()

            if (isinstance(response, HttpXhtmlResponse)):
                default_theme = NamedLoader.get_class("dNG.data.xhtml.theme.Renderer").get_default_theme()
                theme = response.get_theme()

                if (theme is not None and theme != default_theme): _return['theme'] = theme
            #
        #

        return _return
Exemplo n.º 22
0
    def get_user_profile(self):
        """
Returns the user profile set for the session.

:return: (mixed) User Profile; None if not set
:since:  v0.2.00
        """

        # pylint: disable=broad-except

        _return = None

        try:
            if (self.user_profile is not None): _return = self.user_profile
            else:
                user_id = self.get_user_id()
                user_profile = None

                try:
                    if (user_id is not None):
                        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
                        if (user_profile_class is not None): user_profile = user_profile_class.load_id(user_id)
                    #
                except NothingMatchedException: pass

                if (user_profile is not None and user_profile.is_valid()):
                    self.user_profile = user_profile
                    _return = self.user_profile
                #
            #
        except Exception as handled_exception:
            LogLine.error(handled_exception, context = "pas_session")
            _return = None
        #

        return _return
Exemplo n.º 23
0
    def _check_username_not_registered(self, field, validator_context):
        """
Form validator that checks if the user name is not already registered.

:param field: Form field
:param validator_context: Form validator context

:return: (str) Error message; None on success
:since:  v0.2.00
        """

        _return = None

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

        if (user_profile_class is None): _return = L10n.get("pas_http_core_form_error_internal_error")
        else:
            try:
                user_profile_class.load_username(InputFilter.filter_control_chars(field.get_value()), True)
                _return = L10n.get("pas_http_user_form_error_username_exists")
            except NothingMatchedException: pass
        #

        return _return
Exemplo n.º 24
0
    def get_class(cls, is_not_implemented_class_aware = False):
        """
Returns an media implementation class based on the configuration set.

:param cls: Python class
:param is_not_implemented_class_aware: True to return
       "dNG.runtime.NotImplementedClass" instead of None

:return: (object) Media implementation class; None if not available
:since:  v0.2.00
        """

        # pylint: disable=assignment-from-no-return

        implementation_class_name = cls._get_implementation_class_name()

        _return = (None
                   if (implementation_class_name == "") else
                   NamedLoader.get_class("dNG.data.media.{0}".format(implementation_class_name))
                  )

        if (_return is None and is_not_implemented_class_aware): _return = NotImplementedClass

        return _return
Exemplo n.º 25
0
    def execute_edit(self, is_save_mode = False):
        """
Action for "edit"

:since: v0.2.00
        """

        pid = InputFilter.filter_file_path(self.request.get_dsd("upid", ""))

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

        source = source_iline
        if (source_iline == ""): source_iline = "m=user;s=profile;dsd=upid+{0}".format(Link.encode_query_value(pid))

        target = target_iline
        if (target_iline == ""): target_iline = source_iline

        L10n.init("pas_http_user")

        session = (self.request.get_session() if (self.request.is_supported("session")) else None)

        session_user_is_administrator = False
        session_user_pid = None
        session_user_profile = None

        if (session is not None):
            session_user_pid = session.get_user_id()
            session_user_profile = session.get_user_profile()

            if (session_user_profile is not None):
                if (session_user_profile.is_valid()): session_user_is_administrator = session_user_profile.is_type("ad")
                if (pid == ""): pid = session_user_pid
            #
        #

        if (pid == ""): raise TranslatableError("pas_http_user_pid_invalid", 404)

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        if (user_profile_class is None): raise TranslatableException("core_unknown_error")

        try: user_profile = user_profile_class.load_id(pid)
        except NothingMatchedException as handled_exception: raise TranslatableError("pas_http_user_pid_invalid", 404, _exception = handled_exception)

        if ((not session_user_is_administrator)
            and (pid != session_user_pid or (not user_profile.is_valid()))
           ): raise TranslatableError("core_access_denied", 403)

        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
                      )

        edit_source = ("m=user;s=profile;a=edit;dsd=upid+{0}".format(Link.encode_query_value(pid)) if (source == "") else source)

        if (not user_profile.is_type("ex")):
            Link.set_store("servicemenu",
                           Link.TYPE_RELATIVE_URL,
                           (L10n.get("pas_http_user_change_username_or_password")
                            if (Settings.get("pas_http_user_change_username_allowed", True)) else
                            L10n.get("pas_http_user_change_password")
                           ),
                           { "m": "user", "s": "profile", "a": "change-username-password", "dsd": { "source": edit_source, "target": target } },
                           icon = "mini-default-option",
                           priority = 3
                          )

            if (not session_user_is_administrator):
                Link.set_store("servicemenu",
                               Link.TYPE_RELATIVE_URL,
                               L10n.get("pas_http_user_change_email"),
                               { "m": "user", "s": "profile", "a": "change-email", "dsd": { "source": edit_source, "target": target } },
                               icon = "mini-default-option",
                               priority = 3
                              )
            #
        elif (Settings.get("pas_http_user_change_username_allowed", True)):
            Link.set_store("servicemenu",
                           Link.TYPE_RELATIVE_URL,
                           L10n.get("pas_http_user_change_username"),
                           { "m": "user", "s": "profile", "a": "change-username", "dsd": { "source": edit_source, "target": target } },
                           icon = "mini-default-option",
                           priority = 3
                          )
        #

        if (not DatabaseTasks.is_available()): raise TranslatableException("pas_core_tasks_daemon_not_available")

        form_id = InputFilter.filter_control_chars(self.request.get_parameter("form_id"))

        form = FormProcessor(form_id)

        user_profile_data = user_profile.get_data_attributes("name", "email", "signature", "title")

        email = user_profile_data['email']
        title = user_profile_data['title']

        if (is_save_mode): form.set_input_available()

        if (session_user_is_administrator):
            field = EMailField("uemail")
            field.set_title(L10n.get("pas_http_user_email"))
            field.set_value(email)
            field.set_required()
            field.set_limits(_max = 255)
            form.add(field)
        else:
            field = InfoField("uemail")
            field.set_title(L10n.get("pas_http_user_email"))
            field.set_value(email)
            form.add(field)
        #

        field = FormTagsTextareaField("usignature")
        field.set_title(L10n.get("pas_http_user_signature"))
        field.set_value(user_profile_data['signature'])
        field.set_size(FormTagsTextareaField.SIZE_SMALL)
        field.set_limits(_max = 255)
        form.add(field)

        if (session_user_is_administrator):
            field = FormTagsTextField("utitle")
            field.set_title(L10n.get("pas_http_user_title"))
            field.set_value(title)
            field.set_limits(_max = 255)
            form.add(field)
        #

        if (is_save_mode and form.check()):
            if (session_user_is_administrator): email = InputFilter.filter_control_chars(form.get_value("uemail"))
            signature = InputFilter.filter_control_chars(form.get_value("usignature"))
            if (session_user_is_administrator): title = InputFilter.filter_control_chars(form.get_value("utitle"))

            original_user_profile_data = user_profile_data.copy()
            user_profile_data_changed = { "signature": FormTags.encode(signature) }

            if (session_user_is_administrator):
                user_profile_data_changed['email'] = email
                user_profile_data_changed['title'] = FormTags.encode(title)
            #

            user_profile.set_data_attributes(**user_profile_data_changed)
            user_profile.save()

            DatabaseTasks.get_instance().add("dNG.pas.user.Profile.onEdited.{0}".format(user_profile_data['name']),
                                             "dNG.pas.user.Profile.onEdited",
                                             1,
                                             user_profile_id = pid,
                                             user_profile_data_changed = user_profile_data_changed,
                                             original_user_profile_data = original_user_profile_data
                                            )

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

            NotificationStore.get_instance().add_completed_info(L10n.get("pas_http_user_done_change_profile"))

            Link.clear_store("servicemenu")

            redirect_request = PredefinedHttpRequest()
            redirect_request.set_iline(target_iline)
            self.request.redirect(redirect_request)
        else:
            content = { "title": L10n.get("pas_http_user_title_change_profile") }

            content['form'] = { "object": form,
                                "url_parameters": { "__request__": True,
                                                    "a": "edit-save",
                                                    "dsd": { "source": source, "target": target }
                                                  },
                                "button_title": "pas_http_core_edit"
                              }

            self.response.init()
            self.response.set_title(content['title'])
            self.response.add_oset_content("core.form", content)
Exemplo n.º 26
0
    def execute_view(self):
        """
Action for "view"

:since: v0.2.00
        """

        pid = InputFilter.filter_file_path(self.request.get_dsd("upid", ""))

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

        source = source_iline
        if (source_iline == ""): source_iline = "m=user;a=services"

        L10n.init("pas_http_user")

        session = (self.request.get_session() if (self.request.is_supported("session")) else None)

        session_user_is_administrator = False
        session_user_pid = None
        session_user_profile = None

        if (session is not None):
            session_user_pid = session.get_user_id()
            session_user_profile = session.get_user_profile()

            if (session_user_profile is not None and session_user_profile.is_valid()):
                session_user_is_administrator = session_user_profile.is_type("ad")
                if (pid == ""): pid = session_user_pid
            else: session_user_pid = None
        #

        if (pid == ""): raise TranslatableError("pas_http_user_pid_invalid", 404)

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        if (user_profile_class is None): raise TranslatableException("core_unknown_error")

        try: user_profile = user_profile_class.load_id(pid)
        except NothingMatchedException as handled_exception: raise TranslatableError("pas_http_user_pid_invalid", 404, _exception = handled_exception)

        if (user_profile.is_deleted()): raise TranslatableError("pas_http_user_pid_invalid", 404)

        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 (session_user_pid is not None):
            Link.set_store("servicemenu",
                           Link.TYPE_RELATIVE_URL,
                           L10n.get("pas_http_user_profile_edit"),
                           { "m": "user", "s": "profile", "a": "edit", "dsd": { "source": source } },
                           icon = "mini-default-option",
                           priority = 3
                          )
        #

        user_profile_data = user_profile.get_data_attributes("type",
                                                             "name",
                                                             "email",
                                                             "email_public",
                                                             "title",
                                                             "signature",
                                                             "registration_ip",
                                                             "registration_time",
                                                             "lastvisit_ip",
                                                             "lastvisit_time"
                                                            )

        view = FormView()

        if (user_profile_data['email'] != ""
            and session_user_profile is not None
            and session_user_profile.is_valid()
           ):
            field = InfoField("uemail")
            field.set_title(L10n.get("pas_http_user_email"))

            if (session_user_is_administrator or user_profile_data['email_public']): field.set_value(user_profile_data['email'])
            else: field.set_value(L10n.get("pas_http_user_send_email"))

            field.set_link(Link().build_url(Link.TYPE_RELATIVE_URL,
                                            { "m": "user", "s": "email", "dsd": { "upid": pid } }
                                           )
                          )

            view.add(field)
        #

        if (user_profile_data['registration_time'] > 0):
            field = InfoField("uregistration_time")
            field.set_title(L10n.get("pas_http_user_registration_time"))
            field.set_value(DateTime.format_l10n(DateTime.TYPE_DATE_TIME_SHORT, user_profile_data['registration_time']))
            view.add(field)

            if (session_user_is_administrator and user_profile_data['registration_ip'] != ""):
                field = InfoField("uregistration_ip")
                field.set_title(L10n.get("pas_http_user_registration_ip"))
                field.set_value(user_profile_data['registration_ip'])
                view.add(field)
            #
        #

        if (user_profile_data['lastvisit_time'] > 0):
            field = InfoField("ulastvisit_time")
            field.set_title(L10n.get("pas_http_user_lastvisit_time"))
            field.set_value(DateTime.format_l10n(DateTime.TYPE_DATE_TIME_SHORT, user_profile_data['lastvisit_time']))
            view.add(field)

            if (session_user_is_administrator and user_profile_data['lastvisit_ip'] != ""):
                field = InfoField("ulastvisit_ip")
                field.set_title(L10n.get("pas_http_user_lastvisit_ip"))
                field.set_value(user_profile_data['lastvisit_ip'])
                view.add(field)
            #
        #

        content = { "title": user_profile_data['name'],
                    "username": user_profile_data['name'],
                    "usertitle": user_profile_data['title'],
                    "signature": user_profile_data['signature'],
                    "details_form_view": { "object": view }
                  }

        self.response.init()
        self.response.set_title(user_profile_data['name'])
        self.response.add_oset_content("user.profile", content)
Exemplo n.º 27
0
    def execute_login(self, is_save_mode = False):
        """
Action for "login"

: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()

        source = source_iline
        if (source_iline == ""): source_iline = "m=user;a=services"

        target = target_iline

        if (target_iline == ""):
            if (Settings.is_defined("pas_http_user_login_default_target_lang_{0}".format(self.request.get_lang()))): target_iline = Settings.get("pas_http_user_login_default_target_lang_{0}".format(self.request.get_lang()))
            elif (Settings.is_defined("pas_http_user_login_default_target")): target_iline = Settings.get("pas_http_user_login_default_target")
            elif (source == ""): target_iline = "m=user;a=services;lang=__lang__;theme=__theme__"
            else: target_iline = source_iline
        #

        L10n.init("pas_http_core_form")
        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)

        is_cookie_supported = Settings.get("pas_http_site_cookies_supported", True)

        if (is_cookie_supported
            and type(Settings.get("pas_http_user_alternative_login_services_list")) is list
           ):
            Link.set_store("servicemenu",
                           Link.TYPE_RELATIVE_URL,
                           L10n.get("pas_http_user_alternative_login_methods_view"),
                           { "__request__": True, "a": "login-alternatives-list", "dsd": { "source": source, "target": target } },
                           icon = "mini-default-option",
                           priority = 3
                          )
        #

        form_id = InputFilter.filter_control_chars(self.request.get_parameter("form_id"))

        form = FormProcessor(form_id)
        if (is_save_mode): form.set_input_available()

        field = TextField("uusername")
        field.set_title(L10n.get("pas_core_username"))
        field.set_placeholder(L10n.get("pas_http_core_form_case_sensitive_placeholder"))
        field.set_required()
        field.set_limits(int(Settings.get("pas_http_core_username_min", 3)), 100)
        field.set_size(TextField.SIZE_SMALL)
        form.add(field)

        field = PasswordField("upassword")
        field.set_title(L10n.get("pas_http_user_password"))
        field.set_required()
        field.set_limits(int(Settings.get("pas_http_user_password_min", 6)))
        field.set_mode(PasswordField.PASSWORD_CLEARTEXT)
        form.add(field)

        if (is_cookie_supported):
            cookie_choices = [ { "value": "1", "title": L10n.get("core_yes") },
                               { "value": "0", "title": L10n.get("core_no") }
                             ]

            field = RadioField("ucookie")
            field.set_title(L10n.get("pas_http_user_login_use_cookie"))
            field.set_value("1")
            field.set_choices(cookie_choices)
            field.set_required()
            form.add(field)
        #

        if (is_save_mode and form.check()):
            username = InputFilter.filter_control_chars(form.get_value("uusername"))
            password = InputFilter.filter_control_chars(form.get_value("upassword"))

            user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
            if (user_profile_class is None): raise TranslatableException("core_unknown_error")

            try: user_profile = user_profile_class.load_username(username)
            except NothingMatchedException as handled_exception: raise TranslatableError("pas_http_user_username_or_password_invalid", 403, _exception = handled_exception)

            user_profile_data = user_profile.get_data_attributes("id", "lang", "theme")

            if (user_profile.is_banned()): raise TranslatableError("pas_http_user_profile_banned", 403)
            if (user_profile.is_locked()): raise TranslatableError("pas_http_user_profile_locked", 403)
            if (user_profile.is_type("ex")): raise TranslatableError("pas_http_user_feature_not_available_for_external_verified_member", 403)

            if ((not user_profile.is_valid())
                or (not user_profile.is_password_valid(password))
               ): raise TranslatableError("pas_http_user_username_or_password_invalid", 403)

            session = Session.load()
            session.set("session.user_id", user_profile_data['id'])
            session.set_cookie(is_cookie_supported and form.get_value("ucookie") == "1")
            session.save()

            self.request.set_session(session)

            target_iline = target_iline.replace("__lang__", user_profile_data['lang'])
            target_iline = target_iline.replace("__theme__", user_profile_data['theme'])
            target_iline = re.sub("\\_\\_\\w+\\_\\_", "", target_iline)

            NotificationStore.get_instance().add_completed_info(L10n.get("pas_http_user_done_login"))

            Link.clear_store("servicemenu")

            redirect_request = PredefinedHttpRequest()
            redirect_request.set_iline(target_iline)
            self.request.redirect(redirect_request)
        else:
            content = { "title": L10n.get("pas_http_user_title_login") }

            content['form'] = { "object": form,
                                "url_parameters": { "__request__": True, "a": "login-save", "dsd": { "source": source, "target": target } },
                                "button_title": "pas_core_login"
                              }

            self.response.init()
            self.response.set_title(content['title'])
            self.response.add_oset_content("user.status.login", content)
Exemplo n.º 28
0
    def _thread_run(self):
        """
Active conversation

:since: v0.2.00
        """

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

        ssdp_data = self.get_data(65535)

        headers = (None if (ssdp_data == "") else HttpClient.get_headers(ssdp_data))
        ssdp_request = None

        if (headers is not None and "@http" in headers):
            ssdp_request_data = headers['@http'].split(" ", 2)

            if (len(ssdp_request_data) > 2 and ssdp_request_data[2].startswith("HTTP/")):
                ssdp_request = ssdp_request_data[0].upper()
                ssdp_request_path = ssdp_request_data[1]

                http_version = float(ssdp_request_data[2].split("/", 1)[1])
            #
        #

        if (ssdp_request == "NOTIFY" and ssdp_request_path == "*" and "NT" in headers and "NTS" in headers and "USN" in headers):
            bootid = (int(headers['BOOTID.UPNP.ORG']) if ("BOOTID.UPNP.ORG" in headers) else None)
            configid = (int(headers['CONFIGID.UPNP.ORG']) if ("CONFIGID.UPNP.ORG" in headers) else None)
            control_point = NamedLoader.get_singleton("dNG.net.upnp.ControlPoint")
            user_agent = headers.get("SERVER")

            client_settings = ClientSettings(user_agent)

            if (client_settings.get("ssdp_notify_use_filter", False)):
                headers_filtered = Hook.call("dNG.pas.upnp.SsdpRequest.filterHeaders", headers = headers, user_agent = user_agent)
                if (headers_filtered is not None): headers = headers_filtered
            #

            if (headers['NTS'] == "ssdp:alive" or headers['NTS'] == "ssdp:update"):
                if ("CACHE-CONTROL" in headers and "LOCATION" in headers and "SERVER" in headers):
                    bootid_old = None

                    if (headers['NTS'] == "ssdp:update"):
                        bootid = (int(headers['NEXTBOOTID.UPNP.ORG']) if ("NEXTBOOTID.UPNP.ORG" in headers) else None)
                        bootid_old = (int(headers['BOOTID.UPNP.ORG']) if ("BOOTID.UPNP.ORG" in headers) else None)
                    #

                    re_result = SsdpRequest.RE_HEADER_MAX_AGE.search(headers['CACHE-CONTROL'])
                    unicast_port = (int(headers['SEARCHPORT.UPNP.ORG']) if ("SEARCHPORT.UPNP.ORG" in headers) else None)

                    if (re_result is not None): control_point.update_usn(headers['SERVER'], headers['USN'], bootid, bootid_old, configid, int(re_result.group(2)), unicast_port, http_version, headers['LOCATION'], headers)
                    elif (self.log_handler is not None): self.log_handler.debug("{0!r} ignored broken NOTIFY CACHE-CONTROL '{1}'", self, headers['CACHE-CONTROL'], context = "pas_upnp")
                elif (self.log_handler is not None): self.log_handler.debug("{0!r} ignored incomplete NOTIFY {1!r}", self, headers, context = "pas_upnp")
            elif (headers['NTS'] == "ssdp:byebye"): control_point.delete_usn(headers['USN'], bootid, configid, headers)
            elif (self.log_handler is not None): self.log_handler.debug("{0!r} received unknown NOTIFY {1!r}", self, headers, context = "pas_upnp")
        elif (ssdp_request == "M-SEARCH" and ssdp_request_path == "*" and "MAN" in headers and headers['MAN'].strip("\"") == "ssdp:discover" and "ST" in headers):
            wait_timeout = (int(headers['MX']) if ("MX" in headers) else 1)
            if (wait_timeout > 5): wait_timeout = 5

            ssdp_search_class = NamedLoader.get_class("dNG.net.upnp.SsdpSearch")
            ssdp_search_class.handle_request(self.address, wait_timeout, headers['ST'], headers)
Exemplo n.º 29
0
    def _execute_register(self, username = None, email = None, ex_type = None, source_iline = "", target_iline = "", is_save_mode = False):
        """
Action for "register"

:param username: User name to be used
:param email: Verified e-mail address to be used
:param ex_type: Externally verified service identifier string
:param source_iline: Source URI query string
:param target_iline: Target URI query string
:param is_save_mode: True if the form is submitted

:since: v0.2.00
        """

        # pylint: disable=star-args

        source = source_iline
        if (source_iline == ""): source_iline = "m=user;a=services"

        target = target_iline

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

        L10n.init("pas_http_core_form")
        L10n.init("pas_http_user")

        if (not Settings.get("pas_http_user_registration_allowed", True)): raise TranslatableError("pas_http_user_registration_disabled", 403)

        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 DatabaseTasks.is_available()): raise TranslatableException("pas_core_tasks_daemon_not_available")

        form_id = InputFilter.filter_control_chars(self.request.get_parameter("form_id"))

        form = FormProcessor(form_id)
        if (is_save_mode): form.set_input_available()

        is_email_verified = (email is not None)

        if (not is_email_verified):
            field = EMailField("uemail")
            field.set_title(L10n.get("pas_http_user_email"))
            field.set_required()
            field.set_limits(_max = 255)
            field.set_validators([ self._check_email_not_registered ])
            form.add(field)
        #

        if (username is None):
            field = TextField("uusername")
            field.set_required()
            field.set_limits(int(Settings.get("pas_http_core_username_min", 3)), 100)
            field.set_size(TextField.SIZE_SMALL)
        else:
            field = InfoField("uusername")
            field.set_value(username)
        #

        field.set_title(L10n.get("pas_core_username"))
        field.set_validators([ self._check_username_not_registered ])
        form.add(field)

        if (is_email_verified):
            field = InfoField("uemail")
            field.set_title(L10n.get("pas_http_user_email"))
            field.set_value(email)
            field.set_validators([ self._check_email_not_registered ])
            form.add(field)
        #

        if (ex_type is None):
            field = PasswordField("upassword")
            field.set_title(L10n.get("pas_http_user_password"))
            field.set_required()
            field.set_limits(int(Settings.get("pas_http_user_password_min", 6)))
            field.set_mode(PasswordField.PASSWORD_CLEARTEXT | PasswordField.PASSWORD_WITH_REPETITION)
            form.add(field)
        #

        tos_filepath = Settings.get_lang_associated("pas_http_user_tos_filepath",
                                                    self.request.get_lang(),
                                                    "{0}/settings/pas_user_tos.ftg".format(Settings.get("path_data"))
                                                   )

        field = FormTagsFileField("utos")
        field.set_title(L10n.get("pas_http_user_tos"))
        field.set_required()
        field.set_formtags_filepath(tos_filepath)
        form.add(field)

        tos_choices = [ { "title": L10n.get("core_yes"), "value": "accepted" },
                        { "title": L10n.get("core_no"), "value": "denied" }
                      ]

        field = RadioField("utos_accepted")
        field.set_title(L10n.get("pas_http_user_tos_accepted"))
        field.set_choices(tos_choices)
        field.set_required()
        field.set_validators([ self._check_tos_accepted ])
        form.add(field)

        if (is_save_mode and form.check()):
            if (not is_email_verified): email = InputFilter.filter_email_address(form.get_value("uemail"))
            if (username is None): username = InputFilter.filter_control_chars(form.get_value("uusername"))

            user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
            if (user_profile_class is None): raise TranslatableException("core_unknown_error")

            user_profile = user_profile_class()

            user_profile_data = { "name": username,
                                  "lang": self.request.get_lang(),
                                  "email": email
                                }

            if (ex_type is None):
                password = InputFilter.filter_control_chars(form.get_value("upassword"))
                user_profile.set_password(password)
            else:
                user_profile_data['type'] = user_profile_class.TYPE_EXTERNAL_VERIFIED_MEMBER
                user_profile_data['type_ex'] = ex_type
            #

            with TransactionContext():
                user_profile.set_data_attributes(**user_profile_data)

                if (not is_email_verified): user_profile.lock()
                else: user_profile.unlock()

                user_profile.save()
            #

            user_id = user_profile.get_id()

            if (not is_email_verified):
                cleanup_timeout_days = int(Settings.get("pas_http_user_registration_days", 28))

                cleanup_timeout = (cleanup_timeout_days * 86400)
                vid = Md5.hash(urandom(32))

                database_tasks = DatabaseTasks.get_instance()

                database_tasks.add("dNG.pas.user.Profile.delete.{0}".format(username),
                                   "dNG.pas.user.Profile.delete",
                                   cleanup_timeout,
                                   username = username
                                  )

                database_tasks.add("dNG.pas.user.Profile.sendRegistrationEMail.{0}".format(username),
                                   "dNG.pas.user.Profile.sendRegistrationEMail",
                                   1,
                                   username = username,
                                   vid = vid,
                                   vid_timeout_days = cleanup_timeout_days
                                  )

                database_tasks.register_timeout(vid,
                                                "dNG.pas.user.Profile.registrationValidated",
                                                cleanup_timeout,
                                                username = username,
                                                vid = vid
                                               )

                self._on_pending_registration(user_id, source_iline, target_iline)
            else: self._on_registration_completed(user_id, source_iline, target_iline)
        else:
            content = { "title": L10n.get("pas_http_user_registration") }

            content['form'] = { "object": form,
                                "url_parameters": { "__request__": True, "a": "register-save", "dsd": { "source": source, "target": target } },
                                "button_title": "core_continue"
                              }

            self.response.init()
            self.response.set_title(content['title'])
            self.response.add_oset_content("core.form", content)
Exemplo n.º 30
0
    def _execute_validated_profile_change(self, _type, base_action, is_save_mode = False):
        """
Action for public "change-*" requests

: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()

        source = source_iline
        if (source_iline == ""): source_iline = "m=user"

        target = target_iline
        if (target_iline == ""): target_iline = source_iline

        L10n.init("pas_http_user")

        session = (self.request.get_session() if (self.request.is_supported("session")) else None)

        pid = None
        if (session is not None): pid = session.get_user_id()
        if (pid is None): raise TranslatableError("pas_http_user_pid_invalid", 404)

        user_profile_class = NamedLoader.get_class("dNG.data.user.Profile")
        if (user_profile_class is None): raise TranslatableException("core_unknown_error")

        try: user_profile = user_profile_class.load_id(pid)
        except NothingMatchedException as handled_exception: raise TranslatableError("pas_http_user_pid_invalid", 404, _exception = handled_exception)

        if (not user_profile.is_valid()): raise TranslatableError("core_access_denied", 403)

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

        if (source_iline == ""): source_iline = "m=user;s=profile;a=edit;dsd=upid+{0}".format(Link.encode_query_value(pid))

        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 DatabaseTasks.is_available()): raise TranslatableException("pas_core_tasks_daemon_not_available")

        change_email = (_type & Profile.CHANGE_TYPE_EMAIL == Profile.CHANGE_TYPE_EMAIL)

        change_password = ((not user_profile.is_type("ex"))
                           and _type & Profile.CHANGE_TYPE_PASSWORD == Profile.CHANGE_TYPE_PASSWORD
                          )

        change_username = (Settings.get("pas_http_user_change_username_allowed", True)
                           and _type & Profile.CHANGE_TYPE_USERNAME == Profile.CHANGE_TYPE_USERNAME
                           )

        form_id = InputFilter.filter_control_chars(self.request.get_parameter("form_id"))

        form = FormProcessor(form_id)

        user_profile_data = user_profile.get_data_attributes("name", "email")

        current_email = user_profile_data['email']
        current_username = user_profile_data['name']

        if (is_save_mode): form.set_input_available()

        if (not user_profile.is_type("ex")):
            field = PasswordField("upassword")
            field.set_title(L10n.get("pas_http_user_password_current"))
            field.set_required()
            field.set_limits(int(Settings.get("pas_http_user_password_min", 6)))
            field.set_mode(PasswordField.PASSWORD_CLEARTEXT)
            form.add(field)
        #

        if (change_username):
            field = TextField("uusername")
            field.set_title(L10n.get("pas_core_username"))
            field.set_value(current_username)
            field.set_required()
            field.set_limits(int(Settings.get("pas_http_core_username_min", 3)), 100)
            field.set_size(TextField.SIZE_SMALL)
            form.add(field)
        #

        if (change_email):
            field = EMailField("uemail")
            field.set_title(L10n.get("pas_http_user_email"))
            field.set_value(current_email)
            field.set_required()
            field.set_limits(_max = 255)
            form.add(field)
        #

        if (change_password):
            field = PasswordField("upassword_new")
            field.set_title(L10n.get("pas_http_user_password_new"))
            field.set_limits(int(Settings.get("pas_http_user_password_min", 6)))
            field.set_mode(PasswordField.PASSWORD_CLEARTEXT | PasswordField.PASSWORD_WITH_REPETITION)
            form.add(field)
        #

        if (is_save_mode and form.check()):
            if (not user_profile.is_type("ex")):
                current_password = InputFilter.filter_control_chars(form.get_value("upassword"))
                if (not user_profile.is_password_valid(current_password)): raise TranslatableError("pas_http_user_password_invalid", 403)
            #

            new_email = (InputFilter.filter_control_chars(form.get_value("uemail"))
                         if (change_email) else
                         None
                        )

            new_password = (InputFilter.filter_control_chars(form.get_value("upassword_new"))
                            if (change_password) else
                            None
                           )

            new_username = (InputFilter.filter_control_chars(form.get_value("uusername"))
                            if (change_username) else
                            None
                           )

            user_profile_data_changed = { }

            if (change_email and current_email != new_email):
                try:
                    user_profile_class.load_email(new_email, True)
                    raise TranslatableError("pas_http_user_email_exists", 403)
                except NothingMatchedException: pass
            #

            if (change_username and current_username != new_username):
                try:
                    user_profile_class.load_username(new_username, True)
                    raise TranslatableError("pas_http_user_username_exists", 403)
                except NothingMatchedException: pass

                user_profile_data_changed['name'] = new_username
                user_profile.set_data_attributes(**user_profile_data_changed)
            #

            if (not user_profile.is_type("ex")):
                if (change_password
                    and new_password != ""
                    and current_password != new_password
                   ): user_profile.set_password(new_password)
                elif (change_username
                      and current_username != new_username
                     ): user_profile.set_password(current_password)
            #

            user_profile.save()

            database_tasks = DatabaseTasks.get_instance()
            username = (new_username if (new_username is not None) else current_username)

            if (len(user_profile_data_changed) > 0):
                original_user_profile_data = user_profile.get_data_attributes(*user_profile_data_changed.keys())

                database_tasks.add("dNG.pas.user.Profile.onEdited.{0}".format(username),
                                   "dNG.pas.user.Profile.onEdited",
                                   1,
                                   user_profile_id = pid,
                                   user_profile_data_changed = user_profile_data_changed,
                                   original_user_profile_data = original_user_profile_data
                                  )
            #

            if (change_email and current_email != new_email):
                cleanup_timeout_days = int(Settings.get("pas_http_user_change_profile_days", 7))

                cleanup_timeout = (cleanup_timeout_days * 86400)
                vid = Md5.hash(urandom(32))

                database_tasks.add("dNG.pas.user.Profile.sendChangePendingEMail.{0}".format(username),
                                   "dNG.pas.user.Profile.sendChangePendingEMail",
                                   1,
                                   username = username,
                                   recipient = new_email,
                                   vid = vid,
                                   vid_timeout_days = cleanup_timeout_days
                                  )

                database_tasks.register_timeout(vid,
                                                "dNG.pas.user.Profile.changesConfirmed",
                                                cleanup_timeout,
                                                username = username,
                                                values_changed = { "email": new_email },
                                                vid = vid
                                               )
            #

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

            if (change_email
                and current_email != new_email
               ): NotificationStore.get_instance().add_info(L10n.get("pas_http_user_done_change_profile_pending"))
            else: NotificationStore.get_instance().add_completed_info(L10n.get("pas_http_user_done_change_profile"))

            Link.clear_store("servicemenu")

            redirect_request = PredefinedHttpRequest()
            redirect_request.set_iline(target_iline)
            self.request.redirect(redirect_request)
        else:
            content = { "title": L10n.get("pas_http_user_title_change_profile") }

            content['form'] = { "object": form,
                                "url_parameters": { "__request__": True,
                                                    "a": "{0}-save".format(base_action),
                                                    "dsd": { "source": source, "target": target }
                                                  },
                                "button_title": "pas_http_core_edit"
                              }

            self.response.init()
            self.response.set_title(content['title'])
            self.response.add_oset_content("core.form", content)