11import datetime
22import json
33import logging
4- from typing import Any , Dict , Tuple , Optional
4+ from typing import Any , Dict , Optional , Tuple
5+ from urllib .parse import urlparse
56
67import aiohttp
78from eth_account .messages import encode_defunct
@@ -39,7 +40,7 @@ def _generate_pubkey_payload(self) -> Dict[str, Any]:
3940 return {
4041 "pubkey" : json .loads (self .ephemeral_key .export_public ()),
4142 "alg" : "ECDSA" ,
42- "domain" : self .node_url ,
43+ "domain" : urlparse ( self .node_url ). netloc ,
4344 "address" : self .account .get_address (),
4445 "expires" : (
4546 datetime .datetime .utcnow () + datetime .timedelta (days = 1 )
@@ -60,36 +61,51 @@ async def _generate_pubkey_signature_header(self) -> str:
6061 "sender" : self .account .get_address (),
6162 "payload" : pubkey_payload ,
6263 "signature" : pubkey_signature ,
63- "content" : {"domain" : self .node_url },
64+ "content" : {"domain" : urlparse ( self .node_url ). netloc },
6465 }
6566 )
6667
67- async def _generate_header (
68- self , vm_id : str , operation : str
69- ) -> Tuple [str , Dict [str , str ]]:
68+ def create_payload (self , vm_id : str , operation : str ) -> Dict [str , str ]:
7069 path = (
7170 f"/logs/{ vm_id } "
7271 if operation == "logs"
7372 else f"/control/machine/{ vm_id } /{ operation } "
7473 )
75-
7674 payload = {
7775 "time" : datetime .datetime .utcnow ().isoformat () + "Z" ,
7876 "method" : "POST" ,
7977 "path" : path ,
8078 }
79+ return payload
80+
81+ def sign_payload (self , payload : Dict [str , str ], ephemeral_key ) -> str :
8182 payload_as_bytes = json .dumps (payload ).encode ("utf-8" )
82- headers = {"X-SignedPubKey" : self .pubkey_signature_header }
8383 payload_signature = JWA .signing_alg ("ES256" ).sign (
84- self . ephemeral_key , payload_as_bytes
84+ ephemeral_key , payload_as_bytes
8585 )
86- headers [ "X-SignedOperation" ] = json .dumps (
86+ signed_operation = json .dumps (
8787 {
8888 "payload" : payload_as_bytes .hex (),
8989 "signature" : payload_signature .hex (),
9090 }
9191 )
92+ return signed_operation
9293
94+ async def _generate_header (
95+ self , vm_id : str , operation : str
96+ ) -> Tuple [str , Dict [str , str ]]:
97+ payload = self .create_payload (vm_id , operation )
98+ signed_operation = self .sign_payload (payload , self .ephemeral_key )
99+
100+ if not self .pubkey_signature_header :
101+ self .pubkey_signature_header = await self .generate_pubkey_signature_header ()
102+
103+ headers = {
104+ "X-SignedPubKey" : self .pubkey_signature_header ,
105+ "X-SignedOperation" : signed_operation ,
106+ }
107+
108+ path = payload ["path" ]
93109 return f"{ self .node_url } { path } " , headers
94110
95111 async def perform_operation (self , vm_id , operation ):
@@ -114,22 +130,24 @@ async def get_logs(self, vm_id):
114130 await self ._generate_pubkey_signature_header ()
115131 )
116132
133+ payload = self .create_payload (vm_id , "logs" )
134+ signed_operation = self .sign_payload (payload , self .ephemeral_key )
135+
117136 ws_url , header = await self ._generate_header (vm_id = vm_id , operation = "logs" )
118137
119- async with aiohttp .ClientSession () as session :
120- async with session .ws_connect (ws_url ) as ws :
121- auth_message = {
122- "auth" : {
123- "X-SignedPubKey" : header ["X-SignedPubKey" ],
124- "X-SignedOperation" : header ["X-SignedOperation" ],
125- }
138+ async with self .session .ws_connect (ws_url ) as ws :
139+ auth_message = {
140+ "auth" : {
141+ "X-SignedPubKey" : self .pubkey_signature_header ,
142+ "X-SignedOperation" : signed_operation ,
126143 }
127- await ws .send_json (auth_message )
128- async for msg in ws : # msg is of type aiohttp.WSMessage
129- if msg .type == aiohttp .WSMsgType .TEXT :
130- yield msg .data
131- elif msg .type == aiohttp .WSMsgType .ERROR :
132- break
144+ }
145+ await ws .send_json (auth_message )
146+ async for msg in ws : # msg is of type aiohttp.WSMessage
147+ if msg .type == aiohttp .WSMsgType .TEXT :
148+ yield msg .data
149+ elif msg .type == aiohttp .WSMsgType .ERROR :
150+ break
133151
134152 async def start_instance (self , vm_id ):
135153 return await self .notify_allocation (vm_id )
0 commit comments