Skip to main content

ProfileEditor

Trait ProfileEditor 

Source
pub trait ProfileEditor:
    Send
    + Sync
    + 'static {
    type Input: FormInput;
    type User: PanelUser;

    // Required methods
    fn fill(&self, cx: &Cx, user: &Self::User) -> Self::Input;
    fn save(
        &self,
        cx: &Cx,
        user: &Self::User,
        input: Self::Input,
        ex: &mut dyn Executor,
    ) -> impl Future<Output = Result<ProfileUpdate>> + Send;

    // Provided method
    fn validate(
        &self,
        _cx: &Cx,
        _user: &Self::User,
        _input: &Self::Input,
        _ex: &mut dyn Executor,
    ) -> impl Future<Output = Result<FieldErrors>> + Send { ... }
}
Expand description

How a panel lets the signed-in user edit their own account on its profile page, installed with Auth::profile.

It mirrors a Registrar: Input is the form the page shows, fill seeds it from the account, validate refuses a submission field by field, and save writes it. validate and save run in one transaction the framework opens.

The shipped PasswordAuth edits an AdminUser through a Profile; an app with its own user table implements it beside its Authenticator, for the same user type:

#[derive(tablo_core::FormInput)]
struct Rename {
    name: String,
}

struct StaffProfile;

impl ProfileEditor for StaffProfile {
    type Input = Rename;
    type User = Staff;

    fn fill(&self, _cx: &Cx, staff: &Staff) -> Rename {
        Rename {
            name: staff.name.clone(),
        }
    }

    async fn save(
        &self,
        _cx: &Cx,
        staff: &Staff,
        rename: Rename,
        ex: &mut dyn toasty::Executor,
    ) -> topcoat::Result<ProfileUpdate> {
        Staff::filter(Staff::fields().id().eq(staff.id))
            .update()
            .name(rename.name)
            .exec(ex)
            .await?;
        Ok(ProfileUpdate::Details)
    }
}

Required Associated Types§

Source

type Input: FormInput

What the profile page asks for: Profile, or the app’s own #[derive(FormInput)] struct.

Source

type User: PanelUser

The account the page edits: the type the panel’s Authenticator loads, which mounting checks.

Required Methods§

Source

fn fill(&self, cx: &Cx, user: &Self::User) -> Self::Input

The form as the page first shows it, from the signed-in user. The page renders what FormInput::write writes, so an input that never writes its passwords shows them empty.

Source

fn save( &self, cx: &Cx, user: &Self::User, input: Self::Input, ex: &mut dyn Executor, ) -> impl Future<Output = Result<ProfileUpdate>> + Send

Write a validated input to user’s account through the transaction ex, which commits when it returns Ok, and say whether a credential changed.

Provided Methods§

Source

fn validate( &self, _cx: &Cx, _user: &Self::User, _input: &Self::Input, _ex: &mut dyn Executor, ) -> impl Future<Output = Result<FieldErrors>> + Send

Refuse a submission save should not receive, such as a wrong current password: each error names an input field’s key and renders under its control. Defaults to none. A key no control renders is a declaration error: the page would show no message.

It runs inside the save’s transaction ex, after the input parses and its controls’ own rules pass.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl ProfileEditor for PasswordAuth

Edits the signed-in AdminUser’s name, email and password through a Profile. Changing the email or the password asks for the current password, and refuses a new password new_password_errors refuses and, once the current password verifies, an email another account holds. A changed password is a ProfileUpdate::Credentials. A new email goes through request_email_change: on a panel with Auth::email_verification it waits for its link, elsewhere it is stored at once, as a credential change. Install it with Auth::profile.