From 58b4b4e036810b4731c18514f31ded9c5fce1074 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 23 Sep 2026 21:04:00 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20(user):=20El=20rol=20`auth?= =?UTF-8?q?enticated`=20es=20impl=C3=ADcito?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/pagetop-user/src/account.rs | 8 ++++---- extensions/pagetop-user/src/auth.rs | 7 +------ extensions/pagetop-user/src/demo.rs | 2 -- extensions/pagetop-user/src/handlers/admin/users.rs | 2 +- extensions/pagetop-user/src/lib.rs | 2 +- extensions/pagetop-user/src/service/user_admin.rs | 13 +++++++------ extensions/pagetop-user/src/session.rs | 3 ++- 7 files changed, 16 insertions(+), 21 deletions(-) diff --git a/extensions/pagetop-user/src/account.rs b/extensions/pagetop-user/src/account.rs index 54342077..6cf50562 100644 --- a/extensions/pagetop-user/src/account.rs +++ b/extensions/pagetop-user/src/account.rs @@ -66,8 +66,8 @@ pub struct Account { pub email: String, pub display_name: String, pub status: UserStatus, - /// Nombres de máquina de los roles asignados, incluido "authenticated" (se asigna - /// automáticamente a toda cuenta en el alta, ver `auth::assign_role`). + /// Nombres de máquina de los roles asignados explícitamente. No incluye "authenticated", que + /// es implícito (ver [`Account::has_role`]). pub roles: Vec, /// Unión de permisos de todos sus roles. pub permissions: PermissionSet, @@ -90,8 +90,8 @@ impl Account { } } - /// Comprueba si la cuenta tiene el rol indicado. + /// Comprueba si la cuenta tiene el rol indicado ("authenticated" siempre se cumple). pub fn has_role(&self, machine_name: &str) -> bool { - self.roles.iter().any(|r| r == machine_name) + machine_name == "authenticated" || self.roles.iter().any(|r| r == machine_name) } } diff --git a/extensions/pagetop-user/src/auth.rs b/extensions/pagetop-user/src/auth.rs index ece3800f..67d21aa6 100644 --- a/extensions/pagetop-user/src/auth.rs +++ b/extensions/pagetop-user/src/auth.rs @@ -147,8 +147,6 @@ pub async fn register( let result = user::Entity::insert(new_user).exec(dbconn()).await?; let user_id = result.last_insert_id; - assign_role(user_id, crate::AUTHENTICATED_ROLE_ID).await?; - Ok(user_id) } @@ -259,10 +257,7 @@ async fn do_seed() { }; match user::Entity::insert(new_admin).exec(dbconn()).await { - Ok(result) => { - if let Err(e) = assign_role(result.last_insert_id, crate::AUTHENTICATED_ROLE_ID).await { - eprintln!("pagetop-user seed error: {}", e); - } + Ok(_) => { if generated { println!( "\npagetop-user: admin account created.\n username: {}\n password: {}\n", diff --git a/extensions/pagetop-user/src/demo.rs b/extensions/pagetop-user/src/demo.rs index dd9935e7..bc9fd568 100644 --- a/extensions/pagetop-user/src/demo.rs +++ b/extensions/pagetop-user/src/demo.rs @@ -102,8 +102,6 @@ async fn create_demo_users(role_ids: &[i32]) -> Result<(), AuthError> { let result = user::Entity::insert(new_user).exec(dbconn()).await?; let user_id = result.last_insert_id; - auth::assign_role(user_id, crate::AUTHENTICATED_ROLE_ID).await?; - // Reparte los usuarios de forma cíclica entre los roles de demostración. let role_id = role_ids[(n - 1) % role_ids.len()]; auth::assign_role(user_id, role_id).await?; diff --git a/extensions/pagetop-user/src/handlers/admin/users.rs b/extensions/pagetop-user/src/handlers/admin/users.rs index f3b833df..c757fc35 100644 --- a/extensions/pagetop-user/src/handlers/admin/users.rs +++ b/extensions/pagetop-user/src/handlers/admin/users.rs @@ -112,7 +112,7 @@ fn search_bar(current_query: Option) -> Html { // **< available_roles >**************************************************************************** // Roles asignables desde la UI de usuarios: excluye "anonymous" (nunca se asigna explícitamente) -// y "authenticated" (se envía siempre fijo vía campo oculto). +// y "authenticated" (implícito, nunca se asigna). async fn available_roles(selected: &[i32]) -> Result, AuthError> { let items = role_admin::list_roles(&role_admin::RoleListParams { sort: role_admin::RoleSortField::Weight, diff --git a/extensions/pagetop-user/src/lib.rs b/extensions/pagetop-user/src/lib.rs index 781a1cff..a4607e2c 100644 --- a/extensions/pagetop-user/src/lib.rs +++ b/extensions/pagetop-user/src/lib.rs @@ -182,7 +182,7 @@ fn declare_admin_pages(bag: &mut PageBag) { // Sembrados con id fijo en `migration/m20260629_000002_create_roles.rs` y bloqueados (`locked`); // no se borran ni cambian de id. const ANONYMOUS_ROLE_ID: i32 = 1; -// Se asigna automáticamente a toda cuenta en el alta (ver `auth::assign_role`). +// Implícito: nunca se asigna en `user_role`; sus permisos se aplican a toda cuenta autenticada. const AUTHENTICATED_ROLE_ID: i32 = 2; // **< Extension >********************************************************************************** diff --git a/extensions/pagetop-user/src/service/user_admin.rs b/extensions/pagetop-user/src/service/user_admin.rs index 58aa35ed..468641d8 100644 --- a/extensions/pagetop-user/src/service/user_admin.rs +++ b/extensions/pagetop-user/src/service/user_admin.rs @@ -200,7 +200,6 @@ pub(crate) async fn create_user(data: NewUserData<'_>) -> Result let result = user::Entity::insert(new_user).exec(dbconn()).await?; let user_id = result.last_insert_id; - crate::auth::assign_role(user_id, crate::AUTHENTICATED_ROLE_ID).await?; for role_id in data.initial_role_ids { crate::auth::assign_role(user_id, *role_id).await?; } @@ -242,14 +241,16 @@ pub(crate) async fn update_user(user_id: i32, data: UserUpdateData<'_>) -> Resul /// Reemplaza por completo el conjunto de roles asignados a un usuario. /// -/// "authenticated" ([`crate::AUTHENTICATED_ROLE_ID`]) se reintroduce siempre, esté o no en -/// `role_ids`: la UI no lo ofrece como casilla (ver `available_roles()`), pero toda cuenta -/// activa lo tiene concedido por definición y debe seguir apareciendo en `Account.roles`. +/// "authenticated" ([`crate::AUTHENTICATED_ROLE_ID`]) nunca se almacena: es implícito para toda +/// cuenta autenticada, por lo que se descarta si llega en `role_ids`. pub(crate) async fn set_user_roles(user_id: i32, role_ids: &[i32]) -> Result<(), AuthError> { find_user(user_id).await?; - let mut role_ids: Vec = role_ids.to_vec(); - role_ids.push(crate::AUTHENTICATED_ROLE_ID); + let mut role_ids: Vec = role_ids + .iter() + .copied() + .filter(|id| *id != crate::AUTHENTICATED_ROLE_ID) + .collect(); role_ids.sort_unstable(); role_ids.dedup(); diff --git a/extensions/pagetop-user/src/session.rs b/extensions/pagetop-user/src/session.rs index a7a2b14b..b0555a43 100644 --- a/extensions/pagetop-user/src/session.rs +++ b/extensions/pagetop-user/src/session.rs @@ -130,7 +130,8 @@ pub async fn load_user_from_session(sid: &str) -> (CurrentUser, Option) let is_admin = user_model.is_admin; let role_names: Vec = role_rows.iter().map(|r| r.machine_name.clone()).collect(); - // Cargar permisos de todos los roles (incluido "authenticated", siempre asignado). + // Cargar permisos de todos los roles más los del rol implícito "authenticated", que no se + // asigna en `user_role` pero se aplica siempre. let mut all_role_ids = role_ids; if !all_role_ids.contains(&AUTHENTICATED_ROLE_ID) { all_role_ids.push(AUTHENTICATED_ROLE_ID);