♻️ Importa PageTop usando el prelude
This commit is contained in:
parent
8651b91ab2
commit
404739a3fd
31 changed files with 96 additions and 112 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use pagetop::auth::PermissionRef;
|
||||
use pagetop::prelude::*;
|
||||
|
||||
// **< UserStatus >*********************************************************************************
|
||||
|
||||
|
|
@ -56,9 +56,9 @@ impl PermissionSet {
|
|||
|
||||
/// Datos ricos del usuario autenticado inyectados por el middleware de sesión.
|
||||
///
|
||||
/// Se almacena en las extensiones de la petición HTTP durante la fase de middleware y se
|
||||
/// accede desde los handlers o desde handlers de [`CheckPermission`](pagetop::auth::CheckPermission)
|
||||
/// mediante [`HttpRequest::extension::<Account>()`](pagetop::web::HttpRequest::extension).
|
||||
/// Se almacena en las extensiones de la petición HTTP durante la fase de middleware y se accede
|
||||
/// desde los handlers o desde handlers de [`CheckPermission`] mediante
|
||||
/// [`HttpRequest::extension::<Account>()`](pagetop::web::HttpRequest::extension).
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Account {
|
||||
pub id: i32,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//! Lógica de autenticación: login, logout, registro, semilla inicial.
|
||||
|
||||
use pagetop::datetime::{Duration, NaiveDateTime, Utc};
|
||||
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::{
|
||||
ActiveModelTrait, ActiveValue, ColumnTrait, Condition, EntityTrait, PaginatorTrait,
|
||||
QueryFilter, Set, dbconn,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
//! Tabla de roles: cabeceras ordenables y filas con acciones.
|
||||
|
||||
use pagetop::prelude::*;
|
||||
|
||||
use pagetop::base::component::table::{Column, Row};
|
||||
use pagetop_htmx::hx;
|
||||
use pagetop_htmx::hx_table::sort_link;
|
||||
|
||||
|
|
@ -93,7 +91,7 @@ impl Component for RoleTable {
|
|||
};
|
||||
|
||||
table.alter_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(role.machine_name.as_str())
|
||||
.with_cell(label_cell(role, &waypoint))
|
||||
.with_cell(Html::with(move |_cx| {
|
||||
|
|
@ -188,7 +186,12 @@ impl RoleTable {
|
|||
// Construye la cabecera ordenable de una columna: el enlace ya funciona sin HTMX (navega con
|
||||
// una petición normal); `pagetop_htmx::hx_table::sort_link()` añade aparte los atributos `hx-*`
|
||||
// para que la tabla se actualice sin recargar la página cuando la extensión esté disponible.
|
||||
fn sort_column(&self, cx: &Context, field: RoleSortField, label_key: &'static str) -> Column {
|
||||
fn sort_column(
|
||||
&self,
|
||||
cx: &Context,
|
||||
field: RoleSortField,
|
||||
label_key: &'static str,
|
||||
) -> table::Column {
|
||||
let is_active = *self.sort() == field;
|
||||
let active = is_active.then_some(*self.dir());
|
||||
let next_dir = SortDir::next_for(active);
|
||||
|
|
@ -197,7 +200,7 @@ impl RoleTable {
|
|||
.alter_param("sort", field.as_str())
|
||||
.alter_param("dir", next_dir);
|
||||
|
||||
Column::new(Lc::t(label_key, &LOCALES_USER)).with_sort(sort_link(
|
||||
table::Column::new(Lc::t(label_key, &LOCALES_USER)).with_sort(sort_link(
|
||||
route,
|
||||
"#role-table-wrapper",
|
||||
active,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
//! Tabla de usuarios: cabeceras ordenables, filas y paginación embebida.
|
||||
|
||||
use pagetop::prelude::*;
|
||||
|
||||
use pagetop::base::component::table::{Column, Row};
|
||||
use pagetop_htmx::hx;
|
||||
use pagetop_htmx::hx_table::sort_link;
|
||||
|
||||
|
|
@ -75,7 +73,7 @@ impl Component for UserTable {
|
|||
let status = user.status;
|
||||
|
||||
table.alter_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(username_cell(user, &waypoint))
|
||||
.with_cell(user.email.as_str())
|
||||
.with_cell(user.display_name.as_deref().unwrap_or("-"))
|
||||
|
|
@ -163,7 +161,12 @@ impl UserTable {
|
|||
// Construye la cabecera ordenable de una columna: el enlace ya funciona sin HTMX (navega con
|
||||
// una petición normal); `pagetop_htmx::hx_table::sort_link()` añade aparte los atributos `hx-*`
|
||||
// para que la tabla se actualice sin recargar la página cuando la extensión esté disponible.
|
||||
fn sort_column(&self, cx: &Context, field: UserSortField, label_key: &'static str) -> Column {
|
||||
fn sort_column(
|
||||
&self,
|
||||
cx: &Context,
|
||||
field: UserSortField,
|
||||
label_key: &'static str,
|
||||
) -> table::Column {
|
||||
let is_active = *self.sort() == field;
|
||||
let active = is_active.then_some(*self.dir());
|
||||
let next_dir = SortDir::next_for(active);
|
||||
|
|
@ -176,7 +179,7 @@ impl UserTable {
|
|||
.alter_param("sort", field.as_str())
|
||||
.alter_param("dir", next_dir);
|
||||
|
||||
Column::new(Lc::t(label_key, &LOCALES_USER)).with_sort(sort_link(
|
||||
table::Column::new(Lc::t(label_key, &LOCALES_USER)).with_sort(sort_link(
|
||||
route,
|
||||
"#user-table-wrapper",
|
||||
active,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
//! `Extension::initialize()`, después de `auth::seed_initial_data()`. Si el rol
|
||||
//! `demo_role_01` ya existe, la siembra se omite para no duplicar datos en reinicios.
|
||||
|
||||
use pagetop::datetime::Utc;
|
||||
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::{ActiveValue, ColumnTrait, EntityTrait, QueryFilter, Set, dbconn};
|
||||
|
||||
use crate::account::UserStatus;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::*;
|
||||
|
||||
use pagetop::datetime::NaiveDateTime;
|
||||
|
||||
#[derive(Clone, Debug, DeriveEntityModel, PartialEq)]
|
||||
#[sea_orm(table_name = "roles")]
|
||||
pub struct Model {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::*;
|
||||
|
||||
use pagetop::datetime::NaiveDateTime;
|
||||
|
||||
#[derive(Clone, Debug, DeriveEntityModel, PartialEq)]
|
||||
#[sea_orm(table_name = "role_permissions")]
|
||||
pub struct Model {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::*;
|
||||
|
||||
use pagetop::datetime::NaiveDateTime;
|
||||
|
||||
#[derive(Clone, Debug, DeriveEntityModel, PartialEq)]
|
||||
#[sea_orm(table_name = "sessions")]
|
||||
pub struct Model {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::*;
|
||||
|
||||
use pagetop::datetime::NaiveDateTime;
|
||||
|
||||
#[derive(Clone, Debug, DeriveEntityModel, PartialEq)]
|
||||
#[sea_orm(table_name = "users")]
|
||||
pub struct Model {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::*;
|
||||
|
||||
use pagetop::datetime::NaiveDateTime;
|
||||
|
||||
#[derive(Clone, Debug, DeriveEntityModel, PartialEq)]
|
||||
#[sea_orm(table_name = "user_tokens")]
|
||||
pub struct Model {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! Handler HTTP para el perfil del propio usuario autenticado.
|
||||
|
||||
use pagetop::base::component::table::Row;
|
||||
use pagetop::prelude::*;
|
||||
|
||||
use crate::account::UserStatus;
|
||||
|
|
@ -47,32 +46,32 @@ async fn profile_details(user: &user::Model, status: UserStatus, cx: &mut Contex
|
|||
let mut table = Table::new()
|
||||
.with_prop(PropsOp::add_classes("user-admin-table"))
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-username-admin", &LOCALES_USER))
|
||||
.with_cell(user.username.as_str()),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-email", &LOCALES_USER))
|
||||
.with_cell(user.email.as_str()),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-display-name", &LOCALES_USER))
|
||||
.with_cell(user.display_name.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-language", &LOCALES_USER))
|
||||
.with_cell(user.language.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-timezone", &LOCALES_USER))
|
||||
.with_cell(user.timezone.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("col-status", &LOCALES_USER))
|
||||
.with_cell(Lc::t(status_key(status), &LOCALES_USER)),
|
||||
);
|
||||
|
|
@ -83,7 +82,7 @@ async fn profile_details(user: &user::Model, status: UserStatus, cx: &mut Contex
|
|||
.render(cx)
|
||||
.await;
|
||||
table = table.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell("")
|
||||
.with_cell(Html::with(move |_| badge.clone())),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use serde::Deserialize;
|
||||
|
||||
use pagetop::base::component::table::Row;
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_htmx::prelude::*;
|
||||
|
||||
|
|
@ -313,22 +312,22 @@ async fn role_view_details(role: &role::Model, cx: &mut Context) -> Block {
|
|||
let mut table = Table::new()
|
||||
.with_prop(PropsOp::add_classes("user-admin-table"))
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-machine-name", &LOCALES_USER))
|
||||
.with_cell(role.machine_name.as_str()),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-label", &LOCALES_USER))
|
||||
.with_cell(role.label.as_str()),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-description", &LOCALES_USER))
|
||||
.with_cell(role.description.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-weight", &LOCALES_USER))
|
||||
.with_cell(role.weight.to_string()),
|
||||
);
|
||||
|
|
@ -339,7 +338,7 @@ async fn role_view_details(role: &role::Model, cx: &mut Context) -> Block {
|
|||
.render(cx)
|
||||
.await;
|
||||
table = table.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell("")
|
||||
.with_cell(Html::with(move |_| badge.clone())),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use serde::Deserialize;
|
||||
|
||||
use pagetop::base::component::table::Row;
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_htmx::prelude::*;
|
||||
|
||||
|
|
@ -517,32 +516,32 @@ async fn user_view_details(user: &user::Model, status: UserStatus, cx: &mut Cont
|
|||
let mut table = Table::new()
|
||||
.with_prop(PropsOp::add_classes("user-admin-table"))
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-username-admin", &LOCALES_USER))
|
||||
.with_cell(user.username.as_str()),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-email", &LOCALES_USER))
|
||||
.with_cell(user.email.as_str()),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-display-name", &LOCALES_USER))
|
||||
.with_cell(user.display_name.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-language", &LOCALES_USER))
|
||||
.with_cell(user.language.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("field-timezone", &LOCALES_USER))
|
||||
.with_cell(user.timezone.as_deref().unwrap_or("-")),
|
||||
)
|
||||
.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell(Lc::t("col-status", &LOCALES_USER))
|
||||
.with_cell(Lc::t(status_key(status), &LOCALES_USER)),
|
||||
);
|
||||
|
|
@ -553,7 +552,7 @@ async fn user_view_details(user: &user::Model, status: UserStatus, cx: &mut Cont
|
|||
.render(cx)
|
||||
.await;
|
||||
table = table.with_row(
|
||||
Row::new()
|
||||
table::Row::new()
|
||||
.with_cell("")
|
||||
.with_cell(Html::with(move |_| badge.clone())),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use serde::Deserialize;
|
||||
|
||||
use pagetop::auth::CurrentUser;
|
||||
use pagetop::prelude::*;
|
||||
|
||||
use crate::auth;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@
|
|||
//! si el usuario está autenticado, el [`crate::account::Account`] con sus datos ricos en las
|
||||
//! extensiones de la petición HTTP.
|
||||
|
||||
use pagetop::auth::PermissionRef;
|
||||
use pagetop::web::middleware::Next;
|
||||
use pagetop::web::{Request, Response};
|
||||
use pagetop::prelude::*;
|
||||
|
||||
use crate::account::Account;
|
||||
use crate::session;
|
||||
|
|
@ -17,7 +15,10 @@ use crate::session;
|
|||
///
|
||||
/// - Siempre inserta [`pagetop::auth::CurrentUser`] (anónimo o autenticado).
|
||||
/// - Si hay sesión activa, inserta también el [`Account`] con roles y permisos.
|
||||
pub(crate) async fn session_middleware(mut req: Request, next: Next) -> Response {
|
||||
pub(crate) async fn session_middleware(
|
||||
mut req: web::Request,
|
||||
next: web::middleware::Next,
|
||||
) -> Response {
|
||||
let (current_user, maybe_account) = session::resolve_session(req.headers()).await;
|
||||
|
||||
req.extensions_mut().insert(current_user);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use pagetop::datetime::Utc;
|
||||
use pagetop::html::SortDir;
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::{
|
||||
ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, Order, Paginated, PaginatorTrait,
|
||||
QueryFilter, QueryOrder, QuerySelect, Set, TransactionTrait, dbconn, flatten_txn_err, paginate,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use pagetop::datetime::Utc;
|
||||
use pagetop::html::SortDir;
|
||||
use pagetop::util;
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::{
|
||||
ActiveModelTrait, ActiveValue, ColumnTrait, Condition, EntityTrait, Order, Paginated,
|
||||
PaginatorTrait, QueryFilter, QueryOrder, Set, TransactionTrait, dbconn, flatten_txn_err,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
//! Generación y verificación de tokens de un solo uso (reset de contraseña, verificación de
|
||||
//! email...).
|
||||
|
||||
use pagetop::datetime::{Duration, Utc};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use pagetop::prelude::*;
|
||||
use pagetop_seaorm::db::{
|
||||
ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, QueryFilter, Set, dbconn,
|
||||
};
|
||||
|
|
@ -11,6 +9,8 @@ use pagetop_seaorm::db::{
|
|||
use crate::entity::user_token;
|
||||
use crate::error::AuthError;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
// **< Generación de tokens >***********************************************************************
|
||||
|
||||
/// Genera un token URL-safe de 43 caracteres (32 bytes -> base64url sin padding).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue