tawasuyu

tawasuyu/mirada

Sovereign tiling Wayland compositor + window manager in Rust, on Llimphi.

Rust 50Markdown 30TOML 211282 Sutichaykuna

⎇ 3dc85ebdcdd5fda0a1be0db5f8fbce5859266f2e shared/auth/auth-core/src/user.rs Rust · 79 siq'ikuna · 2.3 KB Ñawpa willay Pi imata llamkarqan ch'uya

feat: mirada standalone — compositor Wayland + WM sobre Llimphi (build magro) 3dc85ebdc · Sergio ·

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}