⎇ 3dc85ebdcdd5fda0a1be0db5f8fbce5859266f2e
shared/auth/auth-core/src/user.rs
Ñawpa willay
Pi imata llamkarqan
ch'uya
feat: mirada standalone — compositor Wayland + WM sobre Llimphi (build magro)
1//! Resolución de la identidad de un usuario del sistema.
2
3use std::path::PathBuf;
4
5use crate::AuthError;
6
7/// Identidad de un usuario en el sistema: lo que el compositor necesita
8/// para arrancar una sesión — fijar uid/gid, `cd` al home, ejecutar el
9/// shell o la sesión de escritorio.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct UserInfo {
12 /// Nombre de login.
13 pub name: String,
14 /// User ID.
15 pub uid: u32,
16 /// Group ID primario.
17 pub gid: u32,
18 /// Directorio personal.
19 pub home: PathBuf,
20 /// Shell de login.
21 pub shell: PathBuf,
22}
23
24impl UserInfo {
25 /// Identidad sintética para tests y para cajas donde el usuario no
26 /// está en `/etc/passwd`. **No** representa a un usuario real del SO
27 /// — no usar para fijar privilegios de un proceso real.
28 pub fn synthetic(name: &str) -> Self {
29 Self {
30 name: name.to_string(),
31 uid: 1000,
32 gid: 1000,
33 home: PathBuf::from(format!("/home/{name}")),
34 shell: PathBuf::from("/bin/sh"),
35 }
36 }
37}
38
39/// Resuelve un usuario por nombre vía `getpwnam`. `Err` si no existe o
40/// si la consulta a `/etc/passwd` (o NSS) falla.
41pub fn resolve_user(name: &str) -> Result<UserInfo, AuthError> {
42 match nix::unistd::User::from_name(name) {
43 Ok(Some(u)) => Ok(UserInfo {
44 name: u.name,
45 uid: u.uid.as_raw(),
46 gid: u.gid.as_raw(),
47 home: u.dir,
48 shell: u.shell,
49 }),
50 Ok(None) => Err(AuthError::UnresolvedUser(name.to_string())),
51 Err(e) => Err(AuthError::Pam(format!("getpwnam({name}): {e}"))),
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn resolves_root() {
61 // root (uid 0) existe en todo sistema Unix.
62 let info = resolve_user("root").expect("root debe existir");
63 assert_eq!(info.uid, 0);
64 assert_eq!(info.name, "root");
65 }
66
67 #[test]
68 fn unknown_user_errs() {
69 let r = resolve_user("usuario-que-no-existe-xyzzy");
70 assert!(matches!(r, Err(AuthError::UnresolvedUser(_))));
71 }
72
73 #[test]
74 fn synthetic_has_home_under_slash_home() {
75 let info = UserInfo::synthetic("prueba");
76 assert_eq!(info.home, PathBuf::from("/home/prueba"));
77 assert_eq!(info.uid, 1000);
78 }
79}