more cleaning up
This commit is contained in:
parent
aecafbbebd
commit
4d79a7828c
7 changed files with 276 additions and 222 deletions
|
@ -45,12 +45,9 @@ KNOWN_DHT_NODES = [('104.236.42.182', 4000),
|
||||||
POINTTRADER_SERVER = 'http://ec2-54-187-192-68.us-west-2.compute.amazonaws.com:2424'
|
POINTTRADER_SERVER = 'http://ec2-54-187-192-68.us-west-2.compute.amazonaws.com:2424'
|
||||||
#POINTTRADER_SERVER = 'http://127.0.0.1:2424'
|
#POINTTRADER_SERVER = 'http://127.0.0.1:2424'
|
||||||
|
|
||||||
if IS_DEVELOPMENT_VERSION:
|
SEARCH_SERVERS = ["http://lighthouse1.lbry.io:50005",
|
||||||
SEARCH_SERVERS = ["http://107.170.207.64:50005"]
|
"http://lighthouse2.lbry.io:50005",
|
||||||
else:
|
"http://lighthouse3.lbry.io:50005"]
|
||||||
SEARCH_SERVERS = ["http://lighthouse1.lbry.io:50005",
|
|
||||||
"http://lighthouse2.lbry.io:50005",
|
|
||||||
"http://lighthouse3.lbry.io:50005"]
|
|
||||||
|
|
||||||
REFLECTOR_SERVERS = [("reflector.lbry.io", 5566)]
|
REFLECTOR_SERVERS = [("reflector.lbry.io", 5566)]
|
||||||
|
|
||||||
|
@ -67,6 +64,9 @@ if os.name == "nt":
|
||||||
else:
|
else:
|
||||||
ICON_PATH = "app.icns"
|
ICON_PATH = "app.icns"
|
||||||
APP_NAME = "LBRY"
|
APP_NAME = "LBRY"
|
||||||
|
|
||||||
|
ORIGIN = "http://%s:%i" % (API_INTERFACE, API_PORT)
|
||||||
|
REFERER = "http://%s:%i/" % (API_INTERFACE, API_PORT)
|
||||||
API_CONNECTION_STRING = "http://%s:%i/%s" % (API_INTERFACE, API_PORT, API_ADDRESS)
|
API_CONNECTION_STRING = "http://%s:%i/%s" % (API_INTERFACE, API_PORT, API_ADDRESS)
|
||||||
UI_ADDRESS = "http://%s:%i" % (API_INTERFACE, API_PORT)
|
UI_ADDRESS = "http://%s:%i" % (API_INTERFACE, API_PORT)
|
||||||
PROTOCOL_PREFIX = "lbry"
|
PROTOCOL_PREFIX = "lbry"
|
||||||
|
@ -88,11 +88,6 @@ CURRENCIES = {
|
||||||
'USD': {'type': 'fiat'},
|
'USD': {'type': 'fiat'},
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOWED_DURING_STARTUP = ['is_running', 'is_first_run',
|
|
||||||
'get_time_behind_blockchain', 'stop',
|
|
||||||
'daemon_status', 'get_start_notice',
|
|
||||||
'version', 'get_search_servers']
|
|
||||||
|
|
||||||
LOGGLY_TOKEN = 'LJEzATH4AzRgAwxjAP00LwZ2YGx3MwVgZTMuBQZ3MQuxLmOv'
|
LOGGLY_TOKEN = 'LJEzATH4AzRgAwxjAP00LwZ2YGx3MwVgZTMuBQZ3MQuxLmOv'
|
||||||
|
|
||||||
ANALYTICS_ENDPOINT = 'https://api.segment.io/v1'
|
ANALYTICS_ENDPOINT = 'https://api.segment.io/v1'
|
||||||
|
|
|
@ -93,4 +93,7 @@ class InvalidHeaderError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class InvalidAuthenticationToken(Exception):
|
class InvalidAuthenticationToken(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SubhandlerError(Exception):
|
||||||
pass
|
pass
|
|
@ -40,7 +40,8 @@ from lbrynet.lbrynet_daemon.LBRYDownloader import GetStream
|
||||||
from lbrynet.lbrynet_daemon.LBRYPublisher import Publisher
|
from lbrynet.lbrynet_daemon.LBRYPublisher import Publisher
|
||||||
from lbrynet.lbrynet_daemon.LBRYExchangeRateManager import ExchangeRateManager
|
from lbrynet.lbrynet_daemon.LBRYExchangeRateManager import ExchangeRateManager
|
||||||
from lbrynet.lbrynet_daemon.Lighthouse import LighthouseClient
|
from lbrynet.lbrynet_daemon.Lighthouse import LighthouseClient
|
||||||
from lbrynet.lbrynet_daemon.auth.server import LBRYJSONRPCServer, auth_required, authorizer
|
from lbrynet.lbrynet_daemon.auth.server import AuthJSONRPCServer
|
||||||
|
from lbrynet.lbrynet_daemon.auth.util import get_auth_message
|
||||||
from lbrynet.metadata.LBRYMetadata import Metadata, verify_name_characters
|
from lbrynet.metadata.LBRYMetadata import Metadata, verify_name_characters
|
||||||
from lbrynet.core import log_support
|
from lbrynet.core import log_support
|
||||||
from lbrynet.core import utils
|
from lbrynet.core import utils
|
||||||
|
@ -49,7 +50,7 @@ from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings
|
||||||
from lbrynet.conf import MIN_BLOB_DATA_PAYMENT_RATE, DEFAULT_MAX_SEARCH_RESULTS, \
|
from lbrynet.conf import MIN_BLOB_DATA_PAYMENT_RATE, DEFAULT_MAX_SEARCH_RESULTS, \
|
||||||
KNOWN_DHT_NODES, DEFAULT_MAX_KEY_FEE, DEFAULT_WALLET, \
|
KNOWN_DHT_NODES, DEFAULT_MAX_KEY_FEE, DEFAULT_WALLET, \
|
||||||
DEFAULT_SEARCH_TIMEOUT, DEFAULT_CACHE_TIME, DEFAULT_UI_BRANCH, \
|
DEFAULT_SEARCH_TIMEOUT, DEFAULT_CACHE_TIME, DEFAULT_UI_BRANCH, \
|
||||||
LOG_POST_URL, LOG_FILE_NAME, REFLECTOR_SERVERS, SEARCH_SERVERS, ALLOWED_DURING_STARTUP
|
LOG_POST_URL, LOG_FILE_NAME, REFLECTOR_SERVERS, SEARCH_SERVERS
|
||||||
from lbrynet.conf import DEFAULT_SD_DOWNLOAD_TIMEOUT
|
from lbrynet.conf import DEFAULT_SD_DOWNLOAD_TIMEOUT
|
||||||
from lbrynet.conf import DEFAULT_TIMEOUT
|
from lbrynet.conf import DEFAULT_TIMEOUT
|
||||||
from lbrynet.core.StreamDescriptor import StreamDescriptorIdentifier, download_sd_blob, BlobStreamDescriptorReader
|
from lbrynet.core.StreamDescriptor import StreamDescriptorIdentifier, download_sd_blob, BlobStreamDescriptorReader
|
||||||
|
@ -122,10 +123,8 @@ BAD_REQUEST = 400
|
||||||
NOT_FOUND = 404
|
NOT_FOUND = 404
|
||||||
OK_CODE = 200
|
OK_CODE = 200
|
||||||
|
|
||||||
# TODO add login credentials in a conf file
|
|
||||||
# TODO alert if your copy of a lbry file is out of date with the name record
|
# TODO alert if your copy of a lbry file is out of date with the name record
|
||||||
|
|
||||||
|
|
||||||
REMOTE_SERVER = "www.google.com"
|
REMOTE_SERVER = "www.google.com"
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,14 +133,17 @@ class Parameters(object):
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
|
|
||||||
@authorizer
|
class LBRYDaemon(AuthJSONRPCServer):
|
||||||
class LBRYDaemon(LBRYJSONRPCServer):
|
|
||||||
"""
|
"""
|
||||||
LBRYnet daemon, a jsonrpc interface to lbry functions
|
LBRYnet daemon, a jsonrpc interface to lbry functions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, root, wallet_type=None):
|
def __init__(self, root, wallet_type=None):
|
||||||
LBRYJSONRPCServer.__init__(self)
|
AuthJSONRPCServer.__init__(self)
|
||||||
|
self.allowed_during_startup = ['is_running', 'is_first_run',
|
||||||
|
'get_time_behind_blockchain', 'stop',
|
||||||
|
'daemon_status', 'get_start_notice',
|
||||||
|
'version', 'get_search_servers']
|
||||||
reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
|
reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
|
||||||
|
|
||||||
self.startup_status = STARTUP_STAGES[0]
|
self.startup_status = STARTUP_STAGES[0]
|
||||||
|
@ -392,6 +394,17 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
f.write("rpcpassword=" + password)
|
f.write("rpcpassword=" + password)
|
||||||
log.info("Done writing lbrycrd.conf")
|
log.info("Done writing lbrycrd.conf")
|
||||||
|
|
||||||
|
@AuthJSONRPCServer.subhandler
|
||||||
|
def _exclude_lbrycrd_only_commands_from_lbryum_session(self, request):
|
||||||
|
request.content.seek(0, 0)
|
||||||
|
content = request.content.read()
|
||||||
|
parsed = jsonrpclib.loads(content)
|
||||||
|
function_path = parsed.get("method")
|
||||||
|
if self.wallet_type == "lbryum" and function_path in ['set_miner', 'get_miner_status']:
|
||||||
|
log.warning("Mining commands are not available in lbryum")
|
||||||
|
raise Exception("Command not available in lbryum")
|
||||||
|
return True
|
||||||
|
|
||||||
def setup(self, branch=DEFAULT_UI_BRANCH, user_specified=False, branch_specified=False, host_ui=True):
|
def setup(self, branch=DEFAULT_UI_BRANCH, user_specified=False, branch_specified=False, host_ui=True):
|
||||||
def _log_starting_vals():
|
def _log_starting_vals():
|
||||||
log.info("Starting balance: " + str(self.session.wallet.wallet_balance))
|
log.info("Starting balance: " + str(self.session.wallet.wallet_balance))
|
||||||
|
@ -1337,7 +1350,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
def _search(self, search):
|
def _search(self, search):
|
||||||
return self.lighthouse_client.search(search)
|
return self.lighthouse_client.search(search)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_is_running(self):
|
def jsonrpc_is_running(self):
|
||||||
"""
|
"""
|
||||||
Check if lbrynet daemon is running
|
Check if lbrynet daemon is running
|
||||||
|
@ -1354,7 +1367,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
else:
|
else:
|
||||||
return self._render_response(False, OK_CODE)
|
return self._render_response(False, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_daemon_status(self):
|
def jsonrpc_daemon_status(self):
|
||||||
"""
|
"""
|
||||||
Get lbrynet daemon status information
|
Get lbrynet daemon status information
|
||||||
|
@ -1386,10 +1398,8 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
else:
|
else:
|
||||||
r['message'] = "Catching up with the blockchain"
|
r['message'] = "Catching up with the blockchain"
|
||||||
r['progress'] = 0
|
r['progress'] = 0
|
||||||
log.info("daemon status: " + str(r))
|
|
||||||
return self._render_response(r, OK_CODE)
|
return self._render_response(r, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_is_first_run(self):
|
def jsonrpc_is_first_run(self):
|
||||||
"""
|
"""
|
||||||
Check if this is the first time lbrynet daemon has been run
|
Check if this is the first time lbrynet daemon has been run
|
||||||
|
@ -1410,7 +1420,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_start_notice(self):
|
def jsonrpc_get_start_notice(self):
|
||||||
"""
|
"""
|
||||||
Get special message to be displayed at startup
|
Get special message to be displayed at startup
|
||||||
|
@ -1430,7 +1439,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
else:
|
else:
|
||||||
self._render_response(self.startup_message, OK_CODE)
|
self._render_response(self.startup_message, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_version(self):
|
def jsonrpc_version(self):
|
||||||
"""
|
"""
|
||||||
Get lbry version information
|
Get lbry version information
|
||||||
|
@ -1465,7 +1473,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
log.info("Get version info: " + json.dumps(msg))
|
log.info("Get version info: " + json.dumps(msg))
|
||||||
return self._render_response(msg, OK_CODE)
|
return self._render_response(msg, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_settings(self):
|
def jsonrpc_get_settings(self):
|
||||||
"""
|
"""
|
||||||
Get lbrynet daemon settings
|
Get lbrynet daemon settings
|
||||||
|
@ -1494,7 +1502,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
log.info("Get daemon settings")
|
log.info("Get daemon settings")
|
||||||
return self._render_response(self.session_settings, OK_CODE)
|
return self._render_response(self.session_settings, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_set_settings(self, p):
|
def jsonrpc_set_settings(self, p):
|
||||||
"""
|
"""
|
||||||
Set lbrynet daemon settings
|
Set lbrynet daemon settings
|
||||||
|
@ -1522,7 +1530,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_help(self, p=None):
|
def jsonrpc_help(self, p=None):
|
||||||
"""
|
"""
|
||||||
Function to retrieve docstring for API function
|
Function to retrieve docstring for API function
|
||||||
|
@ -1537,17 +1544,17 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not p:
|
if not p:
|
||||||
return self._render_response(self._listFunctions(), OK_CODE)
|
return self._render_response(self.callable_methods.keys(), OK_CODE)
|
||||||
elif 'callable_during_start' in p.keys():
|
elif 'callable_during_start' in p.keys():
|
||||||
return self._render_response(ALLOWED_DURING_STARTUP, OK_CODE)
|
return self._render_response(self.allowed_during_startup, OK_CODE)
|
||||||
elif 'function' in p.keys():
|
elif 'function' in p.keys():
|
||||||
func_path = p['function']
|
func_path = p['function']
|
||||||
function = self._getFunction(func_path)
|
function = self.callable_methods.get(func_path)
|
||||||
return self._render_response(function.__doc__, OK_CODE)
|
return self._render_response(function.__doc__, OK_CODE)
|
||||||
else:
|
else:
|
||||||
return self._render_response(self.jsonrpc_help.__doc__, OK_CODE)
|
return self._render_response(self.jsonrpc_help.__doc__, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_balance(self):
|
def jsonrpc_get_balance(self):
|
||||||
"""
|
"""
|
||||||
Get balance
|
Get balance
|
||||||
|
@ -1561,7 +1568,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
log.info("Get balance")
|
log.info("Get balance")
|
||||||
return self._render_response(float(self.session.wallet.wallet_balance), OK_CODE)
|
return self._render_response(float(self.session.wallet.wallet_balance), OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_stop(self):
|
def jsonrpc_stop(self):
|
||||||
"""
|
"""
|
||||||
Stop lbrynet-daemon
|
Stop lbrynet-daemon
|
||||||
|
@ -1581,7 +1587,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return self._render_response("Shutting down", OK_CODE)
|
return self._render_response("Shutting down", OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_lbry_files(self):
|
def jsonrpc_get_lbry_files(self):
|
||||||
"""
|
"""
|
||||||
Get LBRY files
|
Get LBRY files
|
||||||
|
@ -1608,7 +1614,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_lbry_file(self, p):
|
def jsonrpc_get_lbry_file(self, p):
|
||||||
"""
|
"""
|
||||||
Get lbry file
|
Get lbry file
|
||||||
|
@ -1638,7 +1644,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_resolve_name(self, p):
|
def jsonrpc_resolve_name(self, p):
|
||||||
"""
|
"""
|
||||||
Resolve stream info from a LBRY uri
|
Resolve stream info from a LBRY uri
|
||||||
|
@ -1660,7 +1665,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallbacks(lambda info: self._render_response(info, OK_CODE), lambda _: server.failure)
|
d.addCallbacks(lambda info: self._render_response(info, OK_CODE), lambda _: server.failure)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_claim_info(self, p):
|
def jsonrpc_get_claim_info(self, p):
|
||||||
"""
|
"""
|
||||||
Resolve claim info from a LBRY uri
|
Resolve claim info from a LBRY uri
|
||||||
|
@ -1685,7 +1689,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def _process_get_parameters(self, p):
|
def _process_get_parameters(self, p):
|
||||||
"""Extract info from input parameters and fill in default values for `get` call."""
|
"""Extract info from input parameters and fill in default values for `get` call."""
|
||||||
# TODO: this process can be abstracted s.t. each method
|
# TODO: this process can be abstracted s.t. each method
|
||||||
|
@ -1707,7 +1711,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
name=name
|
name=name
|
||||||
)
|
)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get(self, p):
|
def jsonrpc_get(self, p):
|
||||||
"""Download stream from a LBRY uri.
|
"""Download stream from a LBRY uri.
|
||||||
|
|
||||||
|
@ -1738,7 +1742,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda message: self._render_response(message, OK_CODE))
|
d.addCallback(lambda message: self._render_response(message, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_stop_lbry_file(self, p):
|
def jsonrpc_stop_lbry_file(self, p):
|
||||||
"""
|
"""
|
||||||
Stop lbry file
|
Stop lbry file
|
||||||
|
@ -1764,7 +1768,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_start_lbry_file(self, p):
|
def jsonrpc_start_lbry_file(self, p):
|
||||||
"""
|
"""
|
||||||
Stop lbry file
|
Stop lbry file
|
||||||
|
@ -1789,7 +1793,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_est_cost(self, p):
|
def jsonrpc_get_est_cost(self, p):
|
||||||
"""
|
"""
|
||||||
Get estimated cost for a lbry uri
|
Get estimated cost for a lbry uri
|
||||||
|
@ -1811,7 +1814,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_search_nametrie(self, p):
|
def jsonrpc_search_nametrie(self, p):
|
||||||
"""
|
"""
|
||||||
Search the nametrie for claims
|
Search the nametrie for claims
|
||||||
|
@ -1848,7 +1851,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_delete_lbry_file(self, p):
|
def jsonrpc_delete_lbry_file(self, p):
|
||||||
"""
|
"""
|
||||||
Delete a lbry file
|
Delete a lbry file
|
||||||
|
@ -1878,7 +1881,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_publish(self, p):
|
def jsonrpc_publish(self, p):
|
||||||
"""
|
"""
|
||||||
Make a new name claim and publish associated data to lbrynet
|
Make a new name claim and publish associated data to lbrynet
|
||||||
|
@ -1955,7 +1958,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_abandon_claim(self, p):
|
def jsonrpc_abandon_claim(self, p):
|
||||||
"""
|
"""
|
||||||
Abandon a name and reclaim credits from the claim
|
Abandon a name and reclaim credits from the claim
|
||||||
|
@ -1982,7 +1985,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_abandon_name(self, p):
|
def jsonrpc_abandon_name(self, p):
|
||||||
"""
|
"""
|
||||||
DEPRECIATED, use abandon_claim
|
DEPRECIATED, use abandon_claim
|
||||||
|
@ -1995,7 +1998,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return self.jsonrpc_abandon_claim(p)
|
return self.jsonrpc_abandon_claim(p)
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_support_claim(self, p):
|
def jsonrpc_support_claim(self, p):
|
||||||
"""
|
"""
|
||||||
Support a name claim
|
Support a name claim
|
||||||
|
@ -2015,7 +2018,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_name_claims(self):
|
def jsonrpc_get_name_claims(self):
|
||||||
"""
|
"""
|
||||||
Get my name claims
|
Get my name claims
|
||||||
|
@ -2039,7 +2042,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_claims_for_name(self, p):
|
def jsonrpc_get_claims_for_name(self, p):
|
||||||
"""
|
"""
|
||||||
Get claims for a name
|
Get claims for a name
|
||||||
|
@ -2055,7 +2057,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_transaction_history(self):
|
def jsonrpc_get_transaction_history(self):
|
||||||
"""
|
"""
|
||||||
Get transaction history
|
Get transaction history
|
||||||
|
@ -2070,7 +2072,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_transaction(self, p):
|
def jsonrpc_get_transaction(self, p):
|
||||||
"""
|
"""
|
||||||
Get a decoded transaction from a txid
|
Get a decoded transaction from a txid
|
||||||
|
@ -2087,7 +2088,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_address_is_mine(self, p):
|
def jsonrpc_address_is_mine(self, p):
|
||||||
"""
|
"""
|
||||||
Checks if an address is associated with the current wallet.
|
Checks if an address is associated with the current wallet.
|
||||||
|
@ -2105,7 +2106,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_public_key_from_wallet(self, p):
|
def jsonrpc_get_public_key_from_wallet(self, p):
|
||||||
"""
|
"""
|
||||||
Get public key from wallet address
|
Get public key from wallet address
|
||||||
|
@ -2120,7 +2121,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d = self.session.wallet.get_pub_keys(wallet)
|
d = self.session.wallet.get_pub_keys(wallet)
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_time_behind_blockchain(self):
|
def jsonrpc_get_time_behind_blockchain(self):
|
||||||
"""
|
"""
|
||||||
Get number of blocks behind the blockchain
|
Get number of blocks behind the blockchain
|
||||||
|
@ -2144,7 +2144,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_new_address(self):
|
def jsonrpc_get_new_address(self):
|
||||||
"""
|
"""
|
||||||
Generate a new wallet address
|
Generate a new wallet address
|
||||||
|
@ -2164,7 +2164,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda address: self._render_response(address, OK_CODE))
|
d.addCallback(lambda address: self._render_response(address, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_send_amount_to_address(self, p):
|
def jsonrpc_send_amount_to_address(self, p):
|
||||||
"""
|
"""
|
||||||
Send credits to an address
|
Send credits to an address
|
||||||
|
@ -2189,7 +2189,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda _: self._render_response(True, OK_CODE))
|
d.addCallback(lambda _: self._render_response(True, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_best_blockhash(self):
|
def jsonrpc_get_best_blockhash(self):
|
||||||
"""
|
"""
|
||||||
Get hash of most recent block
|
Get hash of most recent block
|
||||||
|
@ -2204,7 +2203,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_block(self, p):
|
def jsonrpc_get_block(self, p):
|
||||||
"""
|
"""
|
||||||
Get contents of a block
|
Get contents of a block
|
||||||
|
@ -2227,7 +2225,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_claims_for_tx(self, p):
|
def jsonrpc_get_claims_for_tx(self, p):
|
||||||
"""
|
"""
|
||||||
Get claims for tx
|
Get claims for tx
|
||||||
|
@ -2247,7 +2244,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_download_descriptor(self, p):
|
def jsonrpc_download_descriptor(self, p):
|
||||||
"""
|
"""
|
||||||
Download and return a sd blob
|
Download and return a sd blob
|
||||||
|
@ -2264,7 +2261,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallbacks(lambda r: self._render_response(r, OK_CODE), lambda _: self._render_response(False, OK_CODE))
|
d.addCallbacks(lambda r: self._render_response(r, OK_CODE), lambda _: self._render_response(False, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_nametrie(self):
|
def jsonrpc_get_nametrie(self):
|
||||||
"""
|
"""
|
||||||
Get the nametrie
|
Get the nametrie
|
||||||
|
@ -2280,7 +2276,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_set_miner(self, p):
|
def jsonrpc_set_miner(self, p):
|
||||||
"""
|
"""
|
||||||
Start of stop the miner, function only available when lbrycrd is set as the wallet
|
Start of stop the miner, function only available when lbrycrd is set as the wallet
|
||||||
|
@ -2300,7 +2296,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_miner_status(self):
|
def jsonrpc_get_miner_status(self):
|
||||||
"""
|
"""
|
||||||
Get status of miner
|
Get status of miner
|
||||||
|
@ -2315,7 +2311,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_log(self, p):
|
def jsonrpc_log(self, p):
|
||||||
"""
|
"""
|
||||||
Log message
|
Log message
|
||||||
|
@ -2330,7 +2325,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
log.info("API client log request: %s" % message)
|
log.info("API client log request: %s" % message)
|
||||||
return self._render_response(True, OK_CODE)
|
return self._render_response(True, OK_CODE)
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_upload_log(self, p=None):
|
def jsonrpc_upload_log(self, p=None):
|
||||||
"""
|
"""
|
||||||
Upload log
|
Upload log
|
||||||
|
@ -2372,7 +2366,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda _: self._render_response(True, OK_CODE))
|
d.addCallback(lambda _: self._render_response(True, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_configure_ui(self, p):
|
def jsonrpc_configure_ui(self, p):
|
||||||
"""
|
"""
|
||||||
Configure the UI being hosted
|
Configure the UI being hosted
|
||||||
|
@ -2397,7 +2391,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_reveal(self, p):
|
def jsonrpc_reveal(self, p):
|
||||||
"""
|
"""
|
||||||
Reveal a file or directory in file browser
|
Reveal a file or directory in file browser
|
||||||
|
@ -2417,7 +2411,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda _: self._render_response(True, OK_CODE))
|
d.addCallback(lambda _: self._render_response(True, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_peers_for_hash(self, p):
|
def jsonrpc_get_peers_for_hash(self, p):
|
||||||
"""
|
"""
|
||||||
Get peers for blob hash
|
Get peers for blob hash
|
||||||
|
@ -2435,7 +2429,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_announce_all_blobs_to_dht(self):
|
def jsonrpc_announce_all_blobs_to_dht(self):
|
||||||
"""
|
"""
|
||||||
Announce all blobs to the dht
|
Announce all blobs to the dht
|
||||||
|
@ -2450,7 +2444,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda _: self._render_response("Announced", OK_CODE))
|
d.addCallback(lambda _: self._render_response("Announced", OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_reflect(self, p):
|
def jsonrpc_reflect(self, p):
|
||||||
"""
|
"""
|
||||||
Reflect a stream
|
Reflect a stream
|
||||||
|
@ -2467,7 +2461,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallbacks(lambda _: self._render_response(True, OK_CODE), lambda err: self._render_response(err.getTraceback(), OK_CODE))
|
d.addCallbacks(lambda _: self._render_response(True, OK_CODE), lambda err: self._render_response(err.getTraceback(), OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_get_blob_hashes(self):
|
def jsonrpc_get_blob_hashes(self):
|
||||||
"""
|
"""
|
||||||
Returns all blob hashes
|
Returns all blob hashes
|
||||||
|
@ -2482,7 +2476,7 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
@AuthJSONRPCServer.auth_required
|
||||||
def jsonrpc_reflect_all_blobs(self):
|
def jsonrpc_reflect_all_blobs(self):
|
||||||
"""
|
"""
|
||||||
Reflects all saved blobs
|
Reflects all saved blobs
|
||||||
|
@ -2498,20 +2492,6 @@ class LBRYDaemon(LBRYJSONRPCServer):
|
||||||
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
d.addCallback(lambda r: self._render_response(r, OK_CODE))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@auth_required
|
|
||||||
def jsonrpc_get_search_servers(self):
|
|
||||||
"""
|
|
||||||
Get list of lighthouse servers
|
|
||||||
|
|
||||||
Args:
|
|
||||||
None
|
|
||||||
Returns:
|
|
||||||
List of address:port
|
|
||||||
"""
|
|
||||||
|
|
||||||
d = self._render_response(SEARCH_SERVERS, OK_CODE)
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
def get_lbrynet_version_from_github():
|
def get_lbrynet_version_from_github():
|
||||||
"""Return the latest released version from github."""
|
"""Return the latest released version from github."""
|
||||||
|
|
|
@ -14,7 +14,7 @@ class HttpPasswordRealm(object):
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
|
|
||||||
def requestAvatar(self, avatarId, mind, *interfaces):
|
def requestAvatar(self, avatarId, mind, *interfaces):
|
||||||
log.info("Processing request for %s", avatarId)
|
log.debug("Processing request for %s", avatarId)
|
||||||
if resource.IResource in interfaces:
|
if resource.IResource in interfaces:
|
||||||
return (resource.IResource, self.resource, lambda: None)
|
return (resource.IResource, self.resource, lambda: None)
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
@ -5,7 +5,7 @@ import os
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from lbrynet.lbrynet_daemon.auth.util import load_api_keys, APIKey, API_KEY_NAME
|
from lbrynet.lbrynet_daemon.auth.util import load_api_keys, APIKey, API_KEY_NAME, get_auth_message
|
||||||
from lbrynet.conf import API_INTERFACE, API_ADDRESS, API_PORT
|
from lbrynet.conf import API_INTERFACE, API_ADDRESS, API_PORT
|
||||||
from lbrynet.conf import DATA_DIR
|
from lbrynet.conf import DATA_DIR
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ class LBRYAPIClient(object):
|
||||||
'method': self.__service_name,
|
'method': self.__service_name,
|
||||||
'params': args,
|
'params': args,
|
||||||
'id': self.__id_count}
|
'id': self.__id_count}
|
||||||
to_auth = str(pre_auth_postdata['method']).encode('hex') + str(pre_auth_postdata['id']).encode('hex')
|
to_auth = get_auth_message(pre_auth_postdata)
|
||||||
token = self.__api_key.get_hmac(to_auth.decode('hex'))
|
token = self.__api_key.get_hmac(to_auth)
|
||||||
pre_auth_postdata.update({'hmac': token})
|
pre_auth_postdata.update({'hmac': token})
|
||||||
postdata = json.dumps(pre_auth_postdata)
|
postdata = json.dumps(pre_auth_postdata)
|
||||||
service_url = self.__service_url
|
service_url = self.__service_url
|
||||||
|
@ -79,16 +79,13 @@ class LBRYAPIClient(object):
|
||||||
next_secret = headers.get(LBRY_SECRET, False)
|
next_secret = headers.get(LBRY_SECRET, False)
|
||||||
|
|
||||||
if next_secret:
|
if next_secret:
|
||||||
# print "Next secret: %s" % next_secret
|
|
||||||
self.__api_key.secret = next_secret
|
self.__api_key.secret = next_secret
|
||||||
self.__cookies = cookies
|
self.__cookies = cookies
|
||||||
|
|
||||||
# print "Postdata: %s" % postdata
|
|
||||||
if http_response is None:
|
if http_response is None:
|
||||||
raise JSONRPCException({
|
raise JSONRPCException({
|
||||||
'code': -342, 'message': 'missing HTTP response from server'})
|
'code': -342, 'message': 'missing HTTP response from server'})
|
||||||
|
|
||||||
# print "-----\n%s\n------" % http_response.text
|
|
||||||
http_response.raise_for_status()
|
http_response.raise_for_status()
|
||||||
|
|
||||||
response = http_response.json()
|
response = http_response.json()
|
||||||
|
@ -104,20 +101,18 @@ class LBRYAPIClient(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def config(cls, key_name=None, key=None, pw_path=None, timeout=HTTP_TIMEOUT, connection=None, count=0,
|
def config(cls, key_name=None, key=None, pw_path=None, timeout=HTTP_TIMEOUT, connection=None, count=0,
|
||||||
service=None, cookies=None, auth=None, url=None, login_url=None):
|
service=None, cookies=None, auth=None, url=None, login_url=None):
|
||||||
|
|
||||||
api_key_name = API_KEY_NAME if not key_name else key_name
|
api_key_name = API_KEY_NAME if not key_name else key_name
|
||||||
pw_path = os.path.join(DATA_DIR, ".api_keys") if not pw_path else pw_path
|
pw_path = os.path.join(DATA_DIR, ".api_keys") if not pw_path else pw_path
|
||||||
|
|
||||||
if not key:
|
if not key:
|
||||||
keys = load_api_keys(pw_path)
|
keys = load_api_keys(pw_path)
|
||||||
api_key = keys.get(api_key_name, False)
|
api_key = keys.get(api_key_name, False)
|
||||||
else:
|
else:
|
||||||
api_key = APIKey(name=api_key_name, secret=key)
|
api_key = APIKey(name=api_key_name, secret=key)
|
||||||
|
|
||||||
if login_url is None:
|
if login_url is None:
|
||||||
service_url = "http://%s:%s@%s:%i/%s" % (api_key_name, api_key.secret, API_INTERFACE, API_PORT, API_ADDRESS)
|
service_url = "http://%s:%s@%s:%i/%s" % (api_key_name, api_key.secret, API_INTERFACE, API_PORT, API_ADDRESS)
|
||||||
else:
|
else:
|
||||||
service_url = login_url
|
service_url = login_url
|
||||||
|
|
||||||
id_count = count
|
id_count = count
|
||||||
|
|
||||||
if auth is None and connection is None and cookies is None and url is None:
|
if auth is None and connection is None and cookies is None and url is None:
|
||||||
|
@ -134,10 +129,8 @@ class LBRYAPIClient(object):
|
||||||
pass
|
pass
|
||||||
authpair = user + b':' + passwd
|
authpair = user + b':' + passwd
|
||||||
auth_header = b'Basic ' + base64.b64encode(authpair)
|
auth_header = b'Basic ' + base64.b64encode(authpair)
|
||||||
|
|
||||||
conn = requests.Session()
|
conn = requests.Session()
|
||||||
conn.auth = (user, passwd)
|
conn.auth = (user, passwd)
|
||||||
|
|
||||||
req = requests.Request(method='POST',
|
req = requests.Request(method='POST',
|
||||||
url=service_url,
|
url=service_url,
|
||||||
auth=conn.auth,
|
auth=conn.auth,
|
||||||
|
@ -148,11 +141,9 @@ class LBRYAPIClient(object):
|
||||||
r = req.prepare()
|
r = req.prepare()
|
||||||
http_response = conn.send(r)
|
http_response = conn.send(r)
|
||||||
cookies = http_response.cookies
|
cookies = http_response.cookies
|
||||||
# print "Logged in"
|
|
||||||
|
|
||||||
uid = cookies.get(TWISTED_SESSION)
|
uid = cookies.get(TWISTED_SESSION)
|
||||||
api_key = APIKey.new(seed=uid)
|
api_key = APIKey.new(seed=uid)
|
||||||
# print "Created temporary api key"
|
|
||||||
else:
|
else:
|
||||||
# This is a client that already has a session, use it
|
# This is a client that already has a session, use it
|
||||||
auth_header = auth
|
auth_header = auth
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from twisted.web import server
|
from zope.interface import implements
|
||||||
|
from twisted.web import server, resource
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from txjsonrpc import jsonrpclib
|
from txjsonrpc import jsonrpclib
|
||||||
from txjsonrpc.web import jsonrpc
|
|
||||||
from txjsonrpc.web.jsonrpc import Handler
|
|
||||||
|
|
||||||
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError
|
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError, SubhandlerError
|
||||||
from lbrynet.lbrynet_daemon.auth.util import APIKey
|
from lbrynet.conf import API_INTERFACE, REFERER, ORIGIN
|
||||||
|
from lbrynet.lbrynet_daemon.auth.util import APIKey, get_auth_message
|
||||||
from lbrynet.lbrynet_daemon.auth.client import LBRY_SECRET
|
from lbrynet.lbrynet_daemon.auth.client import LBRY_SECRET
|
||||||
from lbrynet.conf import ALLOWED_DURING_STARTUP
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -20,42 +19,166 @@ def default_decimal(obj):
|
||||||
return float(obj)
|
return float(obj)
|
||||||
|
|
||||||
|
|
||||||
def authorizer(cls):
|
class AuthorizedBase(object):
|
||||||
cls.authorized_functions = []
|
def __init__(self):
|
||||||
for methodname in dir(cls):
|
self.authorized_functions = []
|
||||||
if methodname.startswith("jsonrpc_"):
|
self.subhandlers = []
|
||||||
method = getattr(cls, methodname)
|
self.callable_methods = {}
|
||||||
if hasattr(method, '_auth_required'):
|
|
||||||
cls.authorized_functions.append(methodname.split("jsonrpc_")[1])
|
for methodname in dir(self):
|
||||||
return cls
|
if methodname.startswith("jsonrpc_"):
|
||||||
|
method = getattr(self, methodname)
|
||||||
|
self.callable_methods.update({methodname.split("jsonrpc_")[1]: method})
|
||||||
|
if hasattr(method, '_auth_required'):
|
||||||
|
self.authorized_functions.append(methodname.split("jsonrpc_")[1])
|
||||||
|
elif not methodname.startswith("__"):
|
||||||
|
method = getattr(self, methodname)
|
||||||
|
if hasattr(method, '_subhandler'):
|
||||||
|
self.subhandlers.append(method)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def auth_required(f):
|
||||||
|
f._auth_required = True
|
||||||
|
return f
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def subhandler(f):
|
||||||
|
f._subhandler = True
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
def auth_required(f):
|
class AuthJSONRPCServer(AuthorizedBase):
|
||||||
f._auth_required = True
|
"""
|
||||||
return f
|
Authorized JSONRPC server used as the base class for the LBRY API
|
||||||
|
|
||||||
|
API methods are named with a leading "jsonrpc_"
|
||||||
|
|
||||||
@authorizer
|
Decorators:
|
||||||
class LBRYJSONRPCServer(jsonrpc.JSONRPC):
|
@AuthJSONRPCServer.auth_required: this requires the client include a valid hmac authentication token in their
|
||||||
|
request
|
||||||
|
|
||||||
|
@AuthJSONRPCServer.subhandler: include the tagged method in the processing of requests, to allow inheriting
|
||||||
|
classes to modify request handling. Tagged methods will be passed the request
|
||||||
|
object, and return True when finished to indicate success
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
allowed_during_startup (list): list of api methods that are callable before the server has finished
|
||||||
|
startup
|
||||||
|
|
||||||
|
sessions (dict): dictionary of active session_id: lbrynet.lbrynet_daemon.auth.util.APIKey values
|
||||||
|
|
||||||
|
authorized_functions (list): list of api methods that require authentication
|
||||||
|
|
||||||
|
subhandlers (list): list of subhandlers
|
||||||
|
|
||||||
|
callable_methods (dict): dictionary of api_callable_name: method values
|
||||||
|
"""
|
||||||
|
implements(resource.IResource)
|
||||||
|
|
||||||
isLeaf = True
|
isLeaf = True
|
||||||
|
OK = 200
|
||||||
|
UNAUTHORIZED = 401
|
||||||
|
NOT_FOUND = 8001
|
||||||
|
FAILURE = 8002
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
jsonrpc.JSONRPC.__init__(self)
|
AuthorizedBase.__init__(self)
|
||||||
|
self.allowed_during_startup = []
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
return NotImplementedError()
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
assert self._check_headers(request), InvalidHeaderError
|
||||||
|
|
||||||
|
session = request.getSession()
|
||||||
|
session_id = session.uid
|
||||||
|
|
||||||
|
# if this is a new session, send a new secret and set the expiration, otherwise, session.touch()
|
||||||
|
if self._initialize_session(session_id):
|
||||||
|
def expire_session():
|
||||||
|
self._unregister_user_session(session_id)
|
||||||
|
session.startCheckingExpiration()
|
||||||
|
session.notifyOnExpire(expire_session)
|
||||||
|
message = "OK"
|
||||||
|
request.setResponseCode(self.OK)
|
||||||
|
self._set_headers(request, message, True)
|
||||||
|
self._render_message(request, message)
|
||||||
|
return server.NOT_DONE_YET
|
||||||
|
session.touch()
|
||||||
|
|
||||||
|
request.content.seek(0, 0)
|
||||||
|
content = request.content.read()
|
||||||
|
try:
|
||||||
|
parsed = jsonrpclib.loads(content)
|
||||||
|
except ValueError:
|
||||||
|
return server.failure
|
||||||
|
|
||||||
|
function_name = parsed.get('method')
|
||||||
|
args = parsed.get('params')
|
||||||
|
id = parsed.get('id')
|
||||||
|
token = parsed.pop('hmac', None)
|
||||||
|
version = self._get_jsonrpc_version(parsed.get('jsonrpc'), id)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._run_subhandlers(request)
|
||||||
|
except SubhandlerError:
|
||||||
|
return server.failure
|
||||||
|
|
||||||
|
reply_with_next_secret = False
|
||||||
|
if function_name in self.authorized_functions:
|
||||||
|
try:
|
||||||
|
self._verify_token(session_id, parsed, token)
|
||||||
|
except InvalidAuthenticationToken:
|
||||||
|
log.warning("API validation failed")
|
||||||
|
request.setResponseCode(self.UNAUTHORIZED)
|
||||||
|
request.finish()
|
||||||
|
return server.NOT_DONE_YET
|
||||||
|
self._update_session_secret(session_id)
|
||||||
|
reply_with_next_secret = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
function = self._get_jsonrpc_method(function_name)
|
||||||
|
except Exception:
|
||||||
|
log.warning("Unknown method: %s", function_name)
|
||||||
|
return server.failure
|
||||||
|
|
||||||
|
d = defer.maybeDeferred(function) if args == [{}] else defer.maybeDeferred(function, *args)
|
||||||
|
# cancel the response if the connection is broken
|
||||||
|
notify_finish = request.notifyFinish()
|
||||||
|
notify_finish.addErrback(self._response_failed, d)
|
||||||
|
d.addErrback(self._errback_render, id)
|
||||||
|
d.addCallback(self._callback_render, request, id, version, reply_with_next_secret)
|
||||||
|
d.addErrback(notify_finish.errback)
|
||||||
|
|
||||||
|
return server.NOT_DONE_YET
|
||||||
|
|
||||||
def _register_user_session(self, session_id):
|
def _register_user_session(self, session_id):
|
||||||
|
"""
|
||||||
|
Add or update a HMAC secret for a session
|
||||||
|
|
||||||
|
@param session_id:
|
||||||
|
@return: secret
|
||||||
|
"""
|
||||||
token = APIKey.new()
|
token = APIKey.new()
|
||||||
self.sessions.update({session_id: token})
|
self.sessions.update({session_id: token})
|
||||||
return token
|
return token
|
||||||
|
|
||||||
def _responseFailed(self, err, call):
|
def _unregister_user_session(self, session_id):
|
||||||
|
log.info("Unregister API session")
|
||||||
|
del self.sessions[session_id]
|
||||||
|
|
||||||
|
def _response_failed(self, err, call):
|
||||||
log.debug(err.getTraceback())
|
log.debug(err.getTraceback())
|
||||||
|
|
||||||
def _set_headers(self, request, data):
|
def _set_headers(self, request, data, update_secret=False):
|
||||||
request.setHeader("Access-Control-Allow-Origin", "localhost")
|
request.setHeader("Access-Control-Allow-Origin", API_INTERFACE)
|
||||||
request.setHeader("Content-Type", "text/json")
|
request.setHeader("Content-Type", "text/json")
|
||||||
request.setHeader("Content-Length", str(len(data)))
|
request.setHeader("Content-Length", str(len(data)))
|
||||||
|
if update_secret:
|
||||||
|
session_id = request.getSession().uid
|
||||||
|
request.setHeader(LBRY_SECRET, self.sessions.get(session_id).secret)
|
||||||
|
|
||||||
def _render_message(self, request, message):
|
def _render_message(self, request, message):
|
||||||
request.write(message)
|
request.write(message)
|
||||||
|
@ -64,112 +187,81 @@ class LBRYJSONRPCServer(jsonrpc.JSONRPC):
|
||||||
def _check_headers(self, request):
|
def _check_headers(self, request):
|
||||||
origin = request.getHeader("Origin")
|
origin = request.getHeader("Origin")
|
||||||
referer = request.getHeader("Referer")
|
referer = request.getHeader("Referer")
|
||||||
|
if origin not in [None, ORIGIN]:
|
||||||
if origin not in [None, 'http://localhost:5279']:
|
|
||||||
log.warning("Attempted api call from %s", origin)
|
log.warning("Attempted api call from %s", origin)
|
||||||
raise InvalidHeaderError
|
return False
|
||||||
|
if referer is not None and not referer.startswith(REFERER):
|
||||||
if referer is not None and not referer.startswith('http://localhost:5279/'):
|
|
||||||
log.warning("Attempted api call from %s", referer)
|
log.warning("Attempted api call from %s", referer)
|
||||||
raise InvalidHeaderError
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def _handle(self, request):
|
def _check_function_path(self, function_path):
|
||||||
def _check_function_path(function_path):
|
if function_path not in self.callable_methods:
|
||||||
if not self.announced_startup:
|
log.warning("Unknown method: %s", function_path)
|
||||||
if function_path not in ALLOWED_DURING_STARTUP:
|
return False
|
||||||
log.warning("Cannot call %s during startup", function_path)
|
if not self.announced_startup:
|
||||||
raise Exception("Function not allowed")
|
if function_path not in self.allowed_during_startup:
|
||||||
|
log.warning("Cannot call %s during startup", function_path)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def _get_function(function_path):
|
def _get_jsonrpc_method(self, function_path):
|
||||||
function = self._getFunction(function_path)
|
assert self._check_function_path(function_path)
|
||||||
return function
|
return self.callable_methods.get(function_path)
|
||||||
|
|
||||||
def _verify_token(session_id, message, token):
|
def _initialize_session(self, session_id):
|
||||||
request.setHeader(LBRY_SECRET, "")
|
if not self.sessions.get(session_id, False):
|
||||||
api_key = self.sessions.get(session_id, None)
|
|
||||||
assert api_key is not None, InvalidAuthenticationToken
|
|
||||||
r = api_key.compare_hmac(message, token)
|
|
||||||
assert r, InvalidAuthenticationToken
|
|
||||||
# log.info("Generating new token for next request")
|
|
||||||
self.sessions.update({session_id: APIKey.new(name=session_id)})
|
|
||||||
request.setHeader(LBRY_SECRET, self.sessions.get(session_id).secret)
|
|
||||||
|
|
||||||
session = request.getSession()
|
|
||||||
session_id = session.uid
|
|
||||||
session_store = self.sessions.get(session_id, False)
|
|
||||||
|
|
||||||
if not session_store:
|
|
||||||
token = APIKey.new(seed=session_id, name=session_id)
|
|
||||||
log.info("Initializing new api session")
|
log.info("Initializing new api session")
|
||||||
self.sessions.update({session_id: token})
|
self.sessions.update({session_id: APIKey.new(seed=session_id, name=session_id)})
|
||||||
# log.info("Generated token %s", str(self.sessions[session_id]))
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
request.content.seek(0, 0)
|
def _verify_token(self, session_id, message, token):
|
||||||
content = request.content.read()
|
to_auth = get_auth_message(message)
|
||||||
|
api_key = self.sessions.get(session_id)
|
||||||
|
assert api_key.compare_hmac(to_auth, token), InvalidAuthenticationToken
|
||||||
|
|
||||||
parsed = jsonrpclib.loads(content)
|
def _update_session_secret(self, session_id):
|
||||||
|
# log.info("Generating new token for next request")
|
||||||
functionPath = parsed.get("method")
|
self.sessions.update({session_id: APIKey.new(name=session_id)})
|
||||||
|
|
||||||
_check_function_path(functionPath)
|
|
||||||
require_auth = functionPath in self.authorized_functions
|
|
||||||
if require_auth:
|
|
||||||
token = parsed.pop('hmac')
|
|
||||||
to_auth = functionPath.encode('hex') + str(parsed.get('id')).encode('hex')
|
|
||||||
_verify_token(session_id, to_auth.decode('hex'), token)
|
|
||||||
|
|
||||||
args = parsed.get('params')
|
|
||||||
id = parsed.get('id')
|
|
||||||
version = parsed.get('jsonrpc')
|
|
||||||
|
|
||||||
|
def _get_jsonrpc_version(self, version=None, id=None):
|
||||||
if version:
|
if version:
|
||||||
version = int(float(version))
|
version_for_return = int(float(version))
|
||||||
elif id and not version:
|
elif id and not version:
|
||||||
version = jsonrpclib.VERSION_1
|
version_for_return = jsonrpclib.VERSION_1
|
||||||
else:
|
else:
|
||||||
version = jsonrpclib.VERSION_PRE1
|
version_for_return = jsonrpclib.VERSION_PRE1
|
||||||
|
return version_for_return
|
||||||
|
|
||||||
if self.wallet_type == "lbryum" and functionPath in ['set_miner', 'get_miner_status']:
|
def _run_subhandlers(self, request):
|
||||||
log.warning("Mining commands are not available in lbryum")
|
for handler in self.subhandlers:
|
||||||
raise Exception("Command not available in lbryum")
|
try:
|
||||||
|
assert handler(request)
|
||||||
|
except Exception as err:
|
||||||
|
log.error(err.message)
|
||||||
|
raise SubhandlerError
|
||||||
|
|
||||||
try:
|
|
||||||
function = _get_function(functionPath)
|
|
||||||
if args == [{}]:
|
|
||||||
d = defer.maybeDeferred(function)
|
|
||||||
else:
|
|
||||||
d = defer.maybeDeferred(function, *args)
|
|
||||||
except jsonrpclib.Fault as f:
|
|
||||||
d = self._cbRender(f, request, id, version)
|
|
||||||
finally:
|
|
||||||
# cancel the response if the connection is broken
|
|
||||||
notify_finish = request.notifyFinish()
|
|
||||||
notify_finish.addErrback(self._responseFailed, d)
|
|
||||||
d.addErrback(self._ebRender, id)
|
|
||||||
d.addCallback(self._cbRender, request, id, version)
|
|
||||||
d.addErrback(notify_finish.errback)
|
|
||||||
|
|
||||||
def _cbRender(self, result, request, id, version):
|
def _callback_render(self, result, request, id, version, auth_required=False):
|
||||||
if isinstance(result, Handler):
|
result_for_return = result if not isinstance(result, dict) else result['result']
|
||||||
result = result.result
|
|
||||||
|
|
||||||
if isinstance(result, dict):
|
|
||||||
result = result['result']
|
|
||||||
|
|
||||||
if version == jsonrpclib.VERSION_PRE1:
|
if version == jsonrpclib.VERSION_PRE1:
|
||||||
if not isinstance(result, jsonrpclib.Fault):
|
if not isinstance(result, jsonrpclib.Fault):
|
||||||
result = (result,)
|
result_for_return = (result_for_return,)
|
||||||
# Convert the result (python) to JSON-RPC
|
# Convert the result (python) to JSON-RPC
|
||||||
try:
|
try:
|
||||||
s = jsonrpclib.dumps(result, version=version, default=default_decimal)
|
encoded_message = jsonrpclib.dumps(result_for_return, version=version, default=default_decimal)
|
||||||
self._render_message(request, s)
|
self._set_headers(request, encoded_message, auth_required)
|
||||||
|
self._render_message(request, encoded_message)
|
||||||
except:
|
except:
|
||||||
f = jsonrpclib.Fault(self.FAILURE, "can't serialize output")
|
fault = jsonrpclib.Fault(self.FAILURE, "can't serialize output")
|
||||||
s = jsonrpclib.dumps(f, version=version)
|
encoded_message = jsonrpclib.dumps(fault, version=version)
|
||||||
self._set_headers(request, s)
|
self._set_headers(request, encoded_message)
|
||||||
self._render_message(request, s)
|
self._render_message(request, encoded_message)
|
||||||
|
|
||||||
def _ebRender(self, failure, id):
|
def _errback_render(self, failure, id):
|
||||||
|
log.error("Request failed:")
|
||||||
log.error(failure)
|
log.error(failure)
|
||||||
log.error(failure.value)
|
log.error(failure.value)
|
||||||
log.error(id)
|
log.error(id)
|
||||||
|
@ -177,19 +269,6 @@ class LBRYJSONRPCServer(jsonrpc.JSONRPC):
|
||||||
return failure.value
|
return failure.value
|
||||||
return server.failure
|
return server.failure
|
||||||
|
|
||||||
def render(self, request):
|
|
||||||
try:
|
|
||||||
self._check_headers(request)
|
|
||||||
except InvalidHeaderError:
|
|
||||||
return server.failure
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._handle(request)
|
|
||||||
except:
|
|
||||||
return server.failure
|
|
||||||
|
|
||||||
return server.NOT_DONE_YET
|
|
||||||
|
|
||||||
def _render_response(self, result, code):
|
def _render_response(self, result, code):
|
||||||
return defer.succeed({'result': result, 'code': code})
|
return defer.succeed({'result': result, 'code': code})
|
||||||
|
|
||||||
|
|
|
@ -84,4 +84,10 @@ def initialize_api_key_file(key_path):
|
||||||
keys = {}
|
keys = {}
|
||||||
new_api_key = APIKey.new(name=API_KEY_NAME)
|
new_api_key = APIKey.new(name=API_KEY_NAME)
|
||||||
keys.update({new_api_key.name: new_api_key})
|
keys.update({new_api_key.name: new_api_key})
|
||||||
save_api_keys(keys, key_path)
|
save_api_keys(keys, key_path)
|
||||||
|
|
||||||
|
|
||||||
|
def get_auth_message(message_dict):
|
||||||
|
to_auth = message_dict.get('method').encode('hex')
|
||||||
|
to_auth += str(message_dict.get('id')).encode('hex')
|
||||||
|
return to_auth.decode('hex')
|
Loading…
Reference in a new issue