Skip to content

Commit

Permalink
fix: fix data source to get data from biography
Browse files Browse the repository at this point in the history
  • Loading branch information
dadamu committed Jul 17, 2023
1 parent a543650 commit 73ad5d5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
47 changes: 35 additions & 12 deletions data-sources/instagram.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
import json
import sys
import urllib.parse
import requests
import re
from typing import Optional
import cryptography.hazmat.primitives.asymmetric.utils as crypto
from cryptography.hazmat.primitives.asymmetric import ec
Expand Down Expand Up @@ -34,15 +34,26 @@ def __init__(self, address: str, pub_key: str, value: str, signature: str):
self.value = value


def get_user_data(data: CallData) -> Optional[VerificationData]:
def get_urls_from_biography(user: str) -> [str]:
"""
Tries getting the verification data for the user having the given Instagram username.
:param data: Data used to get the VerificationData
:return: An OptionalData object if the call was successful, or None if it errored somehow.
Returns all the URLs that are found inside the biography of the user having the given user username.
:param user: Username of the Instagram user.
:return: List of URLs that are found inside the biography
"""
url = f"{ENDPOINT}/users/{user}"
result = requests.request("GET", url, headers=HEADERS).json()
return re.findall(r'(https?://[^\s]+)', result['biography'])


def get_signature_from_url(url: str) -> Optional[VerificationData]:
"""
Tries getting the signature object linked to the given URL.
:param url: URL that should contain the signature object.
:return: A dictionary containing 'valid' to tell whether the search was valid, and an optional 'data' containing
the signature object.
"""
try:
url_encoded_username = urllib.parse.quote(data.username)
result = requests.request("GET", f"{ENDPOINT}/{url_encoded_username}", headers=HEADERS).json()
result = requests.request("GET", url, headers=HEADERS).json()
if validate_json(result):
return VerificationData(
result['address'],
Expand Down Expand Up @@ -142,12 +153,24 @@ def main(args: str):
json_obj = json.loads(decoded)
call_data = check_values(json_obj)

result = get_user_data(call_data)
if result is None:
raise Exception(f"No valid signature data found for user with username {call_data.username}")

# Get the URLs to check from the user biography
urls = get_urls_from_biography(call_data.username)
if len(urls) == 0:
raise Exception(f"No URL found inside {call_data.username} biography")

# Find the signature following the URLs
data = None
for url in urls:
result = get_signature_from_url(url)
if result is not None:
data = result
break

if data is None:
raise Exception(f"No valid signature data found inside {call_data.username} biography")

# Verify the signature
signature_valid = verify_signature(result)
signature_valid = verify_signature(data)
if not signature_valid:
raise Exception("Invalid signature")

Expand Down
38 changes: 28 additions & 10 deletions data-sources/instagram_test.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
import unittest
import instagram

import httpretty

import instagram

class instagramTest(unittest.TestCase):

class TestInstagram(unittest.TestCase):

@httpretty.activate(verbose=True, allow_net_connect=False)
def test_get_user_data(self):
def test_get_urls_from_biography(self):
# Register fake HTTP call
httpretty.register_uri(
httpretty.GET,
"https://themis.mainnet.desmos.network/instagram/test_user_desmos",
"https://themis.mainnet.desmos.network/instagram/users/riccardomontagnin",
status=200,
body='{"address":"71b0310267b49279116835ed35791c24c110012f","pub_key":"0203233fabd69a1b7a90bb968a0ab66e3af61989f65cf0bc1f8e9518740a302f1f","value":"746573745f757365725f6465736d6f73","signature":"c12605456b8652df655bb43d0166586dfc0c5d758b03f127ca6b027d0ec140ca29b9569a20c9b78b72e13d15c1a7fa0b142dc0e624f3f51ef76bd94e55345d2a"}',
body='{"biography":"https://pastebin.com/raw/D95NyR91"}',
)

url = instagram.get_urls_from_biography('riccardomontagnin')
self.assertEqual(['https://pastebin.com/raw/TgSpUCz6'], url)

@httpretty.activate(verbose=True, allow_net_connect=False)
def test_get_signature_from_url(self):
# Register fake HTTP call
httpretty.register_uri(
httpretty.GET,
"https://pastebin.com/raw/xz4S8WrW",
status=200,
body='{"address":"desmos13yp2fq3tslq6mmtq4628q38xzj75ethzela9uu","pub_key":"033024e9e0ad4f93045ef5a60bb92171e6418cd13b082e7a7bc3ed05312a0b417d","signature":"a00a7d5bd45e42615645fcaeb4d800af22704e54937ab235e5e50bebd38e88b765fdb696c22712c0cab1176756b6346cbc11481c544d1f7828cb233620c06173","value":"ricmontagnin"}',
)

# Valid signature
data = instagram.get_user_data(instagram.CallData('test_user_desmos'))
data = instagram.get_signature_from_url('https://pastebin.com/raw/xz4S8WrW')
self.assertIsNotNone(data)

# Invalid signature
# Register fake HTTP call
httpretty.register_uri(
httpretty.GET,
"https://themis.mainnet.desmos.network/instagram/test_user_desmos",
status=404,
"https://bitcoin.org",
status=200,
body='Bitcoin website',
)
data = instagram.get_user_data(instagram.CallData('test_user_desmos'))

# Invalid signature
data = instagram.get_signature_from_url('https://bitcoin.org')
self.assertIsNone(data)

def test_validate_json(self):
Expand Down

0 comments on commit 73ad5d5

Please sign in to comment.