Removes usage of lbrynet resolve with lbrynet get_claim #11
5 changed files with 41 additions and 48 deletions
2
setup.py
2
setup.py
|
@ -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',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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']
|
||||||
|
|
Loading…
Reference in a new issue