Root a demanda, lanzador de escritorio, captura nueva y ajustes
- Root: no se pide la contraseña al arrancar (echaba para atras). Se pide solo la primera vez que una accion necesita sudo, y se cachea. --candado para el modo seguro. Aviso de root prominente en el README. - install.sh crea un lanzador de escritorio (jarvis.desktop) con el icono naranja: aparece en el menu de aplicaciones para arrancar con un clic. - Captura del panel reemplazada por una mas limpia (solo la ventana). - Quitado "Probado en ..." del README (informacion del equipo). - ventanas.sh: aviso claro segun el compositor en Wayland.
This commit is contained in:
parent
a0b9afe2f9
commit
3a2a1bb111
8 changed files with 118 additions and 33 deletions
|
|
@ -246,6 +246,11 @@ class Panel:
|
|||
# (accion, para_que, hasta_cuando). para_que es "argumento" o "confirmar".
|
||||
self.pendiente = None
|
||||
|
||||
# Root a demanda: las manos avisan aqui cuando una accion necesita sudo
|
||||
# y no hay sesion. En vez de pedir la contraseña al arrancar, se pide
|
||||
# solo entonces, una vez, y se cachea. Ver _pide_root.
|
||||
self.manos.al_pedir_root = self._pide_root
|
||||
|
||||
# -------------------------------------------------------------- empujar
|
||||
|
||||
def arranca(self):
|
||||
|
|
@ -528,6 +533,22 @@ class Panel:
|
|||
self.tareas.lanza(accion, arg)
|
||||
return True
|
||||
|
||||
def _pide_root(self, comando: str = ""):
|
||||
"""Muestra el dialogo de contraseña porque una accion necesita root.
|
||||
|
||||
No es el candado del arranque —eso pedia la contraseña de primeras y
|
||||
echaba para atras—: esto es a demanda, la PRIMERA vez que hace falta
|
||||
sudo en la sesion. La contraseña que se teclee la valida y la cachea
|
||||
_intenta_desbloquear (por el mismo canal "desbloquear"), asi que a
|
||||
partir de ahi el root ya esta abierto y no se vuelve a pedir hasta que
|
||||
caduque. Corre desde el hilo de las manos, asi que solo manda al HUD.
|
||||
"""
|
||||
que = (comando or "").strip()[:60]
|
||||
self.cara.manda("bloqueo", {
|
||||
"mensaje": f"Contraseña para: {que}" if que
|
||||
else "Contraseña de administrador",
|
||||
"root": True})
|
||||
|
||||
def _intenta_desbloquear(self, clave: str):
|
||||
if not clave:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -219,7 +219,10 @@ def escucha(boca: Boca, modelo="small", fuente=None, callado=False,
|
|||
def panel(boca: Boca, cerebro=None, escuchando=False, modelo="small",
|
||||
fuente=None, abre=True, centinela=None, sin_candado=False) -> int:
|
||||
"""Levanta el panel y, si se pide, ademas escucha el microfono."""
|
||||
manos = Manos(catalogo())
|
||||
# Un SOLO Manos, compartido con el cerebro: asi hay una unica sesion de root
|
||||
# y un unico sitio donde pedir la contraseña. Antes el cerebro tenia su Manos
|
||||
# y el panel otro, con roots separados: desbloquear en uno no abria el otro.
|
||||
manos = cerebro.manos if (cerebro and getattr(cerebro, "manos", None)) else Manos(catalogo())
|
||||
cara = Cara()
|
||||
p = Panel(cara, boca, manos, cerebro, candado=not sin_candado,
|
||||
centinela=centinela)
|
||||
|
|
@ -273,8 +276,10 @@ def main() -> int:
|
|||
help="levantar el panel pero no abrir el navegador")
|
||||
p.add_argument("--palabra", action="store_true",
|
||||
help=f"exigir que le llamen «{NOMBRE}» antes de cada orden")
|
||||
p.add_argument("--sin-candado", action="store_true",
|
||||
help="no pedir la contraseña al abrir (solo para probar)")
|
||||
p.add_argument("--candado", action="store_true",
|
||||
help="pedir la contraseña al abrir y bloquear el panel. Por "
|
||||
"defecto NO: no molesta al arrancar, y el root se pide "
|
||||
"solo la primera vez que una accion lo necesita")
|
||||
a = p.parse_args()
|
||||
|
||||
boca = Boca(a.voz or "davefx")
|
||||
|
|
@ -322,7 +327,7 @@ def main() -> int:
|
|||
if a.panel:
|
||||
return panel(boca, cerebro, a.escucha, a.modelo, a.fuente,
|
||||
abre=not a.sin_abrir, centinela=centinela,
|
||||
sin_candado=a.sin_candado)
|
||||
sin_candado=not a.candado)
|
||||
|
||||
if a.escucha:
|
||||
return escucha(boca, a.modelo, a.fuente, a.callado, cerebro,
|
||||
|
|
|
|||
|
|
@ -33,11 +33,14 @@ class Manos:
|
|||
def __init__(self, catalogo=None, al_ejecutar=None):
|
||||
self.catalogo = catalogo or Catalogo([PROPIO, CATALOGO])
|
||||
self.al_ejecutar = al_ejecutar
|
||||
# Root para la sesion: cuando el usuario desbloquea el candado con su
|
||||
# contraseña, esa misma queda aqui y el cerebro puede hacer sudo hasta
|
||||
# que caduque. Sin desbloquear, no hay root: el candado es la puerta.
|
||||
# Root para la sesion: la primera vez que una accion necesita sudo se
|
||||
# pide la contraseña, y queda aqui hasta que caduque (15 min). No se
|
||||
# pide al arrancar: solo cuando de verdad hace falta.
|
||||
from manos.sudo_root import GestorRoot
|
||||
self.root = GestorRoot([])
|
||||
# El panel conecta aqui como pedir la contraseña de root cuando haga
|
||||
# falta (muestra el dialogo). Sin panel (modo terminal) se queda en None.
|
||||
self.al_pedir_root = None
|
||||
|
||||
# ------------------------------------------------------------- catalogo
|
||||
|
||||
|
|
@ -93,8 +96,15 @@ class Manos:
|
|||
# hay contraseña: el root queda cerrado hasta que el usuario desbloquee.
|
||||
if necesita_root(comando):
|
||||
if not self.root.sesion_activa():
|
||||
return ("eso necesita root y el candado no esta abierto. "
|
||||
"Desbloquee con su contraseña y lo repito.")
|
||||
# No hay root todavia: se pide la contraseña AHORA (una vez), no
|
||||
# al arrancar. El panel muestra el dialogo; el usuario la teclea
|
||||
# y repite la orden, que ya correra con la sesion abierta.
|
||||
if self.al_pedir_root:
|
||||
self.al_pedir_root(comando)
|
||||
return ("Esto necesita permiso de administrador, señor. "
|
||||
"Introduzca su contraseña y repitamelo.")
|
||||
return ("eso necesita permiso de administrador y no hay panel "
|
||||
"para pedir la contraseña.")
|
||||
try:
|
||||
r = self.root.ejecuta(comando, timeout=60)
|
||||
except Exception as e:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue