from __future__ import annotations from typing import List import requests from nacl.signing import SigningKey, VerifyKey import base64 import json BASE_URL = "http://localhost:1323/api" class User: def __init__(self, session: Session, name: str) -> None: self.session = session self.name = name self.signing_key = SigningKey.generate() r = requests.post(BASE_URL + f"/{self.session.name}/user", json={ "Name": name, "PublicKey": base64.b64encode(self.signing_key.verify_key.__bytes__()).decode("ascii") }) data = r.json() print(json.dumps(data, indent=4)) def __repr__(self) -> str: return f"User({self.name})" def test_auth(self): r = self.signed_request("/test-auth", { "foo": "bar" }) print(r.content) def guess(self, letter: str): r = self.signed_request("/guess", { "Guess": letter }) print(r.content) def signed_request(self, endpoint: str, body: dict) -> requests.Response: payload = json.dumps(body).encode("utf-8") signature = self.signing_key.sign(payload) return requests.post( url=BASE_URL+f"/{self.session.name}"+endpoint, data=payload, headers={ "Content-Type": "application/json", "signature": base64.b64encode(signature.signature).decode("ascii") } ) class Game: def __init__(self) -> None: self.session_name = input("session: ").strip().lower() if self.session_name == "": data = requests.post(BASE_URL + "/session").json() self.session_name = data["Name"] print(f"playing with session {self.session_name}") self.user_name = input("name: ").strip() self.signing_key = SigningKey.generate() r = requests.post(BASE_URL + f"/{self.session_name}/user", json={ "Name": self.user_name, "PublicKey": base64.b64encode(self.signing_key.verify_key.__bytes__()).decode("ascii") }) self.last_turn = r.json() def __repr__(self) -> str: return f"Game({self.session_name}, {self.user_name})" def print_turn(self, data: dict): print() print(" ".join(c if c != '' else '_' for c in data["Session"]["DiscoveredPhrase"])) print(f"guessed: {','.join(data['Session']['AskedLetters'])}") def guess(self): self.print_turn(self.last_turn) self.send_guess(input(f"{self.user_name}: ").strip()) def send_guess(self, letter: str): data = self.signed_request("/guess", { "Guess": letter }).json() self.last_turn = data def signed_request(self, endpoint: str, body: dict) -> requests.Response: payload = json.dumps(body).encode("utf-8") signature = self.signing_key.sign(payload) return requests.post( url=BASE_URL+f"/{self.session_name}"+endpoint, data=payload, headers={ "Content-Type": "application/json", "signature": base64.b64encode(signature.signature).decode("ascii") } ) if __name__ == "__main__": g = Game() while True: g.guess()