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
- The form is validated, with every field other features registered.
signup-submittingis sent, and any listener may refuse.- The address is checked, and the account is created through auth's
AuthenticationService.create_user, always with the roleuser. - auth sends
user-registered, with the values of the registered fields. - 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 registersConfirmemailService), 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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| splent_feature_signup-0.4.1.tar.gz | 29.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| splent_feature_signup-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.6 kB
Release files / splent_feature_signup-0.4.1.tar.gz
| Download URL | splent_feature_signup-0.4.1.tar.gz |
|---|---|
| Size | 29.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7d5ad32806a061137d904f389d0d650a36328045656e5c534f3436d64178643a
|
|
BLAKE2b-256 checksum How to use checksums |
6571e52e19186f2243da4ce20b45e417bdd024bdb8fdd0f6ea553f5b114710f0
|
| 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.1-py3-none-any.whl
| Download URL | splent_feature_signup-0.4.1-py3-none-any.whl |
|---|---|
| Size | 34.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85f08b281ebe0b3004beb028554008a00e3fc72138c41d8fec6ecbc6aad235cc
|
|
BLAKE2b-256 checksum How to use checksums |
4ef56a0f6d9f240f18114a6906e33b7ffc17fce250da2063d8a01df0e0bade19
|
| 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.1
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.