#!/usr/bin/env python3.14# -*- coding: utf-8 -*-"""The message admin plane CLI: run **under sudo** by the `msg` shell command.The spool's public socket is `0660 euler-msg:euler-web`, and the operator's own uid isdeliberately **not** in `euler-web` — that group is for the service tier, and puttingthe host's most exposed uid in it would hand every browser and dev tool on the box aconnection to the app plane. So the operator reaches the spool the same way they reachthe auth service: as root, via `sudo`, over the `0600` admin socket, with the tokenthat lives only in root-readable `/etc/euler/msg.env`.This is a **thin authenticated proxy**, not a second command surface: it takes a methodand an admin path, injects the invoking identity, and prints the service's reply as oneJSON line. One renderer (in :mod:`euler_webshell.msg.commands`) then serves both channels,so the terminal and the web shell cannot drift in what they show.Two details are deliberate:- **The body arrives on stdin**, never in `argv`. A message body in the process table would be readable by every uid on the host via `/proc`, which is precisely the exposure the spool exists to avoid.- **The identity is the invoking user** (`SUDO_USER`), not an argument. Root could assert anything here — the point is that a typo cannot file a message under a stranger's name, and the profile check still runs against `authorizations.json`.Invocation (see :mod:`euler_webshell.msg.commands` for the shell wrapper):: echo '{"body": "…"}' | sudo <venv-python> -m euler_webshell.msg.admin api POST /admin/…"""from__future__importannotations__all__=['main']importgetpassimportjsonimportosimportsysfrompathlibimportPathfromtypingimportAnyfromeuler_site.envfileimportenv_file_valuesfromsolver.config.envimportload_specfromeuler_site.unixhttpimportrequest_METHODS=('GET','POST','DELETE')def_fail(message:str,code:int=1)->int:print(f'error: {message}',file=sys.stderr)returncodedef_invoking_identity()->str:"""The operator behind the sudo: `SUDO_USER`, else this process's own login."""who=os.environ.get('SUDO_USER','').strip()ifwho:returnwhotry:returngetpass.getuser()exceptOSError:return''def_api(method:str,path:str,body:dict[str,Any])->tuple[int,dict[str,Any]|str]:"""One call to the euler-msg admin socket, with the token from the scoped env file."""env_file=env_file_values(Path(os.environ.get('EULER_MSG_ENV','/etc/euler/msg.env')))token=os.environ.get('EULER_MSG_ADMIN_TOKEN')orenv_file.get('EULER_MSG_ADMIN_TOKEN','')admin_socket=load_spec('msg').entries['admin_socket_path']socket_path=(os.environ.get(admin_socket.env_var)orenv_file.get(admin_socket.env_var)oradmin_socket.default)ifnottoken:raiseRuntimeError('EULER_MSG_ADMIN_TOKEN not found ''(is /etc/euler/msg.env deployed, and are you root?)')returnrequest(socket_path,method,path,body=bodyorNone,headers={'X-Admin-Token':token},timeout=15.0)defmain(argv:list[str])->int:iflen(argv)<3orargv[0]!='api'orargv[1]notin_METHODS:print(f'usage: python -m euler_webshell.msg.admin api {{{"|".join(_METHODS)}}} <admin-path> ''(JSON body on stdin)',file=sys.stderr)return2method,path=argv[1],argv[2]ifnotpath.startswith('/admin/'):return_fail('only /admin/* paths are reachable from this CLI')raw=sys.stdin.read().strip()ifnotsys.stdin.isatty()else''try:body:Any=json.loads(raw)ifrawelse{}exceptjson.JSONDecodeError:return_fail('malformed JSON body on stdin')ifnotisinstance(body,dict):return_fail('the body must be a JSON object')identity=_invoking_identity()ifnotidentity:return_fail('could not determine the invoking identity')body['identity']=identity# Also on the query string: the service reads the body first and falls back to the# query, and a GET carrying a body is the odd shape of the two.joiner='&'if'?'inpathelse'?'path=f'{path}{joiner}identity={identity}'try:status,data=_api(method,path,body)exceptTimeoutError:return_fail('timed out waiting for the message service')except(OSError,RuntimeError)asexc:return_fail(f'message admin plane error ({exc}) — ''is euler-msg.service running, and are you root?')print(json.dumps({'status':status,'body':data}))return0if__name__=='__main__':raiseSystemExit(main(sys.argv[1:]))