♻️ (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 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<String>,
/// 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)
}
}

View file

@ -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",

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 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?;

View file

@ -112,7 +112,7 @@ fn search_bar(current_query: Option<String>) -> 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<Vec<(i32, String, bool)>, AuthError> {
let items = role_admin::list_roles(&role_admin::RoleListParams {
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`);
// 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 >**********************************************************************************

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 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<i32> = role_ids.to_vec();
role_ids.push(crate::AUTHENTICATED_ROLE_ID);
let mut role_ids: Vec<i32> = role_ids
.iter()
.copied()
.filter(|id| *id != crate::AUTHENTICATED_ROLE_ID)
.collect();
role_ids.sort_unstable();
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 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;
if !all_role_ids.contains(&AUTHENTICATED_ROLE_ID) {
all_role_ids.push(AUTHENTICATED_ROLE_ID);