diff --git a/core/validators.py b/core/validators.py new file mode 100644 index 00000000..45fb2339 --- /dev/null +++ b/core/validators.py @@ -0,0 +1,27 @@ +from django.core.exceptions import BadRequest +from solders.pubkey import Pubkey + +from core.utils import Web3Utils + +from .models import Chain, NetworkTypes + + +def address_validator(address, chain: Chain): + is_address_valid = False + if chain.chain_type == NetworkTypes.LIGHTNING: + return + elif chain.chain_type == NetworkTypes.EVM: + try: + Web3Utils.to_checksum_address(address) + return + except ValueError: + is_address_valid = False + elif chain.chain_type == NetworkTypes.SOLANA: + try: + pub_key = Pubkey.from_string(address) + is_address_valid = pub_key.is_on_curve() + except ValueError: + is_address_valid = False + + if not is_address_valid: + raise BadRequest(f"Address: {address} is not valid") diff --git a/faucet/faucet_manager/lnpay_manager/utility_helpers.py b/faucet/faucet_manager/lnpay_manager/utility_helpers.py index 15412191..6d64031a 100644 --- a/faucet/faucet_manager/lnpay_manager/utility_helpers.py +++ b/faucet/faucet_manager/lnpay_manager/utility_helpers.py @@ -1,7 +1,7 @@ -import pprint -import requests import json +import requests + def get_request(location): from .lnpay_main import __ENDPOINT_URL__, __PUBLIC_API_KEY__, __VERSION__ @@ -53,5 +53,4 @@ def post_request(location, params): data = json.dumps(params) r = requests.post(url=endpoint, data=data, headers=headers) - print("salam", r.text) return r.json() diff --git a/faucet/tests.py b/faucet/tests.py index 5fbfaf5b..fb022555 100644 --- a/faucet/tests.py +++ b/faucet/tests.py @@ -451,7 +451,9 @@ def test_claim_max_api_should_fail_if_not_verified(self): def test_claim_max_api_should_claim_all(self): endpoint = reverse("FAUCET:claim-max", kwargs={"chain_pk": self.x_dai.pk}) - response = self.client.post(endpoint, data={"address": "0x12345"}) + response = self.client.post( + endpoint, data={"address": "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"} + ) claim_receipt = json.loads(response.content) self.assertEqual(response.status_code, 200) @@ -463,13 +465,24 @@ def test_claim_max_api_should_claim_all(self): ) def test_claim_max_twice_should_fail(self): endpoint = reverse("FAUCET:claim-max", kwargs={"chain_pk": self.x_dai.pk}) - response_1 = self.client.post(endpoint, data={"address": "0x12345"}) + response_1 = self.client.post( + endpoint, data={"address": "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"} + ) self.assertEqual(response_1.status_code, 200) try: self.client.post(endpoint) except CustomException: self.assertEqual(True, True) + @patch( + "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", + lambda a, b, c: (True, None), + ) + def test_address_validator_evm(self): + endpoint = reverse("FAUCET:claim-max", kwargs={"chain_pk": self.x_dai.pk}) + response_1 = self.client.post(endpoint, data={"address": "0x132546"}) + self.assertEqual(response_1.status_code, 400) + @patch( "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None), diff --git a/faucet/views.py b/faucet/views.py index 11049568..53eac32a 100644 --- a/faucet/views.py +++ b/faucet/views.py @@ -24,6 +24,7 @@ from authentication.models import UserProfile from core.filters import ChainFilterBackend, IsOwnerFilterBackend from core.paginations import StandardResultsSetPagination +from core.validators import address_validator from faucet.faucet_manager.claim_manager import ( ClaimManagerFactory, LimitedChainClaimManager, @@ -203,6 +204,11 @@ def get_chain(self) -> Chain: def get_claim_manager(self): return ClaimManagerFactory(self.get_chain(), self.get_user()).get_manager() + def check_to_address_is_validate(self): + chain = self.get_chain() + to_address = self.request.data.get("address", None) + address_validator(to_address, chain) + def claim_max(self, to_address) -> ClaimReceipt: manager = self.get_claim_manager() max_credit = manager.get_credit_strategy().get_unclaimed() @@ -218,6 +224,7 @@ def claim_max(self, to_address) -> ClaimReceipt: def post(self, request, *args, **kwargs): self.check_user_is_verified() self.to_address_is_provided() + self.check_to_address_is_validate() receipt = self.claim_max(to_address=request.data.get("address")) return Response(ReceiptSerializer(instance=receipt).data)