# Sample code, software libraries, command line tools, proofs of concept, templates, or other related technology are provided as AWS Content or Third-Party Content under the AWS Customer Agreement, or the relevant written agreement between you and AWS (whichever applies). You should not use this AWS Content or Third-Party Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the AWS Content or Third-Party Content, such as sample code, as appropriate for production grade use based on your specific quality control practices and standards. Deploying AWS Content or Third-Party Content may incur AWS charges for creating or using AWS chargeable resources, such as running Amazon EC2 instances or using Amazon S3 storage.

import os,web3,json
from web3.auto import w3
from web3 import Web3, HTTPProvider
from eth_account.messages import encode_defunct

# Polygon Mumbai params
CHAIN_ID = os.environ['CHAIN_ID']
RPC_ENDPOINT = os.environ['RPC_ENDPOINT']

# Contract params
CONTRACT_ADDRESS = os.environ['CONTRACT_ADDRESS']
CONTRACT_ABI = """
[
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "approved_submitter",
				"type": "address"
			},
			{
				"internalType": "string",
				"name": "ipfs_cid",
				"type": "string"
			}
		],
		"name": "add_to_training_set",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "owner",
				"type": "address"
			}
		],
		"name": "OwnableInvalidOwner",
		"type": "error"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "account",
				"type": "address"
			}
		],
		"name": "OwnableUnauthorizedAccount",
		"type": "error"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "previousOwner",
				"type": "address"
			},
			{
				"indexed": true,
				"internalType": "address",
				"name": "newOwner",
				"type": "address"
			}
		],
		"name": "OwnershipTransferred",
		"type": "event"
	},
	{
		"inputs": [],
		"name": "renounceOwnership",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "newOwner",
				"type": "address"
			}
		],
		"name": "transferOwnership",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "approved_submitter",
				"type": "address"
			}
		],
		"name": "get_from_training_set",
		"outputs": [
			{
				"internalType": "string",
				"name": "",
				"type": "string"
			}
		],
		"stateMutability": "view",
		"type": "function"
	},
	{
		"inputs": [],
		"name": "owner",
		"outputs": [
			{
				"internalType": "address",
				"name": "",
				"type": "address"
			}
		],
		"stateMutability": "view",
		"type": "function"
	}
]
"""

def handler(event, context):
    params = event['queryStringParameters']
    print("Received those params:",params)
    
    cid = params['cid']
    sig = params['signature']
    message = encode_defunct(text=params['message'])
    signer_address = (w3.eth.account.recover_message(message, signature=sig)).lower()
    
    print("Message has been signed by this address:", signer_address)
  
    print("Will now check if this address has a mapping with the provided CID.")
    
    print("Connecting to web3 endpoint")
    web3 = Web3(HTTPProvider(RPC_ENDPOINT))
    
    print("Loading contract definition")
    abi= json.loads(CONTRACT_ABI)
    
    print("Loading contract")
    contract = web3.eth.contract(Web3.to_checksum_address(CONTRACT_ADDRESS), abi=abi)
    
    print("Querying contract")
    address = Web3.to_checksum_address(signer_address)
    allowed_cid = contract.functions.get_from_training_set(address).call()
    print("IPFS CID from {}: {}".format(signer_address, allowed_cid))
    
    response = {
        "isAuthorized": True,
        "context": {
            "signer": signer_address, "expected_cid": cid, "allowed_cid": allowed_cid
        }
    }
    
    if allowed_cid == cid:
        print("Authorization granted. Expected CID \"{}\" matches with Smart Contract data \"{}\"".format(cid,allowed_cid))
    else:
        print("ERROR: expected CID \"{}\" does not match with Smart Contract data \"{}\"".format(cid,allowed_cid))
        response["isAuthorized"] = False

    return response
    


