+
    jHàjÄ  ã                  ó¾   € R t ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RIH	t	H
t
 ^@tRt]P                  ! R4      tR R	 ltRR
 R lltR R ltRR R llt ! R R4      tR# )a¯  Copy and owner-side signalling for unauthorized inbound senders.

Two audiences, two rules:

* The **stranger** gets either a pairing code (behaviour ``pair``) or nothing at all (behaviour
  ``ignore``: an allowlist is configured, so any reply would leak that the bot exists).
* The **owner** is the one who can fix a mis-typed allowlist, so an ignored DM is logged at
  WARNING with the sender's ID and the allowlist / pairing-mode fix, and surfaced once per
  (platform, user) per gateway process in the platform's home channel when one is configured.
  No pairing request is minted for an ignored sender: strangers must not create server state
  when the owner has restricted access.
)ÚannotationsN)ÚOrderedDict©Út)ÚCODE_TTL_SECONDSÚ_allowlist_env_for_platformi   zgateway.runc               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚstr© )Úformats   "ÚE/home/ubuntu/.hermes/hermes-agent/gateway/run_inbound_unauthorized.pyÚ__annotate__r       s   € ÷ ñ ¨#ñ ó    c                óv   € \        V RR4      p\        V\        4      '       d   V'       d   VR8w  d   RV R2# R# )zO``-p <profile> `` when the store belongs to a non-default profile, else ``""``.ÚprofileNÚdefaultz-p Ú Ú )ÚgetattrÚ
isinstancer   )Úpairing_storeÚstore_profiles   & r   Úpairing_profile_argr       s8   € ä˜M¨9°dÓ;€MÜ�-¤×%Ò%¯-¸MÈYÔ<VØ�]�O 1Ð%Ð%Ùr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r
   Úplatform_namer   ÚcodeÚprofile_argr   r   )r   s   "r   r   r   (   s/   € ÷ bñ b cð b°ð bÀ3ð bÐPSñ br   c                óŽ   € \        ^\        R,          4      p\        V^8X  d   RMRVR7      pRV RV  RV 2p\        RWVR	7      # )
z¯The DM a first-time sender receives: what happened, how long the code lives, what to do
whether they are the owner or a guest, and that they must message again after approval.i  zgateway.pairing.validity_hourzgateway.pairing.validity_hours)Úhourszhermes zpairing approve r   zgateway.pairing.code_reply)r   ÚvalidityÚapprove_cmd)Úmaxr   r   )r   r   r   r!   r"   r#   s   &&&   r   Úpairing_code_replyr%   (   sW   € ô �Ô# tÕ+Ó,€EÜ°E¸Q´JÑ0ÐDdÐlqÔr€HØ˜K˜=Ð(8¸¸ÀqÈÈÐO€KÜÐ)°ÐU`ÔaÐar   c               ó   € V ^8„  d   QhRR/# r	   r   )r   s   "r   r   r   1   s   € ÷ -ñ - Cñ -r   c                 ó   € \        R 4      # )zgateway.pairing.rate_limitedr   r   r   r   Úpairing_rate_limited_replyr(   1   s   € ÜÐ+Ó,Ð,r   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )r
   r   r   Úuser_idÚ	user_nameÚhermes_homer   r   )r   s   "r   r   r   5   s;   € ÷ zñ zØðzØ!$ðzØ14ðzØKNðzàñzr   c               ó2  € ^ RI Hp T! T;'       g    R\        R7      pRP                  R V 4       4      P	                  4       pV'       d	   V RV R2M
\        V4      p\        V 4      pV'       d   \        RWsR7      M
\        R	4      p\        R
WWƒR7      # )a"  One-line hint for the owner (log + home channel): who was dropped and how to let them in.
No pairing request is minted for an ignored sender (a configured allowlist means the owner chose
to restrict access), so the ways in are the allowlist itself or switching the platform to
pairing mode.)Ú neutralize_untrusted_inline_textr   )Ú	max_charsc              3  ó6   "  € T F  qR 9  g   K  Vx € K  	  R# 5i)z@<>[]()`*_~#Nr   )Ú.0Úchs   & r   Ú	<genexpr>Ú*unauthorized_owner_hint.<locals>.<genexpr>A   s   é € ÐK¡Y˜r¸NÑ2JŸš£Yùs   ‚�
z (Ú)z#gateway.unauthorized.owner_hint_env)Úenv_varÚhomez'gateway.unauthorized.owner_hint_genericz!gateway.unauthorized.owner_notice)ÚplatformÚwhoÚ	allowlistr7   )Úgateway.sessionr.   Ú_MAX_SENDER_NAME_CHARSÚjoinÚstripr   r   r   )	r   r*   r+   r,   r.   Ú	safe_namer9   r6   r:   s	   &&&$     r   Úunauthorized_owner_hintr@   5   s‘   € õ Aá0°·°¸bÔLbÔc€Ið —‘ÑK¡YÓKÓK×QÑQÓS€Iß(1ˆYˆK�r˜'˜ !Ñ
$´s¸7³|€CÜ)¨-Ó8€G÷ ô 	
Ð
/¸ÕSÜÐCÓDð ô Ð0¸=Ð]fÔyÐyr   c                  óD   € ] tR t^KtRt]3R R lltR R ltR R ltRt	R	# )
ÚUnauthorizedOwnerNotifiera  Tells the owner's home channel about the first drop of each unrecognized DM sender.

One notice per (platform, user_id) per gateway process: the first drop is the useful signal (an
owner who typo'd their own ID); repeats would only let a stranger spam the home channel.
c               ó    € V ^8„  d   QhRRRR/# )r
   Úmax_seenÚintr   ÚNoner   )r   s   "r   r   Ú&UnauthorizedOwnerNotifier.__annotate__R   s   € ÷ /ñ / ð /¸Tñ /r   c                	óX   € \        4       V n        \        ^\        V4      4      V n        R# )é   N)r   Ú_seenr$   rE   Ú	_max_seen)ÚselfrD   s   &&r   Ú__init__Ú"UnauthorizedOwnerNotifier.__init__R   s   € Ü9D»ˆŒ
Ü˜Q¤ H£Ó.ˆŽr   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   r   r   r*   r   Úboolr   )r   s   "r   r   rG   V   s!   € ÷ ñ ¨ð °cð ¸dñ r   c                	ó  € V\        V4      3pW0P                  9   d   V P                  P                  V4       R # RV P                  V&   \        V P                  4      V P                  8”  d   V P                  P                  R R7       KB  R# )FN)ÚlastT)r   rJ   Úmove_to_endÚlenrK   Úpopitem)rL   r   r*   Úkeys   &&& r   Ú
first_timeÚ$UnauthorizedOwnerNotifier.first_timeV   sh   € Øœc '›lÐ+ˆØ—*‘*ÔØ�J‰J×"Ñ" 3Ô'ÙØˆ�
‰
�3‰Ü�$—*‘*‹o §¡Ô.Ø�J‰J×Ñ EÐÖ*Ùr   c               ó    € V ^8„  d   QhRRRR/# )r
   Úhintr   r   rF   r   )r   s   "r   r   rG   `   s   € ÷ ñ °ð ¸ñ r   c              ƒ  ó  aaaaa"  € SP                  4        Fl  w  opooSVP                  8w  d   K  \        SP                  4      \        VP                  4      8X  d    R# ^ RIHp V! VVVVV3R lSR7      G Rj  x€L
   R# 	  R#  L5i)zWBest-effort post to the source platform's home channel; silent when none is configured.N)Úpresent_notificationc                 ó4   <€ SP                  SSSR S  2R4      # )u   âš ï¸� z/unauthorized-sender notice failed for %s:%s: %s)Ú_send_home_channel_message)rZ   r7   r8   ÚrunnerÚ	transports   €€€€€r   Ú<lambda>Ú2UnauthorizedOwnerNotifier.notify.<locals>.<lambda>l   s#   ø€ ˜×9Ñ9Ø˜d I°¸¸Ð/?ÐArôr   )r8   )Ú_home_channel_transportsr8   r   Úchat_idÚgateway.warning_notificationsr\   )	rL   r_   ÚsourcerZ   Ú_cfgr\   r7   r8   r`   s	   &f&f  @@@r   ÚnotifyÚ UnauthorizedOwnerNotifier.notify`   s   üé € à/5×/NÑ/NÖ/PÑ+ˆH�d˜D )Ø˜6Ÿ?™?Ô*ÙÜ�4—<‘<Ó ¤C¨¯©Ó$7Ô7ò åJÙ&÷ð ð "ô	÷ ð ò ó 0Qñùs   ‡A7BÁ>B
Á?B)rK   rJ   N)
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú_MAX_SEEN_SENDERSrM   rW   rh   Ú__static_attributes__r   r   r   rB   rB   K   s    † ñð (9÷ /õ÷ñ r   rB   )r   )rn   Ú
__future__r   ÚloggingÚcollectionsr   Ú
agent.i18nr   Úgateway.pairingr   r   r<   ro   Ú	getLoggerÚloggerr   r%   r(   r@   rB   r   r   r   Ú<module>rx      s[   ðñõ #ã Ý #å ß Ið Ð ð Ð à	×	Ò	˜=Ó	)€õ÷bõ-÷z÷,&ó &r   