#!/usr/bin/env python3.14# -*- coding: utf-8 -*-"""Who is calling: `SO_PEERCRED` → login → identity → profile.The spool authenticates by the **kernel**, not by a header or a token. A connectionon `msg.sock` carries the peer's uid, which the per-user unit already calls theauthoritative identity (web-server-guide § The per-user tier), and this module turnsit into the same `(identity, profile)` pair every other enforcement point uses:1. `SO_PEERCRED` on the accepted socket → the caller's **uid**;2. :mod:`pwd` → its **login name**, which for a collaborator *is* their :func:`~solver.auth.identity.system_slug`;3. `authorizations.json` → the **identity** behind that name, and its **profile**.Step 3 needs no help from the auth service, and that is what keeps this serviceindependent of it: :func:`~solver.auth.identity.system_slug` is a pure SHA-256 of thenormalised e-mail, so recomputing it over every identity in the policy file (which thisservice may read: it is in `euler-authz`) yields the `slug → e-mail` map — the same trick `status-web` uses to label thecollaborator roster. A bare login name (the operator) is looked up directly.The policy is re-read whenever the file's mtime moves, so a `users change` reachesthis service within one request rather than at some next restart — the immediate-revocationrule of § Authorization applies here too.**Boxes.** A message is addressed to a *box key*: a web identity's box is its slug, alocal os-login's box is the login name itself. Both are unique strings in the samenamespace, and using the name the kernel reports means the store never has to hold ane-mail address to route a message."""from__future__importannotations__all__=['PolicyView','box_of','peer_uid']importosimportpwdimportsocketimportstructfrompathlibimportPathfromsolver.auth.authorizationsimportAUTHZ_FILE_ENV,DEFAULT_AUTHZ_FILE,Authorizationsfromsolver.auth.identityimportsystem_slugfromsolver.auth.subjectimportrank#: The floor at which an identity counts as **staff** — the far end of every#: user→staff message, and the only rung that may broadcast.STAFF_FLOOR:str='maintainer'#: `struct ucred` — pid, uid, gid — as returned by `SO_PEERCRED`._UCRED=struct.Struct('3i')defpeer_uid(sock:socket.socket)->int|None:"""The uid on the far end of *sock*, or None if it cannot be read. Unix-socket peer credentials are set by the kernel at `connect()` time and cannot be forged by the peer — which is why nothing on this wire carries a sender field. A non-`AF_UNIX` transport (a dev TCP run) has none. """try:raw=sock.getsockopt(socket.SOL_SOCKET,socket.SO_PEERCRED,_UCRED.size)except(OSError,AttributeError,NameError):returnNone_pid,uid,_gid=_UCRED.unpack(raw)returnint(uid)defbox_of(identity:str)->str:"""The box key for *identity*: a web e-mail's slug, or a bare login unchanged. The one place the mapping is defined. Everything the store holds is keyed by this, so the spool routes by the same name the kernel reports for a connecting uid. """name=identity.strip().lower()returnsystem_slug(name)if'@'innameelsenamedef_policy_path()->Path:"""The policy file this service reads — the same resolution order as the kernel's."""returnPath(os.environ.get(AUTHZ_FILE_ENV)orDEFAULT_AUTHZ_FILE)classPolicyView:"""A cached, box-indexed view of `authorizations.json`. Rebuilt whenever the file's mtime changes (and on the first call), so a profile change lands within one request. A missing or unreadable file yields an empty view: nobody resolves, every gated verb refuses — fail-closed, the same posture as the kernel's own default. """def__init__(self)->None:self._mtime:float=-1.0#: box key → (identity, profile)self._by_box:dict[str,tuple[str,str]]={}def_refresh(self)->None:"""Re-read the policy if its mtime moved (or it appeared / vanished)."""try:mtime=_policy_path().stat().st_mtimeexceptOSError:mtime=0.0ifmtime==self._mtimeandself._by_box:returnself._mtime=mtimeself._by_box={box_of(identity):(identity,profile)foridentity,profileinAuthorizations.load().all_users().items()}defresolve(self,name:str)->tuple[str,str]|None:"""`(identity, profile)` for *name*, or None if the policy maps no such principal. *name* may be either form, because :func:`box_of` collapses them: an OS login (what :mod:`pwd` reports for a connecting uid — a collaborator's slug, or the operator's own login name) or a full web identity (what the admin plane asserts on the operator's behalf). """self._refresh()returnself._by_box.get(box_of(name))defresolve_uid(self,uid:int)->tuple[str,str,str]|None:"""`(box, identity, profile)` for *uid*, or None if it maps to nobody."""try:login=pwd.getpwuid(uid).pw_nameexceptKeyError:returnNonefound=self.resolve(login)returnNoneiffoundisNoneelse(box_of(found[0]),found[0],found[1])defbox_for_identity(self,identity:str)->str|None:"""The box key for a *named* recipient, or None when the policy maps no such identity. A notice may only be addressed to someone the policy knows: an unmapped address would create a box nobody can ever read, and silently accepting it would report success for a message that can never be delivered. """self._refresh()box=box_of(identity)returnboxifboxinself._by_boxelseNonedefstaff_boxes(self)->list[str]:"""Every box at or above :data:`STAFF_FLOOR` — the inbound queue's readers."""self._refresh()floor=rank(STAFF_FLOOR)returnsorted(boxforbox,(_identity,profile)inself._by_box.items()ifrank(profile)>=floor)defall_boxes(self)->list[str]:"""Every box the policy maps — the broadcast recipient set."""self._refresh()returnsorted(self._by_box)defidentity_of(self,box:str)->str:"""The identity behind *box*, or the box key itself when it maps to none. Used for display only (the staff queue names its senders), so an unmapped box — a collaborator removed since they wrote — degrades to its slug rather than dropping the message. """self._refresh()found=self._by_box.get(box)returnfound[0]iffoundisnotNoneelseboxdefis_web(self,box:str)->bool:"""Whether *box* belongs to a web identity — i.e. has a per-user instance to push to."""self._refresh()found=self._by_box.get(box)returnfoundisnotNoneand'@'infound[0]