Skip to main content

splent_feature_signup

The signup feature of a SPLENT product line.

Public self-registration. Without it a product is closed and an administrator gives each person access. With it, /signup/ opens an account with an email address and a password, and a "Sign up" link appears on the login page, in the anonymous navbar and in the anonymous sidebar. It needs auth, which owns the account.

A SPLENT feature is a Python package that a product composes with others. Its models, routes, services, templates and hooks are registered when the product starts. What this feature provides and requires is listed in the [tool.splent.contract] section of pyproject.toml, which splent feature:contract --write keeps in sync with the source.

What a sign-up does

  1. The form is validated, with every field other features registered.
  2. signup-submitting is sent, and any listener may refuse.
  3. The address is checked, and the account is created through auth's AuthenticationService.create_user, always with the role user.
  4. auth sends user-registered, with the values of the registered fields.
  5. The account opens at once, the person is logged in and goes to next, or where a login would send them. When the product confirms addresses (a feature registers ConfirmemailService), the account waits closed and the person is sent to the login page to read where the link went.

Password

The form follows auth's password policy, the same one as every other form that sets a password. signup has no setting of its own.

Setting (auth) Default On the sign-up form
AUTH_PASSWORD_MIN_LENGTH 8 The shortest password accepted, from 8 to 128. No password longer than 128 characters is accepted
AUTH_PASSWORD_CONFIRM false When true, a second box asks for the password again
[tool.splent.config]
AUTH_PASSWORD_MIN_LENGTH = 12
AUTH_PASSWORD_CONFIRM = true

With an auth older than its password policy, which has no passwords module, the form keeps the rule it had before. It asks once, for at least 8 characters, and the two settings change nothing.

Fields other features add

A feature that keeps something about the person asks for it at sign-up with register_signup_field. The field is drawn on the page, validated with the form, and its value travels on user-registered under its name.

# __init__.py of a profile feature
from flask_babel import lazy_gettext as _l
from wtforms import StringField
from wtforms.validators import DataRequired, Length

from splent_io.splent_feature_signup.forms import register_signup_field


def init_feature(app):
    register_signup_field(
        "name",
        StringField(_l("Name"), validators=[DataRequired(), Length(max=100)]),
        order=10,
    )
    register_signup_field(
        "surname",
        StringField(_l("Surname"), validators=[DataRequired(), Length(max=100)]),
        order=20,
    )
# signals.py of the same feature
@connect_signal("user-registered", "splent_feature_profile")
def keep_the_name(sender, user, name="", surname="", **kwargs):
    ...

order places the field. Lower comes first.

Field Order
A registered field that says so its own
email 100 (EMAIL_ORDER)
password, and its repeat 200 (PASSWORD_ORDER)
A registered field that does not say 300 (DEFAULT_FIELD_ORDER)

The registry is read when a request needs the form, so a field registered after signup has loaded is asked for too. The form class is built once for each set of registered fields and reused while that set stays the same. Registering a name again replaces the earlier field. remove_signup_field(name) stops asking for one. A field's own render_kw (a placeholder) and description (a line of help) are shown, and a BooleanField is drawn as a checkbox, so a feature can ask to accept its terms with BooleanField(_l("I accept the terms"), validators=[DataRequired()]).

Some names are refused with a ValueError when the field is registered. role and active decide who the account is and whether it opens, which is never the visitor's choice. user and sender are the arguments of user-registered. The form's own fields (email, password, confirm_password, next, submit, csrf_token) and the form's attributes (data, errors, meta...) cannot be taken either.

Checks before the account is created

signup-submitting is sent once the form is valid and before the address is looked up, with form (the posted form) and remoteip. A listener that returns False refuses the sign-up. The form comes back with the typed values and "We could not verify this sign-up. Please try again.", and no account is made. None or True let it through. A captcha provider listens here, as it listens to contact-submitting and comment-submitting, and draws its widget in the signup.form_fields slot.

# signals.py of a captcha feature
from splent_framework.signals.signal_utils import connect_signal


@connect_signal("signup-submitting", "splent_feature_mycaptcha")
def check_the_answer(sender, form=None, remoteip=None, **kwargs):
    from splent_io.splent_feature_mycaptcha.services import MyCaptchaService

    return MyCaptchaService().verify(form.get("my-captcha-answer"), remoteip)

The sign-up page

The page opens three slots. A callback takes no arguments and returns HTML, or an empty string to add nothing on this request.

Slot Where it renders When
signup.form_fields Inside the form, after the fields and right above the button Always
signup.providers After the form, under the words "or continue with" Only when a callback returns something. Otherwise nothing is drawn, not even the words
signup.form_footer At the bottom of the form, under "Already have an account?" Always
# hooks.py of a captcha feature
from flask import render_template
from splent_framework.hooks.template_hooks import register_template_hook


def captcha_widget():
    return render_template("hooks/captcha_widget.html")


register_template_hook("signup.form_fields", captcha_widget)

An external sign-in provider puts its button in signup.providers, as it does in auth's auth.login.providers.

register_template_hook("signup.providers", sign_in_button, order=20)

The page extends shell('login'), the shell of the login page (AUTH_LOGIN_LAYOUT, else the application shell), so the two look like one site.

Menus

The feature declares the way to sign up in the framework's menu registry, right after auth's Log in, and an application shell that draws menu_sections() and user_menu_sections() shows it to visitors who are not signed in.

Key Menu Section Order Opens
signup Sidebar anonymous 20 signup.show_signup_form
user_signup User menu anonymous 20 signup.show_signup_form

A product hides or reorders them by key in [tool.splent.layout.menu]. The layout.anonymous_sidebar and layout.navbar.anonymous hooks still draw the same links for one minor, for the shells that draw those slots. A shell draws the registry or those slots, never both. The next minor drops the hooks.

Under the login form, "Don't have an account?" renders at order 50 in auth.login.form_footer, before the links that take the default order, such as reset's "Forgot your password?".

Where the person lands

A sign-up on the way to a page ends up on that page. /signup/?next=/the/page goes to /the/page once the account is open, and to /login?next=/the/page while it waits for its confirmation. The rule is auth's safe_next_url, so only a path on this site is followed and anything else is ignored. The "Sign up!" link on the login page carries the login's next, and the sign-up page's "Log in" link carries it back.

Use it in a product

splent feature:add splent_feature_signup

Develop

splent feature:test splent_feature_signup
splent feature:contract splent_feature_signup

Release

splent feature:release splent_feature_signup --dry-run --bump patch
splent feature:release splent_feature_signup

The first command rehearses the release and changes nothing. The second publishes it to the git forge and to PyPI, and a PyPI version is permanent.

Metadata

Release files for splent-feature-signup 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for splent-feature-signup 0.4.0
File Size Uploaded Provenance
splent_feature_signup-0.4.0.tar.gz 29.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for splent-feature-signup 0.4.0
File Interpreter ABI Platform
splent_feature_signup-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 63.6 kB

Release files / splent_feature_signup-0.4.0.tar.gz

Download URL splent_feature_signup-0.4.0.tar.gz
Size 29.7 kB
Tags Source
SHA-256 checksum
How to use checksums
fa664eb96211e37b6c97867dd8cb653b806f74c9834d2c91381ebf0e7a466417
BLAKE2b-256 checksum
How to use checksums
2091dc03fdbfaddeefb3c9cd71ce7fd9fc3de4b3a6f707b6933cc3f9af39a702
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.16

Release files / splent_feature_signup-0.4.0-py3-none-any.whl

Download URL splent_feature_signup-0.4.0-py3-none-any.whl
Size 34.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4cd8ff187faa57a3d81768be40b02ecbfde6cd6d80f568cc3b2faab844ceeaca
BLAKE2b-256 checksum
How to use checksums
0ea64c5f908f7d5392fb04e7d5761b2453379939621534daf6c93f84f3d5086b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.16

Security for splent-feature-signup 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page