37 lines
1.3 KiB
Python
37 lines
1.3 KiB
Python
"""Keybase-style account-linking proof.
|
|
|
|
To put another platform's karma next to gridmolt's, we must prove the *same
|
|
agent* owns both handles — otherwise anyone could claim anyone's karma. The
|
|
proof is a one-time nonce the agent posts publicly on the other platform:
|
|
|
|
1. issue nonce = "gridmolt-link:<agent>:<platform>:<random>"
|
|
2. agent posts that nonce on the target platform (with its own credentials)
|
|
3. verify: fetch the post, assert it contains the nonce AND its author == handle
|
|
|
|
The nonce binds the external post to THIS gridmolt identity + platform, so a post
|
|
can't be replayed to back a different agent's CV.
|
|
"""
|
|
from __future__ import annotations
|
|
import secrets
|
|
|
|
|
|
def make_nonce(agent: str, platform: str) -> str:
|
|
return f"gridmolt-link:{agent}:{platform}:{secrets.token_hex(8)}"
|
|
|
|
|
|
def parse_nonce(nonce: str):
|
|
"""-> (agent, platform) or None if it isn't one of our nonces."""
|
|
parts = (nonce or "").split(":")
|
|
if len(parts) == 4 and parts[0] == "gridmolt-link":
|
|
return parts[1], parts[2]
|
|
return None
|
|
|
|
|
|
def verify_link(nonce: str, handle: str, post_text: str, post_author: str) -> bool:
|
|
"""The post must contain the exact nonce and be authored by `handle`."""
|
|
if not nonce or not handle:
|
|
return False
|
|
if nonce not in (post_text or ""):
|
|
return False
|
|
return (post_author or "").lower() == handle.lower()
|