Various bug fixes
parent
34b919d324
commit
ddb3ce1e35
|
@ -24,7 +24,7 @@ from gevent.wsgi import WSGIServer
|
|||
import sys, random, threading, hmac, hashlib, base64, time, math, os, logger, config
|
||||
from core import Core
|
||||
from onionrblockapi import Block
|
||||
import onionrutils, onionrcrypto, blockimporter
|
||||
import onionrutils, onionrcrypto, blockimporter, onionrevents as events
|
||||
|
||||
class API:
|
||||
'''
|
||||
|
@ -94,6 +94,7 @@ class API:
|
|||
'''
|
||||
Simply define the request as not having yet failed, before every request.
|
||||
'''
|
||||
|
||||
self.requestFailed = False
|
||||
|
||||
return
|
||||
|
@ -119,16 +120,24 @@ class API:
|
|||
@app.route('/client/ui/<path:path>')
|
||||
def webUI(path):
|
||||
startTime = math.floor(time.time())
|
||||
|
||||
if request.args.get('timingToken') is None:
|
||||
timingToken = ''
|
||||
else:
|
||||
timingToken = request.args.get('timingToken')
|
||||
self.validateHost('private')
|
||||
|
||||
if not config.get("onionr_ui.run", True):
|
||||
abort(403)
|
||||
if config.get("onionr_ui.private_only", True):
|
||||
self.validateHost('private')
|
||||
|
||||
endTime = math.floor(time.time())
|
||||
elapsed = endTime - startTime
|
||||
|
||||
if not hmac.compare_digest(timingToken, self.timeBypassToken):
|
||||
if elapsed < self._privateDelayTime:
|
||||
time.sleep(self._privateDelayTime - elapsed)
|
||||
|
||||
return send_from_directory('static-data/ui/dist/', path)
|
||||
|
||||
@app.route('/client/')
|
||||
|
@ -150,6 +159,9 @@ class API:
|
|||
|
||||
if not self.validateToken(token):
|
||||
abort(403)
|
||||
|
||||
events.event('webapi_private', onionr = None, data = {'action' : action, 'data' : data, 'timingToken' : timingToken, 'token' : token})
|
||||
|
||||
self.validateHost('private')
|
||||
if action == 'hello':
|
||||
resp = Response('Hello, World! ' + request.host)
|
||||
|
@ -198,12 +210,12 @@ class API:
|
|||
response['hash'] = hash
|
||||
response['reason'] = 'Successfully wrote block to file'
|
||||
else:
|
||||
response['reason'] = 'Faield to save the block'
|
||||
response['reason'] = 'Failed to save the block'
|
||||
except Exception as e:
|
||||
logger.debug('insertBlock api request failed', error = e)
|
||||
|
||||
resp = Response(json.dumps(response))
|
||||
elif action in callbacks['private']:
|
||||
elif action in API.callbacks['private']:
|
||||
resp = Response(str(getCallback(action, scope = 'private')(request)))
|
||||
else:
|
||||
resp = Response('(O_o) Dude what? (invalid command)')
|
||||
|
@ -257,6 +269,10 @@ class API:
|
|||
data = data
|
||||
except:
|
||||
data = ''
|
||||
|
||||
|
||||
events.event('webapi_public', onionr = None, data = {'action' : action, 'data' : data, 'requestingPeer' : requestingPeer, 'request' : request})
|
||||
|
||||
if action == 'firstConnect':
|
||||
pass
|
||||
elif action == 'ping':
|
||||
|
@ -299,7 +315,7 @@ class API:
|
|||
peers = self._core.listPeers(getPow=True)
|
||||
response = ','.join(peers)
|
||||
resp = Response(response)
|
||||
elif action in callbacks['public']:
|
||||
elif action in API.callbacks['public']:
|
||||
resp = Response(str(getCallback(action, scope = 'public')(request)))
|
||||
else:
|
||||
resp = Response("")
|
||||
|
@ -373,29 +389,29 @@ class API:
|
|||
sys.exit(1)
|
||||
|
||||
def setCallback(action, callback, scope = 'public'):
|
||||
if not scope in callbacks:
|
||||
if not scope in API.callbacks:
|
||||
return False
|
||||
|
||||
callbacks[scope][action] = callback
|
||||
API.callbacks[scope][action] = callback
|
||||
|
||||
return True
|
||||
|
||||
def removeCallback(action, scope = 'public'):
|
||||
if (not scope in callbacks) or (not action in callbacks[scope]):
|
||||
if (not scope in API.callbacks) or (not action in API.callbacks[scope]):
|
||||
return False
|
||||
|
||||
del callbacks[scope][action]
|
||||
del API.callbacks[scope][action]
|
||||
|
||||
return True
|
||||
|
||||
def getCallback(action, scope = 'public'):
|
||||
if (not scope in callbacks) or (not action in callbacks[scope]):
|
||||
if (not scope in API.callbacks) or (not action in API.callbacks[scope]):
|
||||
return None
|
||||
|
||||
return callbacks[scope][action]
|
||||
return API.callbacks[scope][action]
|
||||
|
||||
def getCallbacks(scope = None):
|
||||
if (not scope is None) and (scope in callbacks):
|
||||
return callbacks[scope]
|
||||
if (not scope is None) and (scope in API.callbacks):
|
||||
return API.callbacks[scope]
|
||||
|
||||
return callbacks
|
||||
return API.callbacks
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
import sys, os, core, config, json, onionrblockapi as block, requests, time, logger, threading, onionrplugins as plugins, base64, onionr
|
||||
import onionrexceptions, onionrpeers
|
||||
import sys, os, core, config, json, requests, time, logger, threading, base64, onionr
|
||||
import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as plugins, onionrblockapi as block
|
||||
from defusedxml import minidom
|
||||
|
||||
class OnionrCommunicatorDaemon:
|
||||
|
@ -337,6 +337,8 @@ class OnionrCommunicatorDaemon:
|
|||
cmd = self._core.daemonQueue()
|
||||
|
||||
if cmd is not False:
|
||||
events.event('daemon_command', onionr = None, data = {'cmd' : cmd})
|
||||
|
||||
if cmd[0] == 'shutdown':
|
||||
self.shutdown = True
|
||||
elif cmd[0] == 'announceNode':
|
||||
|
@ -355,6 +357,7 @@ class OnionrCommunicatorDaemon:
|
|||
threading.Thread(target=self.uploadBlock).start()
|
||||
else:
|
||||
logger.info('Recieved daemonQueue command:' + cmd[0])
|
||||
|
||||
self.decrementThreadCount('daemonCommands')
|
||||
|
||||
def uploadBlock(self):
|
||||
|
@ -401,6 +404,7 @@ class OnionrCommunicatorDaemon:
|
|||
time.sleep(1)
|
||||
else:
|
||||
# This executes if the api is NOT detected to be running
|
||||
events.event('daemon_crash', onionr = None, data = {})
|
||||
logger.error('Daemon detected API crash (or otherwise unable to reach API after long time), stopping...')
|
||||
self.shutdown = True
|
||||
self.decrementThreadCount('detectAPICrash')
|
||||
|
|
|
@ -100,7 +100,7 @@ DataDirectory data/tordata/
|
|||
logger.fatal('Failed to start Tor. Try killing any other Tor processes owned by this user.')
|
||||
return False
|
||||
except KeyboardInterrupt:
|
||||
logger.fatal("Got keyboard interrupt")
|
||||
logger.fatal("Got keyboard interrupt.")
|
||||
return False
|
||||
|
||||
logger.debug('Finished starting Tor.', timestamp=True)
|
||||
|
|
|
@ -40,9 +40,9 @@ except ImportError:
|
|||
raise Exception("You need the PySocks module (for use with socks5 proxy to use Tor)")
|
||||
|
||||
ONIONR_TAGLINE = 'Anonymous P2P Platform - GPLv3 - https://Onionr.VoidNet.Tech'
|
||||
ONIONR_VERSION = '0.1.0' # for debugging and stuff
|
||||
ONIONR_VERSION = '0.1.1' # for debugging and stuff
|
||||
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
|
||||
API_VERSION = '4' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes knows how to communicate without learning too much information about you.
|
||||
API_VERSION = '4' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
|
||||
|
||||
class Onionr:
|
||||
def __init__(self):
|
||||
|
|
|
@ -33,10 +33,10 @@ def __event_caller(event_name, data = {}, onionr = None):
|
|||
try:
|
||||
call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(onionr, data))
|
||||
except ModuleNotFoundError as e:
|
||||
logger.warn('Disabling nonexistant plugin \"' + plugin + '\"...')
|
||||
logger.warn('Disabling nonexistant plugin "%s"...' % plugin)
|
||||
plugins.disable(plugin, onionr, stop_event = False)
|
||||
except Exception as e:
|
||||
logger.warn('Event \"' + event_name + '\" failed for plugin \"' + plugin + '\".')
|
||||
logger.warn('Event "%s" failed for plugin "%s".' % (event_name, plugin))
|
||||
logger.debug(str(e))
|
||||
|
||||
|
||||
|
|
|
@ -49,5 +49,6 @@ class InvalidProof(Exception):
|
|||
# network level exceptions
|
||||
class MissingPort(Exception):
|
||||
pass
|
||||
|
||||
class InvalidAddress(Exception):
|
||||
pass
|
||||
|
|
|
@ -199,7 +199,7 @@ class OnionrUtils:
|
|||
def getBlockMetadataFromData(self, blockData):
|
||||
'''
|
||||
accepts block contents as string, returns a tuple of metadata, meta (meta being internal metadata, which will be returned as an encrypted base64 string if it is encrypted, dict if not).
|
||||
|
||||
|
||||
'''
|
||||
meta = {}
|
||||
metadata = {}
|
||||
|
@ -208,7 +208,7 @@ class OnionrUtils:
|
|||
blockData = blockData.encode()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
metadata = json.loads(blockData[:blockData.find(b'\n')].decode())
|
||||
except json.decoder.JSONDecodeError:
|
||||
|
@ -221,7 +221,7 @@ class OnionrUtils:
|
|||
meta = json.loads(metadata['meta'])
|
||||
except KeyError:
|
||||
pass
|
||||
meta = metadata['meta']
|
||||
meta = metadata['meta']
|
||||
return (metadata, meta, data)
|
||||
|
||||
def checkPort(self, port, host=''):
|
||||
|
@ -251,7 +251,7 @@ class OnionrUtils:
|
|||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def processBlockMetadata(self, blockHash):
|
||||
'''
|
||||
Read metadata from a block and cache it to the block database
|
||||
|
@ -269,7 +269,7 @@ class OnionrUtils:
|
|||
def escapeAnsi(self, line):
|
||||
'''
|
||||
Remove ANSI escape codes from a string with regex
|
||||
|
||||
|
||||
taken or adapted from: https://stackoverflow.com/a/38662876
|
||||
'''
|
||||
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
|
||||
|
@ -331,12 +331,12 @@ class OnionrUtils:
|
|||
retVal = False
|
||||
|
||||
return retVal
|
||||
|
||||
|
||||
def validateMetadata(self, metadata):
|
||||
'''Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string'''
|
||||
# TODO, make this check sane sizes
|
||||
retData = False
|
||||
|
||||
|
||||
# convert to dict if it is json string
|
||||
if type(metadata) is str:
|
||||
try:
|
||||
|
@ -382,7 +382,7 @@ class OnionrUtils:
|
|||
else:
|
||||
retVal = True
|
||||
return retVal
|
||||
|
||||
|
||||
def isIntegerString(self, data):
|
||||
'''Check if a string is a valid base10 integer'''
|
||||
try:
|
||||
|
|
|
@ -2,8 +2,16 @@
|
|||
"general" : {
|
||||
"dev_mode": true,
|
||||
"display_header" : true,
|
||||
"dc_response": true,
|
||||
"dc_execcallbacks" : true
|
||||
|
||||
"direct_connect" : {
|
||||
"respond" : true,
|
||||
"execute_callbacks" : true
|
||||
}
|
||||
},
|
||||
|
||||
"onionr_ui" : {
|
||||
"run" : true,
|
||||
"private_only" : true
|
||||
},
|
||||
|
||||
"client" : {
|
||||
|
|
Loading…
Reference in New Issue