clean up
This commit is contained in:
parent
130f9cfc4d
commit
aecafbbebd
8 changed files with 173 additions and 152 deletions
|
@ -2,7 +2,24 @@
|
||||||
Some network wide and also application specific parameters
|
Some network wide and also application specific parameters
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
from appdirs import user_data_dir
|
||||||
|
|
||||||
|
LINUX = 1
|
||||||
|
DARWIN = 2
|
||||||
|
WINDOWS = 3
|
||||||
|
|
||||||
|
if sys.platform.startswith("linux"):
|
||||||
|
platform = LINUX
|
||||||
|
elif sys.platform.startswith("darwin"):
|
||||||
|
platform = DARWIN
|
||||||
|
elif sys.platform.startswith("win"):
|
||||||
|
platform = WINDOWS
|
||||||
|
|
||||||
|
if platform is LINUX:
|
||||||
|
DATA_DIR = os.path.join(os.path.expanduser("~"), ".lbrynet")
|
||||||
|
else:
|
||||||
|
DATA_DIR = user_data_dir("LBRY")
|
||||||
|
|
||||||
IS_DEVELOPMENT_VERSION = False
|
IS_DEVELOPMENT_VERSION = False
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,11 @@ def get_params_from_kwargs(params):
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
api = LBRYAPIClient()
|
api = LBRYAPIClient.config()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
s = api.is_running()
|
status = api.daemon_status()
|
||||||
|
assert status.get('code', False) == "started"
|
||||||
except:
|
except:
|
||||||
print "lbrynet-daemon isn't running"
|
print "lbrynet-daemon isn't running"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -71,10 +72,10 @@ def main():
|
||||||
if meth in api.help():
|
if meth in api.help():
|
||||||
try:
|
try:
|
||||||
if params:
|
if params:
|
||||||
r = LBRYAPIClient(service=meth)(params)
|
result = LBRYAPIClient.config(service=meth)(params)
|
||||||
else:
|
else:
|
||||||
r = LBRYAPIClient(service=meth)()
|
result = LBRYAPIClient.config(service=meth)()
|
||||||
print json.dumps(r, sort_keys=True)
|
print json.dumps(result, sort_keys=True)
|
||||||
except:
|
except:
|
||||||
print "Something went wrong, here's the usage for %s:" % meth
|
print "Something went wrong, here's the usage for %s:" % meth
|
||||||
print api.help({'function': meth})
|
print api.help({'function': meth})
|
||||||
|
|
|
@ -16,14 +16,10 @@ from jsonrpc.proxy import JSONRPCProxy
|
||||||
from lbrynet.core import log_support
|
from lbrynet.core import log_support
|
||||||
from lbrynet.lbrynet_daemon.LBRYDaemonServer import LBRYDaemonServer, LBRYDaemonRequest
|
from lbrynet.lbrynet_daemon.LBRYDaemonServer import LBRYDaemonServer, LBRYDaemonRequest
|
||||||
from lbrynet.lbrynet_daemon.auth.auth import PasswordChecker, HttpPasswordRealm
|
from lbrynet.lbrynet_daemon.auth.auth import PasswordChecker, HttpPasswordRealm
|
||||||
|
from lbrynet.lbrynet_daemon.auth.util import initialize_api_key_file
|
||||||
from lbrynet.conf import API_CONNECTION_STRING, API_INTERFACE, API_PORT, \
|
from lbrynet.conf import API_CONNECTION_STRING, API_INTERFACE, API_PORT, \
|
||||||
UI_ADDRESS, DEFAULT_UI_BRANCH, LOG_FILE_NAME
|
UI_ADDRESS, DEFAULT_UI_BRANCH, LOG_FILE_NAME
|
||||||
|
from lbrynet.conf import DATA_DIR as log_dir
|
||||||
# TODO: stop it!
|
|
||||||
if sys.platform != "darwin":
|
|
||||||
log_dir = os.path.join(os.path.expanduser("~"), ".lbrynet")
|
|
||||||
else:
|
|
||||||
log_dir = user_data_dir("LBRY")
|
|
||||||
|
|
||||||
if not os.path.isdir(log_dir):
|
if not os.path.isdir(log_dir):
|
||||||
os.mkdir(log_dir)
|
os.mkdir(log_dir)
|
||||||
|
@ -116,11 +112,13 @@ def start():
|
||||||
if args.launchui:
|
if args.launchui:
|
||||||
d.addCallback(lambda _: webbrowser.open(UI_ADDRESS))
|
d.addCallback(lambda _: webbrowser.open(UI_ADDRESS))
|
||||||
|
|
||||||
checker = PasswordChecker()
|
pw_path = os.path.join(log_dir, ".api_keys")
|
||||||
|
initialize_api_key_file(pw_path)
|
||||||
|
checker = PasswordChecker.load_file(pw_path)
|
||||||
realm = HttpPasswordRealm(lbry.root)
|
realm = HttpPasswordRealm(lbry.root)
|
||||||
p = portal.Portal(realm, [checker, ])
|
portal_to_realm = portal.Portal(realm, [checker, ])
|
||||||
factory = guard.BasicCredentialFactory('Login to lbrynet api')
|
factory = guard.BasicCredentialFactory('Login to lbrynet api')
|
||||||
protected_resource = guard.HTTPAuthSessionWrapper(p, [factory, ])
|
protected_resource = guard.HTTPAuthSessionWrapper(portal_to_realm, [factory, ])
|
||||||
lbrynet_server = server.Site(protected_resource)
|
lbrynet_server = server.Site(protected_resource)
|
||||||
lbrynet_server.requestFactory = LBRYDaemonRequest
|
lbrynet_server.requestFactory = LBRYDaemonRequest
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,15 @@ class MarketFeed(object):
|
||||||
log.debug("Saving price update %f for %s" % (price, self.market))
|
log.debug("Saving price update %f for %s" % (price, self.market))
|
||||||
self.rate = ExchangeRate(self.market, price, int(time.time()))
|
self.rate = ExchangeRate(self.market, price, int(time.time()))
|
||||||
|
|
||||||
|
def _log_error(self):
|
||||||
|
log.warning("%s failed to update exchange rate information", self.name)
|
||||||
|
|
||||||
def _update_price(self):
|
def _update_price(self):
|
||||||
d = defer.succeed(self._make_request())
|
d = defer.succeed(self._make_request())
|
||||||
d.addCallback(self._handle_response)
|
d.addCallback(self._handle_response)
|
||||||
d.addCallback(self._subtract_fee)
|
d.addCallback(self._subtract_fee)
|
||||||
d.addCallback(self._save_price)
|
d.addCallback(self._save_price)
|
||||||
|
d.addErrback(lambda _: self._log_error())
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if not self._updater.running:
|
if not self._updater.running:
|
||||||
|
|
|
@ -1,26 +1,15 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
from zope.interface import implementer
|
||||||
from zope.interface import implements, implementer
|
|
||||||
from twisted.cred import portal, checkers, credentials, error as cred_error
|
from twisted.cred import portal, checkers, credentials, error as cred_error
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.web import resource
|
from twisted.web import resource
|
||||||
from lbrynet.lbrynet_daemon.auth.util import load_api_keys, APIKey, API_KEY_NAME, save_api_keys
|
from lbrynet.lbrynet_daemon.auth.util import load_api_keys, APIKey, API_KEY_NAME, save_api_keys
|
||||||
from lbrynet.lbrynet_daemon.LBRYDaemon import log_dir as DATA_DIR
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# initialize api key if none exist
|
|
||||||
if not os.path.isfile(os.path.join(DATA_DIR, ".api_keys")):
|
|
||||||
keys = {}
|
|
||||||
api_key = APIKey.new()
|
|
||||||
api_key.rename(API_KEY_NAME)
|
|
||||||
keys.update(api_key)
|
|
||||||
save_api_keys(keys, os.path.join(DATA_DIR, ".api_keys"))
|
|
||||||
|
|
||||||
|
|
||||||
@implementer(portal.IRealm)
|
@implementer(portal.IRealm)
|
||||||
class HttpPasswordRealm:
|
class HttpPasswordRealm(object):
|
||||||
def __init__(self, resource):
|
def __init__(self, resource):
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
|
|
||||||
|
@ -31,19 +20,28 @@ class HttpPasswordRealm:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class PasswordChecker:
|
@implementer(checkers.ICredentialsChecker)
|
||||||
implements(checkers.ICredentialsChecker)
|
class PasswordChecker(object):
|
||||||
credentialInterfaces = (credentials.IUsernamePassword,)
|
credentialInterfaces = (credentials.IUsernamePassword,)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, passwords):
|
||||||
keys = load_api_keys(os.path.join(DATA_DIR, ".api_keys"))
|
self.passwords = passwords
|
||||||
self.passwords = {key: keys[key]['token'] for key in keys}
|
|
||||||
|
@classmethod
|
||||||
|
def load_file(cls, key_path):
|
||||||
|
keys = load_api_keys(key_path)
|
||||||
|
return cls.load(keys)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, password_dict):
|
||||||
|
passwords = {key: password_dict[key].secret for key in password_dict}
|
||||||
|
return cls(passwords)
|
||||||
|
|
||||||
def requestAvatarId(self, creds):
|
def requestAvatarId(self, creds):
|
||||||
if creds.username in self.passwords:
|
if creds.username in self.passwords:
|
||||||
pw = self.passwords.get(creds.username)
|
pw = self.passwords.get(creds.username)
|
||||||
pw_match = creds.checkPassword(pw)
|
pw_match = creds.checkPassword(pw)
|
||||||
if pw_match is True:
|
if pw_match:
|
||||||
return defer.succeed(creds.username)
|
return defer.succeed(creds.username)
|
||||||
log.warning('Incorrect username or password')
|
log.warning('Incorrect username or password')
|
||||||
return defer.fail(cred_error.UnauthorizedLogin('Incorrect username or password'))
|
return defer.fail(cred_error.UnauthorizedLogin('Incorrect username or password'))
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
try:
|
import urlparse
|
||||||
import http.client as httplib
|
|
||||||
except ImportError:
|
|
||||||
import httplib
|
|
||||||
try:
|
|
||||||
import urllib.parse as urlparse
|
|
||||||
except ImportError:
|
|
||||||
import urlparse
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
|
@ -15,10 +7,12 @@ 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
|
||||||
from lbrynet.conf import API_INTERFACE, API_ADDRESS, API_PORT
|
from lbrynet.conf import API_INTERFACE, API_ADDRESS, API_PORT
|
||||||
from lbrynet.lbrynet_daemon.LBRYDaemon import log_dir as DATA_DIR
|
from lbrynet.conf import DATA_DIR
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
USER_AGENT = "AuthServiceProxy/0.1"
|
USER_AGENT = "AuthServiceProxy/0.1"
|
||||||
|
TWISTED_SESSION = "TWISTED_SESSION"
|
||||||
|
LBRY_SECRET = "LBRY_SECRET"
|
||||||
HTTP_TIMEOUT = 30
|
HTTP_TIMEOUT = 30
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,77 +23,15 @@ class JSONRPCException(Exception):
|
||||||
|
|
||||||
|
|
||||||
class LBRYAPIClient(object):
|
class LBRYAPIClient(object):
|
||||||
__api_token = None
|
def __init__(self, key, timeout, connection, count, service, cookies, auth, url, login_url):
|
||||||
|
|
||||||
def __init__(self, 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):
|
|
||||||
self.__api_key_name = API_KEY_NAME if not key_name else key_name
|
|
||||||
self.__api_token = key
|
|
||||||
self.__pw_path = os.path.join(DATA_DIR, ".api_keys") if not pw_path else pw_path
|
|
||||||
self.__service_name = service
|
self.__service_name = service
|
||||||
|
self.__api_key = key
|
||||||
if not key:
|
self.__service_url = login_url
|
||||||
keys = load_api_keys(self.__pw_path)
|
|
||||||
api_key = keys.get(self.__api_key_name, False)
|
|
||||||
self.__api_token = api_key['token']
|
|
||||||
self.__api_key_obj = api_key
|
|
||||||
else:
|
|
||||||
self.__api_key_obj = APIKey({'token': key})
|
|
||||||
|
|
||||||
if login_url is None:
|
|
||||||
self.__service_url = "http://%s:%s@%s:%i/%s" % (self.__api_key_name, self.__api_token,
|
|
||||||
API_INTERFACE, API_PORT, API_ADDRESS)
|
|
||||||
else:
|
|
||||||
self.__service_url = login_url
|
|
||||||
|
|
||||||
self.__id_count = count
|
self.__id_count = count
|
||||||
|
self.__url = url
|
||||||
if auth is None and connection is None and cookies is None and url is None:
|
self.__auth_header = auth
|
||||||
self.__url = urlparse.urlparse(self.__service_url)
|
self.__conn = connection
|
||||||
(user, passwd) = (self.__url.username, self.__url.password)
|
self.__cookies = cookies
|
||||||
try:
|
|
||||||
user = user.encode('utf8')
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
passwd = passwd.encode('utf8')
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
authpair = user + b':' + passwd
|
|
||||||
self.__auth_header = b'Basic ' + base64.b64encode(authpair)
|
|
||||||
|
|
||||||
self.__conn = requests.Session()
|
|
||||||
self.__conn.auth = (user, passwd)
|
|
||||||
|
|
||||||
req = requests.Request(method='POST',
|
|
||||||
url=self.__service_url,
|
|
||||||
auth=self.__conn.auth,
|
|
||||||
headers={'Host': self.__url.hostname,
|
|
||||||
'User-Agent': USER_AGENT,
|
|
||||||
'Authorization': self.__auth_header,
|
|
||||||
'Content-type': 'application/json'},)
|
|
||||||
r = req.prepare()
|
|
||||||
http_response = self.__conn.send(r)
|
|
||||||
cookies = http_response.cookies
|
|
||||||
self.__cookies = cookies
|
|
||||||
# print "Logged in"
|
|
||||||
|
|
||||||
uid = cookies.get('TWISTED_SESSION')
|
|
||||||
api_key = APIKey.new(seed=uid)
|
|
||||||
# print "Created temporary api key"
|
|
||||||
|
|
||||||
self.__api_token = api_key.token()
|
|
||||||
self.__api_key_obj = api_key
|
|
||||||
else:
|
|
||||||
self.__auth_header = auth
|
|
||||||
self.__conn = connection
|
|
||||||
self.__cookies = cookies
|
|
||||||
self.__url = url
|
|
||||||
|
|
||||||
if cookies.get("secret", False):
|
|
||||||
self.__api_token = cookies.get("secret")
|
|
||||||
self.__api_key_obj = APIKey({'name': self.__api_key_name, 'token': self.__api_token})
|
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if name.startswith('__') and name.endswith('__'):
|
if name.startswith('__') and name.endswith('__'):
|
||||||
|
@ -107,11 +39,11 @@ class LBRYAPIClient(object):
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
if self.__service_name is not None:
|
if self.__service_name is not None:
|
||||||
name = "%s.%s" % (self.__service_name, name)
|
name = "%s.%s" % (self.__service_name, name)
|
||||||
return LBRYAPIClient(key_name=self.__api_key_name,
|
return LBRYAPIClient(key=self.__api_key,
|
||||||
key=self.__api_token,
|
timeout=HTTP_TIMEOUT,
|
||||||
connection=self.__conn,
|
connection=self.__conn,
|
||||||
service=name,
|
|
||||||
count=self.__id_count,
|
count=self.__id_count,
|
||||||
|
service=name,
|
||||||
cookies=self.__cookies,
|
cookies=self.__cookies,
|
||||||
auth=self.__auth_header,
|
auth=self.__auth_header,
|
||||||
url=self.__url,
|
url=self.__url,
|
||||||
|
@ -124,7 +56,7 @@ class LBRYAPIClient(object):
|
||||||
'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 = str(pre_auth_postdata['method']).encode('hex') + str(pre_auth_postdata['id']).encode('hex')
|
||||||
token = self.__api_key_obj.get_hmac(to_auth.decode('hex'))
|
token = self.__api_key.get_hmac(to_auth.decode('hex'))
|
||||||
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
|
||||||
|
@ -142,12 +74,14 @@ class LBRYAPIClient(object):
|
||||||
cookies=cookies)
|
cookies=cookies)
|
||||||
r = req.prepare()
|
r = req.prepare()
|
||||||
http_response = self.__conn.send(r)
|
http_response = self.__conn.send(r)
|
||||||
self.__cookies = http_response.cookies
|
cookies = http_response.cookies
|
||||||
headers = http_response.headers
|
headers = http_response.headers
|
||||||
next_secret = headers.get('Next-Secret', False)
|
next_secret = headers.get(LBRY_SECRET, False)
|
||||||
|
|
||||||
if next_secret:
|
if next_secret:
|
||||||
cookies.update({'secret': next_secret})
|
# print "Next secret: %s" % next_secret
|
||||||
|
self.__api_key.secret = next_secret
|
||||||
|
self.__cookies = cookies
|
||||||
|
|
||||||
# print "Postdata: %s" % postdata
|
# print "Postdata: %s" % postdata
|
||||||
if http_response is None:
|
if http_response is None:
|
||||||
|
@ -165,4 +99,65 @@ class LBRYAPIClient(object):
|
||||||
raise JSONRPCException({
|
raise JSONRPCException({
|
||||||
'code': -343, 'message': 'missing JSON-RPC result'})
|
'code': -343, 'message': 'missing JSON-RPC result'})
|
||||||
else:
|
else:
|
||||||
return response['result']
|
return response['result']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
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):
|
||||||
|
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
|
||||||
|
|
||||||
|
if not key:
|
||||||
|
keys = load_api_keys(pw_path)
|
||||||
|
api_key = keys.get(api_key_name, False)
|
||||||
|
else:
|
||||||
|
api_key = APIKey(name=api_key_name, secret=key)
|
||||||
|
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
service_url = login_url
|
||||||
|
|
||||||
|
id_count = count
|
||||||
|
|
||||||
|
if auth is None and connection is None and cookies is None and url is None:
|
||||||
|
# This is a new client instance, initialize the auth header and start a session
|
||||||
|
url = urlparse.urlparse(service_url)
|
||||||
|
(user, passwd) = (url.username, url.password)
|
||||||
|
try:
|
||||||
|
user = user.encode('utf8')
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
passwd = passwd.encode('utf8')
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
authpair = user + b':' + passwd
|
||||||
|
auth_header = b'Basic ' + base64.b64encode(authpair)
|
||||||
|
|
||||||
|
conn = requests.Session()
|
||||||
|
conn.auth = (user, passwd)
|
||||||
|
|
||||||
|
req = requests.Request(method='POST',
|
||||||
|
url=service_url,
|
||||||
|
auth=conn.auth,
|
||||||
|
headers={'Host': url.hostname,
|
||||||
|
'User-Agent': USER_AGENT,
|
||||||
|
'Authorization': auth_header,
|
||||||
|
'Content-type': 'application/json'},)
|
||||||
|
r = req.prepare()
|
||||||
|
http_response = conn.send(r)
|
||||||
|
cookies = http_response.cookies
|
||||||
|
# print "Logged in"
|
||||||
|
|
||||||
|
uid = cookies.get(TWISTED_SESSION)
|
||||||
|
api_key = APIKey.new(seed=uid)
|
||||||
|
# print "Created temporary api key"
|
||||||
|
else:
|
||||||
|
# This is a client that already has a session, use it
|
||||||
|
auth_header = auth
|
||||||
|
conn = connection
|
||||||
|
assert cookies.get(LBRY_SECRET, False), "Missing cookie"
|
||||||
|
secret = cookies.get(LBRY_SECRET)
|
||||||
|
api_key = APIKey(secret, api_key_name)
|
||||||
|
return cls(api_key, timeout, conn, id_count, service, cookies, auth_header, url, service_url)
|
|
@ -9,6 +9,7 @@ from txjsonrpc.web.jsonrpc import Handler
|
||||||
|
|
||||||
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError
|
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError
|
||||||
from lbrynet.lbrynet_daemon.auth.util import APIKey
|
from lbrynet.lbrynet_daemon.auth.util import APIKey
|
||||||
|
from lbrynet.lbrynet_daemon.auth.client import LBRY_SECRET
|
||||||
from lbrynet.conf import ALLOWED_DURING_STARTUP
|
from lbrynet.conf import ALLOWED_DURING_STARTUP
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -84,21 +85,21 @@ class LBRYJSONRPCServer(jsonrpc.JSONRPC):
|
||||||
return function
|
return function
|
||||||
|
|
||||||
def _verify_token(session_id, message, token):
|
def _verify_token(session_id, message, token):
|
||||||
request.setHeader("Next-Secret", "")
|
request.setHeader(LBRY_SECRET, "")
|
||||||
api_key = self.sessions.get(session_id, None)
|
api_key = self.sessions.get(session_id, None)
|
||||||
assert api_key is not None, InvalidAuthenticationToken
|
assert api_key is not None, InvalidAuthenticationToken
|
||||||
r = api_key.compare_hmac(message, token)
|
r = api_key.compare_hmac(message, token)
|
||||||
assert r, InvalidAuthenticationToken
|
assert r, InvalidAuthenticationToken
|
||||||
# log.info("Generating new token for next request")
|
# log.info("Generating new token for next request")
|
||||||
self.sessions.update({session_id: APIKey.new()})
|
self.sessions.update({session_id: APIKey.new(name=session_id)})
|
||||||
request.setHeader("Next-Secret", self.sessions.get(session_id).token())
|
request.setHeader(LBRY_SECRET, self.sessions.get(session_id).secret)
|
||||||
|
|
||||||
session = request.getSession()
|
session = request.getSession()
|
||||||
session_id = session.uid
|
session_id = session.uid
|
||||||
session_store = self.sessions.get(session_id, False)
|
session_store = self.sessions.get(session_id, False)
|
||||||
|
|
||||||
if not session_store:
|
if not session_store:
|
||||||
token = APIKey.new(seed=session_id)
|
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: token})
|
||||||
# log.info("Generated token %s", str(self.sessions[session_id]))
|
# log.info("Generated token %s", str(self.sessions[session_id]))
|
||||||
|
@ -191,3 +192,5 @@ class LBRYJSONRPCServer(jsonrpc.JSONRPC):
|
||||||
|
|
||||||
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})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,24 +22,20 @@ def generate_key(x=None):
|
||||||
return sha(x)
|
return sha(x)
|
||||||
|
|
||||||
|
|
||||||
class APIKey(dict):
|
class APIKey(object):
|
||||||
def __init__(self, key, name=None):
|
def __init__(self, secret, name, expiration=None):
|
||||||
self.key = key if isinstance(key, str) else key['token']
|
self.secret = secret
|
||||||
self.name = name if name else hashlib.sha256(self.key).hexdigest()
|
self.name = name
|
||||||
self.expiration = None if isinstance(key, str) else key.get('expiration', None)
|
self.expiration = expiration
|
||||||
self.update({self.name: {'token': self.key, 'expiration': self.expiration}})
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def new(cls, expiration=None, seed=None, name=None):
|
def new(cls, seed=None, name=None, expiration=None):
|
||||||
key_val = generate_key(seed)
|
secret = generate_key(seed)
|
||||||
key = {'token': key_val, 'expiration': expiration}
|
key_name = name if name else sha(secret)
|
||||||
return APIKey(key, name)
|
return APIKey(secret, key_name, expiration)
|
||||||
|
|
||||||
def token(self):
|
|
||||||
return self[self.name]['token']
|
|
||||||
|
|
||||||
def _raw_key(self):
|
def _raw_key(self):
|
||||||
return base58.b58decode(self.token())
|
return base58.b58decode(self.secret)
|
||||||
|
|
||||||
def get_hmac(self, message):
|
def get_hmac(self, message):
|
||||||
decoded_key = self._raw_key()
|
decoded_key = self._raw_key()
|
||||||
|
@ -56,27 +52,36 @@ class APIKey(dict):
|
||||||
return False
|
return False
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def rename(self, name):
|
|
||||||
old = self.keys()[0]
|
|
||||||
t = self.pop(old)
|
|
||||||
self.update({name: t})
|
|
||||||
|
|
||||||
|
|
||||||
def load_api_keys(path):
|
def load_api_keys(path):
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
raise Exception("Invalid api key path")
|
raise Exception("Invalid api key path")
|
||||||
|
|
||||||
f = open(path, "r")
|
with open(path, "r") as f:
|
||||||
data = yaml.load(f.read())
|
data = yaml.load(f.read())
|
||||||
f.close()
|
|
||||||
|
|
||||||
keys = {key: APIKey(data[key], name=key)[key] for key in data}
|
keys_for_return = {}
|
||||||
|
for key_name in data:
|
||||||
|
key = data[key_name]
|
||||||
|
secret = key['secret']
|
||||||
|
expiration = key['expiration']
|
||||||
|
keys_for_return.update({key_name: APIKey(secret, key_name, expiration)})
|
||||||
|
|
||||||
return keys
|
return keys_for_return
|
||||||
|
|
||||||
|
|
||||||
def save_api_keys(keys, path):
|
def save_api_keys(keys, path):
|
||||||
data = yaml.safe_dump(dict(keys))
|
with open(path, "w") as f:
|
||||||
f = open(path, "w")
|
key_dict = {keys[key_name].name: {'secret': keys[key_name].secret,
|
||||||
f.write(data)
|
'expiration': keys[key_name].expiration}
|
||||||
f.close()
|
for key_name in keys}
|
||||||
|
data = yaml.safe_dump(key_dict)
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_api_key_file(key_path):
|
||||||
|
if not os.path.isfile(key_path):
|
||||||
|
keys = {}
|
||||||
|
new_api_key = APIKey.new(name=API_KEY_NAME)
|
||||||
|
keys.update({new_api_key.name: new_api_key})
|
||||||
|
save_api_keys(keys, key_path)
|
Loading…
Reference in a new issue