♻️ Major code restructuring
This commit is contained in:
parent
a96e203bb3
commit
fa66d628a0
221 changed files with 228 additions and 315 deletions
19
packages/pagetop-user/Cargo.toml
Normal file
19
packages/pagetop-user/Cargo.toml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "pagetop-user"
|
||||
version = "0.0.14"
|
||||
edition = "2021"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
description = """\
|
||||
Module to add user management, roles, permissions and sessions in applications developed with \
|
||||
PageTop.\
|
||||
"""
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../../", features = ["database"], default-features = false }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
27
packages/pagetop-user/README.md
Normal file
27
packages/pagetop-user/README.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Módulo para añadir gestión de usuarios, roles, permisos y sesiones en aplicaciones desarrolladas con
|
||||
**PageTop**.
|
||||
|
||||
[PageTop](https://github.com/manuelcillero/pagetop/tree/main/pagetop), es un entorno de desarrollo
|
||||
basado en algunos de los *crates* más estables y populares del ecosistema Rust para proporcionar
|
||||
APIs, patrones de desarrollo y buenas prácticas para la creación de soluciones web SSR (*Server-Side
|
||||
Rendering*).
|
||||
|
||||
|
||||
# 🚧 Advertencia
|
||||
|
||||
**PageTop** sólo libera actualmente versiones de desarrollo. La API no es estable y los cambios son
|
||||
constantes. No puede considerarse preparado hasta que se libere la versión **0.1.0**.
|
||||
|
||||
|
||||
# 📜 Licencia
|
||||
|
||||
Este proyecto tiene licencia, de hecho tiene dos, puedes aplicar cualquiera de las siguientes a tu
|
||||
elección:
|
||||
|
||||
* Licencia Apache versión 2.0
|
||||
([LICENSE-APACHE](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-APACHE) o
|
||||
[http://www.apache.org/licenses/LICENSE-2.0]).
|
||||
|
||||
* Licencia MIT
|
||||
([LICENSE-MIT](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-MIT) o
|
||||
[http://opensource.org/licenses/MIT]).
|
||||
65
packages/pagetop-user/src/lib.rs
Normal file
65
packages/pagetop-user/src/lib.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
static_locales!(LOCALES_USER);
|
||||
|
||||
mod migration;
|
||||
|
||||
#[derive(AssignHandle)]
|
||||
pub struct User;
|
||||
|
||||
impl PackageTrait for User {
|
||||
fn name(&self) -> L10n {
|
||||
L10n::t("package_name", &LOCALES_USER)
|
||||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::t("package_description", &LOCALES_USER)
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
scfg.route("/user/login", service::web::get().to(login));
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<MigrationItem> {
|
||||
migrations![
|
||||
m20220312_000001_create_table_role,
|
||||
m20220312_000002_create_table_role_permission,
|
||||
m20220312_000003_create_table_user,
|
||||
m20220312_000004_create_table_user_role,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
async fn login(request: service::HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||
Page::new(request)
|
||||
.with_title(L10n::n("Identificación del usuario"))
|
||||
.with_component_in(
|
||||
"content",
|
||||
Wrapper::new()
|
||||
.with_id("welcome")
|
||||
.add_component(form_login()),
|
||||
)
|
||||
.render()
|
||||
}
|
||||
|
||||
fn form_login() -> Form {
|
||||
Form::new()
|
||||
.with_id("user-login")
|
||||
.with_element(
|
||||
form::Input::textfield()
|
||||
.with_name("name")
|
||||
.with_label(L10n::t("username", &LOCALES_USER))
|
||||
.with_help_text(
|
||||
L10n::t("username_help", &LOCALES_USER)
|
||||
.with_arg("app", config::SETTINGS.app.name.to_owned()),
|
||||
)
|
||||
.with_autofocus(true),
|
||||
)
|
||||
.with_element(
|
||||
form::Input::password()
|
||||
.with_name("pass")
|
||||
.with_label(L10n::t("password", &LOCALES_USER))
|
||||
.with_help_text(L10n::t("password_help", &LOCALES_USER)),
|
||||
)
|
||||
.with_element(form::ActionButton::submit().with_value(L10n::t("login", &LOCALES_USER)))
|
||||
}
|
||||
8
packages/pagetop-user/src/locale/en-US/homepage.ftl
Normal file
8
packages/pagetop-user/src/locale/en-US/homepage.ftl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package_name = User
|
||||
package_description = Manages the user registration and login system.
|
||||
|
||||
username = User name
|
||||
password = Password
|
||||
username_help = Enter your { $app } username.
|
||||
password_help = Enter the password that accompanies your username.
|
||||
login = Log in
|
||||
8
packages/pagetop-user/src/locale/es-ES/homepage.ftl
Normal file
8
packages/pagetop-user/src/locale/es-ES/homepage.ftl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package_name = Usuario
|
||||
package_description = Gestiona el registro de usuarios y el sistema de accesos.
|
||||
|
||||
username = Nombre de usuario
|
||||
password = Contraseña
|
||||
username_help = Introduzca su nombre de usuario en { $app }.
|
||||
password_help = Introduzca la contraseña asociada a su nombre de usuario.
|
||||
login = Iniciar sesión
|
||||
4
packages/pagetop-user/src/migration.rs
Normal file
4
packages/pagetop-user/src/migration.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
pub mod m20220312_000001_create_table_role;
|
||||
pub mod m20220312_000002_create_table_role_permission;
|
||||
pub mod m20220312_000003_create_table_user;
|
||||
pub mod m20220312_000004_create_table_user_role;
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum Role {
|
||||
Table, // role: Store user roles.
|
||||
|
||||
Rid, // Primary Key: Unique role ID.
|
||||
Name, // Unique role name.
|
||||
Weight, // The weight of this role in listings and the user interface.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Role::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Role::Rid)
|
||||
.unsigned()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Role::Name)
|
||||
.string_len(64)
|
||||
.not_null()
|
||||
.unique_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Role::Weight)
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(10),
|
||||
)
|
||||
// INDEXES.
|
||||
.index(
|
||||
Index::create()
|
||||
.name("weight-name")
|
||||
.col(Role::Weight)
|
||||
.col(Role::Name),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Built-in roles.
|
||||
db::exec::<InsertStatement>(
|
||||
Query::insert()
|
||||
.into_table(Role::Table)
|
||||
.columns(vec![Role::Name, Role::Weight])
|
||||
.values_panic(vec!["anonymous".into(), "1".into()])
|
||||
.values_panic(vec!["authenticated".into(), "2".into()])
|
||||
.values_panic(vec!["administrator".into(), "3".into()]),
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Role::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum RolePermission {
|
||||
Table, // role_permission: Stores the permissions assigned to user roles.
|
||||
|
||||
Rid, // Foreign Key: Role::Rid.
|
||||
Permission, // A single permission granted to the role identified by Rid.
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum Role {
|
||||
Table,
|
||||
Rid,
|
||||
/* ... */
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(RolePermission::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(RolePermission::Rid).unsigned().not_null())
|
||||
.col(
|
||||
ColumnDef::new(RolePermission::Permission)
|
||||
.string_len(128)
|
||||
.not_null(),
|
||||
)
|
||||
// INDEXES.
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(RolePermission::Rid)
|
||||
.col(RolePermission::Permission),
|
||||
)
|
||||
.index(
|
||||
Index::create()
|
||||
.name("permission")
|
||||
.col(RolePermission::Permission),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_role_permission-rid")
|
||||
.from(RolePermission::Table, RolePermission::Rid)
|
||||
.to(Role::Table, Role::Rid)
|
||||
.on_delete(ForeignKeyAction::Restrict)
|
||||
.on_update(ForeignKeyAction::Restrict),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(RolePermission::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table, // user: Stores user data.
|
||||
|
||||
Uid, // Primary Key: Unique user ID.
|
||||
Name, // Unique user name.
|
||||
Pass, // User's password (hashed).
|
||||
Mail, // User's e-mail address.
|
||||
Created, // Timestamp for when user was created.
|
||||
Changed, // Timestamp for when user was changed.
|
||||
Access, // Timestamp for previous time user accessed the site.
|
||||
Login, // Timestamp for user's last login.
|
||||
Status, // Whether the user is active(1) or blocked(0).
|
||||
Timezone, // User's time zone.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(User::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(User::Uid)
|
||||
.unsigned()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(User::Name)
|
||||
.string_len(60)
|
||||
.not_null()
|
||||
.unique_key(),
|
||||
)
|
||||
.col(ColumnDef::new(User::Pass).string_len(128).not_null())
|
||||
.col(ColumnDef::new(User::Mail).string_len(255))
|
||||
.col(ColumnDef::new(User::Created).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Changed).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Access).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Login).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Status).boolean().not_null())
|
||||
.col(ColumnDef::new(User::Timezone).string_len(32))
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(User::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum UserRole {
|
||||
Table, // user_role: Maps users to roles.
|
||||
|
||||
Uid, // Foreign Key: User::Uid for user.
|
||||
Rid, // Foreign Key: Role::Rid for role.
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table,
|
||||
Uid,
|
||||
/* ... */
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum Role {
|
||||
Table,
|
||||
Rid,
|
||||
/* ... */
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(UserRole::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(UserRole::Uid).unsigned().not_null())
|
||||
.col(ColumnDef::new(UserRole::Rid).unsigned().not_null())
|
||||
// INDEXES.
|
||||
.primary_key(Index::create().col(UserRole::Uid).col(UserRole::Rid))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_user_role-uid")
|
||||
.from(UserRole::Table, UserRole::Uid)
|
||||
.to(User::Table, User::Uid)
|
||||
.on_delete(ForeignKeyAction::Restrict)
|
||||
.on_update(ForeignKeyAction::Restrict),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_user_role-rid")
|
||||
.from(UserRole::Table, UserRole::Rid)
|
||||
.to(Role::Table, Role::Rid)
|
||||
.on_delete(ForeignKeyAction::Restrict)
|
||||
.on_update(ForeignKeyAction::Restrict),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(UserRole::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue