♻️ (user): El rol authenticated es implícito

This commit is contained in:
Manuel Cillero 2026-09-23 21:04:00 +02:00
parent 1254e650f1
commit 58b4b4e036
7 changed files with 16 additions and 21 deletions

View file

@ -66,8 +66,8 @@ pub struct Account {
pub email: String, pub email: String,
pub display_name: String, pub display_name: String,
pub status: UserStatus, pub status: UserStatus,
/// Nombres de máquina de los roles asignados, incluido "authenticated" (se asigna /// Nombres de máquina de los roles asignados explícitamente. No incluye "authenticated", que
/// automáticamente a toda cuenta en el alta, ver `auth::assign_role`). /// es implícito (ver [`Account::has_role`]).
pub roles: Vec<String>, pub roles: Vec<String>,
/// Unión de permisos de todos sus roles. /// Unión de permisos de todos sus roles.
pub permissions: PermissionSet, 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 { 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)
} }
} }

View file

@ -147,8 +147,6 @@ pub async fn register(
let result = user::Entity::insert(new_user).exec(dbconn()).await?; let result = user::Entity::insert(new_user).exec(dbconn()).await?;
let user_id = result.last_insert_id; let user_id = result.last_insert_id;
assign_role(user_id, crate::AUTHENTICATED_ROLE_ID).await?;
Ok(user_id) Ok(user_id)
} }
@ -259,10 +257,7 @@ async fn do_seed() {
}; };
match user::Entity::insert(new_admin).exec(dbconn()).await { match user::Entity::insert(new_admin).exec(dbconn()).await {
Ok(result) => { Ok(_) => {
if let Err(e) = assign_role(result.last_insert_id, crate::AUTHENTICATED_ROLE_ID).await {
eprintln!("pagetop-user seed error: {}", e);
}
if generated { if generated {
println!( println!(
"\npagetop-user: admin account created.\n username: {}\n password: {}\n", "\npagetop-user: admin account created.\n username: {}\n password: {}\n",

View file

@ -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 result = user::Entity::insert(new_user).exec(dbconn()).await?;
let user_id = result.last_insert_id; 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. // Reparte los usuarios de forma cíclica entre los roles de demostración.
let role_id = role_ids[(n - 1) % role_ids.len()]; let role_id = role_ids[(n - 1) % role_ids.len()];
auth::assign_role(user_id, role_id).await?; auth::assign_role(user_id, role_id).await?;

View file

@ -112,7 +112,7 @@ fn search_bar(current_query: Option<String>) -> Html {
// **< available_roles >**************************************************************************** // **< available_roles >****************************************************************************
// Roles asignables desde la UI de usuarios: excluye "anonymous" (nunca se asigna explícitamente) // 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<Vec<(i32, String, bool)>, AuthError> { async fn available_roles(selected: &[i32]) -> Result<Vec<(i32, String, bool)>, AuthError> {
let items = role_admin::list_roles(&role_admin::RoleListParams { let items = role_admin::list_roles(&role_admin::RoleListParams {
sort: role_admin::RoleSortField::Weight, sort: role_admin::RoleSortField::Weight,

View file

@ -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`); // Sembrados con id fijo en `migration/m20260629_000002_create_roles.rs` y bloqueados (`locked`);
// no se borran ni cambian de id. // no se borran ni cambian de id.
const ANONYMOUS_ROLE_ID: i32 = 1; 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; const AUTHENTICATED_ROLE_ID: i32 = 2;
// **< Extension >********************************************************************************** // **< Extension >**********************************************************************************

View file

@ -200,7 +200,6 @@ pub(crate) async fn create_user(data: NewUserData<'_>) -> Result<i32, AuthError>
let result = user::Entity::insert(new_user).exec(dbconn()).await?; let result = user::Entity::insert(new_user).exec(dbconn()).await?;
let user_id = result.last_insert_id; 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 { for role_id in data.initial_role_ids {
crate::auth::assign_role(user_id, *role_id).await?; 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. /// Reemplaza por completo el conjunto de roles asignados a un usuario.
/// ///
/// "authenticated" ([`crate::AUTHENTICATED_ROLE_ID`]) se reintroduce siempre, esté o no en /// "authenticated" ([`crate::AUTHENTICATED_ROLE_ID`]) nunca se almacena: es implícito para toda
/// `role_ids`: la UI no lo ofrece como casilla (ver `available_roles()`), pero toda cuenta /// cuenta autenticada, por lo que se descarta si llega en `role_ids`.
/// activa lo tiene concedido por definición y debe seguir apareciendo en `Account.roles`.
pub(crate) async fn set_user_roles(user_id: i32, role_ids: &[i32]) -> Result<(), AuthError> { pub(crate) async fn set_user_roles(user_id: i32, role_ids: &[i32]) -> Result<(), AuthError> {
find_user(user_id).await?; find_user(user_id).await?;
let mut role_ids: Vec<i32> = role_ids.to_vec(); let mut role_ids: Vec<i32> = role_ids
role_ids.push(crate::AUTHENTICATED_ROLE_ID); .iter()
.copied()
.filter(|id| *id != crate::AUTHENTICATED_ROLE_ID)
.collect();
role_ids.sort_unstable(); role_ids.sort_unstable();
role_ids.dedup(); role_ids.dedup();

View file

@ -130,7 +130,8 @@ pub async fn load_user_from_session(sid: &str) -> (CurrentUser, Option<Account>)
let is_admin = user_model.is_admin; let is_admin = user_model.is_admin;
let role_names: Vec<String> = role_rows.iter().map(|r| r.machine_name.clone()).collect(); let role_names: Vec<String> = 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; let mut all_role_ids = role_ids;
if !all_role_ids.contains(&AUTHENTICATED_ROLE_ID) { if !all_role_ids.contains(&AUTHENTICATED_ROLE_ID) {
all_role_ids.push(AUTHENTICATED_ROLE_ID); all_role_ids.push(AUTHENTICATED_ROLE_ID);