From 7a8bbb79d5a8c236a95c30c363408709653e2230 Mon Sep 17 00:00:00 2001 From: Amin Alaee Date: Thu, 20 Jun 2024 14:29:42 +0200 Subject: [PATCH] Add cookbook: Working with passwords (#783) --- docs/cookbook/working_with_passwords.md | 48 +++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 49 insertions(+) create mode 100644 docs/cookbook/working_with_passwords.md diff --git a/docs/cookbook/working_with_passwords.md b/docs/cookbook/working_with_passwords.md new file mode 100644 index 00000000..37ed1200 --- /dev/null +++ b/docs/cookbook/working_with_passwords.md @@ -0,0 +1,48 @@ +It's a comment use-case that you have a model +with a `Password` field which needs a custom behaviour. + +Let's say you have the following `User` model: + +```py +class User(Base): + __tablename__ = "user" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(50)) + hashed_password: Mapped[str] = mapped_column(String) +``` + +In this specific case we want the following features to be available in the Admin console: + +- We only want `hashed_password` when creating a new `User`, and we want to hide it when editing a `User`. +- When a User is created, the password should be hashed and stored in the `hashed_password` column. + +So we define the following `UserAdmin` class for it: + +```py +class UserAdmin(ModelView, model=User): + column_labels = {"hashed_password": "password"} + form_create_rules = ["name", "hashed_password"] + form_edit_rules = ["name"] + + async def on_model_change(self, data, model, is_created, request) -> None: + if is_created: + # Hash the password before saving into DB ! + data["hashed_password"] = data["hashed_password"] + "_hashed" + +``` + +So let's see what is happening. + +The `column_labels` is just saying to rename `hashed_password` to `password` when displaying or creating a form for the `User`. + +Next we have defined two extra attributes called `form_create_rules` and `form_edit_rules` which +controls how the create and edit forms are created. + +In the `form_create_rules` declaration we specify we want `name` and `hashed_password` when creating a `User`. + +But in `form_edit_rules` we specifically excluded `hashed_password` so we only want to edit `name` of the `User`. + +And finally the last step is to hash the password before saving into the database. +There could be a few options to do this, but in this case we are overriding `on_model_change` and only hashing the password +when we are creating a `User`. diff --git a/mkdocs.yml b/mkdocs.yml index cc071cd0..427ea422 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -27,6 +27,7 @@ nav: - Using a request object: "cookbook/using_request_object.md" - Multiple databases: "cookbook/multiple_databases.md" - Using rich text editor: "cookbook/using_wysiwyg.md" + - Working with Passwords: "cookbook/working_with_passwords.md" - API Reference: - Application: "api_reference/application.md" - ModelView: "api_reference/model_view.md"