Removes usage of lbrynet resolve with lbrynet get_claim (#11)

Removes usage of lbrynet resolve with get_claim
This commit is contained in:
Oleg Silkin 2019-08-23 23:51:39 -04:00 committed by GitHub
parent 4e591de56e
commit 93e568ca21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 48 deletions

View file

@ -23,6 +23,6 @@ setup(
'aiosqlite==0.10.0', 'aiosqlite==0.10.0',
'PyNaCl>=1.3.0', 'PyNaCl>=1.3.0',
'requests', 'requests',
'cython', # Not really needed anymore but w/e 'cython',
] ]
) )

View file

@ -118,12 +118,13 @@ def insert_comment(conn: sqlite3.Connection, claim_id: str, comment: str, parent
with conn: with conn:
conn.execute( conn.execute(
""" """
INSERT INTO COMMENT(CommentId, LbryClaimId, ChannelId, Body, ParentId, Timestamp, Signature, SigningTs) INSERT INTO COMMENT(CommentId, LbryClaimId, ChannelId, Body, ParentId,
Timestamp, Signature, SigningTs)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", """,
(comment_id, claim_id, channel_id, comment, parent_id, timestamp, signature, signing_ts) (comment_id, claim_id, channel_id, comment, parent_id, timestamp, signature, signing_ts)
) )
logger.info('Inserted Comment into DB, `comment_id`: %s', comment_id) logging.info('Inserted Comment into DB, `comment_id`: %s', comment_id)
return comment_id return comment_id

View file

@ -9,10 +9,10 @@ from src.database.queries import get_comment_or_none
from src.database.queries import insert_comment from src.database.queries import insert_comment
from src.database.queries import insert_channel from src.database.queries import insert_channel
from src.database.queries import get_claim_ids_from_comment_ids from src.database.queries import get_claim_ids_from_comment_ids
from src.server.misc import is_authentic_delete_signal
from src.server.misc import request_lbrynet
from src.server.misc import validate_signature_from_claim from src.server.misc import validate_signature_from_claim
from src.server.misc import channel_matches_pattern_or_error from src.server.misc import channel_matches_pattern_or_error
from src.server.misc import get_claim_from_id
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -41,9 +41,9 @@ async def abandon_comment(app, comment_id):
return await coroutine(delete_comment_by_id)(app['writer'], comment_id) return await coroutine(delete_comment_by_id)(app['writer'], comment_id)
async def abandon_comment_if_authorized(app, comment_id, **kwargs): async def abandon_comment_if_authorized(app, comment_id, channel_id, signature, signing_ts, **kwargs):
authorized = await is_authentic_delete_signal(app, comment_id, **kwargs) claim = await get_claim_from_id(app, channel_id)
if not authorized: if not validate_signature_from_claim(claim, signature, signing_ts, comment_id):
return False return False
job = await app['comment_scheduler'].spawn(abandon_comment(app, comment_id)) job = await app['comment_scheduler'].spawn(abandon_comment(app, comment_id))
@ -58,10 +58,6 @@ async def hide_comments(app, comment_ids):
return await coroutine(hide_comments_by_id)(app['writer'], comment_ids) return await coroutine(hide_comments_by_id)(app['writer'], comment_ids)
async def claim_search(app, **kwargs):
return (await request_lbrynet(app, 'claim_search', **kwargs))['items'][0]
async def hide_comments_where_authorized(app, pieces: list): async def hide_comments_where_authorized(app, pieces: list):
comment_cids = get_claim_ids_from_comment_ids( comment_cids = get_claim_ids_from_comment_ids(
conn=app['reader'], conn=app['reader'],
@ -73,7 +69,7 @@ async def hide_comments_where_authorized(app, pieces: list):
for p in pieces: for p in pieces:
claim_id = comment_cids[p['comment_id']] claim_id = comment_cids[p['comment_id']]
if claim_id not in claims: if claim_id not in claims:
claims[claim_id] = await claim_search(app, claim_id=claim_id, no_totals=True) claims[claim_id] = await get_claim_from_id(app, claim_id, no_totals=True)
channel = claims[claim_id].get('signing_channel') channel = claims[claim_id].get('signing_channel')
if validate_signature_from_claim(channel, p['signature'], p['signing_ts'], p['comment_id']): if validate_signature_from_claim(channel, p['signature'], p['signing_ts'], p['comment_id']):
comments_to_hide.append(p['comment_id']) comments_to_hide.append(p['comment_id'])

View file

@ -59,6 +59,10 @@ async def request_lbrynet(app, method, **params):
raise Exception("Server cannot verify delete signature") raise Exception("Server cannot verify delete signature")
async def get_claim_from_id(app, claim_id, **kwargs):
return (await request_lbrynet(app, 'claim_search', no_totals=True, claim_id=claim_id, **kwargs))['items'][0]
def get_encoded_signature(signature): def get_encoded_signature(signature):
signature = signature.encode() if type(signature) is str else signature signature = signature.encode() if type(signature) is str else signature
r = int(signature[:int(len(signature) / 2)], 16) r = int(signature[:int(len(signature) / 2)], 16)
@ -109,21 +113,6 @@ def is_valid_credential_input(channel_id=None, channel_name=None, signature=None
return True return True
async def is_authentic_delete_signal(app, comment_id, channel_name, channel_id, signature, signing_ts):
lbry_url = f'lbry://{channel_name}#{channel_id}'
claim = await request_lbrynet(app, 'resolve', urls=[lbry_url])
if claim:
public_key = claim['value']['public_key']
claim_hash = binascii.unhexlify(claim['claim_id'].encode())[::-1]
pieces_injest = b''.join((signing_ts.encode(), claim_hash, comment_id.encode()))
return is_signature_valid(
encoded_signature=get_encoded_signature(signature),
signature_digest=hashlib.sha256(pieces_injest).digest(),
public_key_bytes=binascii.unhexlify(public_key.encode())
)
return False
def validate_signature_from_claim(claim, signature, signing_ts, data: str): def validate_signature_from_claim(claim, signature, signing_ts, data: str):
try: try:
if claim: if claim:

View file

@ -1,10 +1,5 @@
import unittest
import atexit
import os import os
from multiprocessing.pool import Pool
import asyncio
import aiohttp import aiohttp
import requests
import re import re
from itertools import * from itertools import *
@ -64,7 +59,12 @@ class ServerTest(AsyncioTestCase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.url = 'http://' + config['HOST'] + ':5921/api' self.host = 'localhost'
self.port = 5931
@property
def url(self):
return f'http://{self.host}:{self.port}/api'
@classmethod @classmethod
def tearDownClass(cls) -> None: def tearDownClass(cls) -> None:
@ -74,7 +74,7 @@ class ServerTest(AsyncioTestCase):
async def asyncSetUp(self): async def asyncSetUp(self):
await super().asyncSetUp() await super().asyncSetUp()
self.server = app.CommentDaemon(config, db_file=self.db_file) self.server = app.CommentDaemon(config, db_file=self.db_file)
await self.server.start() await self.server.start(host=self.host, port=self.port)
self.addCleanup(self.server.stop) self.addCleanup(self.server.stop)
async def post_comment(self, **params): async def post_comment(self, **params):
@ -199,24 +199,30 @@ class ListCommentsTest(AsyncioTestCase):
'signature': nothing, 'signature': nothing,
'parent_id': nothing 'parent_id': nothing
} }
db_file = 'list_test.db'
url = 'http://localhost:5921/api'
comment_ids = None
claim_id = '1d8a5cc39ca02e55782d619e67131c0a20843be8'
@classmethod def __init__(self, *args, **kwargs):
async def post_comment(cls, **params): super().__init__(*args, **kwargs)
return await jsonrpc_post(cls.url, 'create_comment', **params) self.host = 'localhost'
self.port = 5931
self.db_file = 'list_test.db'
self.claim_id = '1d8a5cc39ca02e55782d619e67131c0a20843be8'
self.comment_ids = None
@classmethod @property
def tearDownClass(cls) -> None: def url(self):
return f'http://{self.host}:{self.port}/api'
async def post_comment(self, **params):
return await jsonrpc_post(self.url, 'create_comment', **params)
def tearDown(self) -> None:
print('exit reached') print('exit reached')
os.remove(cls.db_file) os.remove(self.db_file)
async def asyncSetUp(self): async def asyncSetUp(self):
await super().asyncSetUp() await super().asyncSetUp()
self.server = app.CommentDaemon(config, db_file=self.db_file) self.server = app.CommentDaemon(config, db_file=self.db_file)
await self.server.start() await self.server.start(self.host, self.port)
self.addCleanup(self.server.stop) self.addCleanup(self.server.stop)
if self.comment_ids is None: if self.comment_ids is None:
self.comment_list = [{key: self.replace[key]() for key in self.replace.keys()} for _ in range(23)] self.comment_list = [{key: self.replace[key]() for key in self.replace.keys()} for _ in range(23)]
@ -226,8 +232,9 @@ class ListCommentsTest(AsyncioTestCase):
for comm in self.comment_list] for comm in self.comment_list]
async def testListComments(self): async def testListComments(self):
response_one = await jsonrpc_post(self.url, 'get_claim_comments', page_size=20, response_one = await jsonrpc_post(
page=1, top_level=1, claim_id=self.claim_id) self.url, 'get_claim_comments', page_size=20, page=1, top_level=1, claim_id=self.claim_id
)
self.assertIsNotNone(response_one) self.assertIsNotNone(response_one)
self.assertIn('result', response_one) self.assertIn('result', response_one)
response_one: dict = response_one['result'] response_one: dict = response_one['result']