Add web api callbacks

This commit is contained in:
Arinerron 2018-07-29 17:37:12 -07:00
parent 695cd7503b
commit 215fbcba68
6 changed files with 107 additions and 13 deletions

View File

@ -30,6 +30,9 @@ class API:
'''
Main HTTP API (Flask)
'''
callbacks = {'public' : {}, 'private' : {}, 'ui' : {}}
def validateToken(self, token):
'''
Validate that the client token matches the given token
@ -164,6 +167,44 @@ class API:
self.mimeType = 'text/html'
response = siteData.split(b'-', 2)[-1]
resp = Response(response)
elif action == "insertBlock":
response = {'success' : False, 'reason' : 'An unknown error occurred'}
try:
decoded = json.loads(data)
block = Block()
sign = False
for key in decoded:
val = decoded[key]
key = key.lower()
if key == 'type':
block.setType(val)
elif key in ['body', 'content']:
block.setContent(val)
elif key == 'parent':
block.setParent(val)
elif key == 'sign':
sign = (str(val).lower() == 'true')
hash = block.save(sign = sign)
if not hash is False:
response['success'] = true
response['hash'] = hash
response['reason'] = 'Successfully wrote block to file'
else:
response['reason'] = 'Faield 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']:
resp = Response(str(getCallback(action, scope = 'private')(request)))
else:
resp = Response('(O_o) Dude what? (invalid command)')
endTime = math.floor(time.time())
@ -258,6 +299,8 @@ class API:
peers = self._core.listPeers(getPow=True)
response = ','.join(peers)
resp = Response(response)
elif action in callbacks['public']:
resp = Response(str(getCallback(action, scope = 'public')(request)))
else:
resp = Response("")
@ -328,3 +371,31 @@ class API:
# we exit rather than abort to avoid fingerprinting
logger.debug('Avoiding fingerprinting, exiting...')
sys.exit(1)
def setCallback(action, callback, scope = 'public'):
if not scope in callbacks:
return False
callbacks[scope][action] = callback
return True
def removeCallback(action, scope = 'public'):
if (not scope in callbacks) or (not action in callbacks[scope]):
return False
del callbacks[scope][action]
return True
def getCallback(action, scope = 'public'):
if (not scope in callbacks) or (not action in callbacks[scope]):
return None
return callbacks[scope][action]
def getCallbacks(scope = None):
if (not scope is None) and (scope in callbacks):
return callbacks[scope]
return callbacks

View File

@ -36,7 +36,7 @@ class OnionrCommunicatorDaemon:
# intalize NIST beacon salt and time
self.nistSaltTimestamp = 0
self.powSalt = 0
self.blockToUpload = ''
# loop time.sleep delay in seconds
@ -309,7 +309,7 @@ class OnionrCommunicatorDaemon:
logger.info(i)
def peerAction(self, peer, action, data=''):
'''Perform a get request to a peer'''
'''Perform a get request to a peer'''
if len(peer) == 0:
return False
logger.info('Performing ' + action + ' with ' + peer + ' on port ' + str(self.proxyPort))

View File

@ -91,8 +91,6 @@ class Onionr:
self.onionrCore = core.Core()
self.onionrUtils = OnionrUtils(self.onionrCore)
self.userOS = platform.system()
# Handle commands
self.debug = False # Whole application debugging
@ -258,7 +256,7 @@ class Onionr:
def getWebPassword(self):
return config.get('client.hmac')
def printWebPassword(self):
print(self.getWebPassword())
@ -542,7 +540,7 @@ class Onionr:
subprocess.Popen([communicatorDaemon, "run", str(net.socksPort)])
logger.debug('Started communicator')
events.event('daemon_start', onionr = self)
api.API(self.debug)
self.api = api.API(self.debug)
return

View File

@ -38,7 +38,6 @@ class Block:
self.btype = type
self.bcontent = content
# initialize variables
self.valid = True
self.raw = None
@ -71,8 +70,10 @@ class Block:
# logic
def decrypt(self, anonymous=True, encodedData=True):
'''Decrypt a block, loading decrypted data into their vars'''
def decrypt(self, anonymous = True, encodedData = True):
'''
Decrypt a block, loading decrypted data into their vars
'''
if self.decrypted:
return True
retData = False
@ -100,9 +101,11 @@ class Block:
else:
logger.warn('symmetric decryption is not yet supported by this API')
return retData
def verifySig(self):
'''Verify if a block's signature is signed by its claimed signer'''
'''
Verify if a block's signature is signed by its claimed signer
'''
core = self.getCore()
if core._crypto.edVerify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
@ -227,12 +230,14 @@ class Block:
else:
self.hash = self.getCore().insertBlock(self.getContent(), header = self.getType(), sign = sign)
self.update()
return self.getHash()
else:
logger.warn('Not writing block; it is invalid.')
except Exception as e:
logger.error('Failed to save block.', error = e, timestamp = False)
return False
return False
# getters
@ -533,7 +538,7 @@ class Block:
if relevant:
relevant_blocks.append(block)
if bool(reverse):
relevant_blocks.reverse()

View File

@ -130,6 +130,22 @@ class CommandAPI:
def get_commands(self):
return self.pluginapi.get_onionr().getCommands()
class WebAPI:
def __init__(self, pluginapi):
self.pluginapi = pluginapi
def register_callback(self, action, callback, scope = 'public'):
return self.pluginapi.get_onionr().api.setCallback(action, callback, scope = scope)
def unregister_callback(self, action, scope = 'public'):
return self.pluginapi.get_onionr().api.removeCallback(action, scope = scope)
def get_callback(self, action, scope = 'public'):
return self.pluginapi.get_onionr().api.getCallback(action, scope= scope)
def get_callbacks(self, scope = None):
return self.pluginapi.get_onionr().api.getCallbacks(scope = scope)
class pluginapi:
def __init__(self, onionr, data):
self.onionr = onionr
@ -142,6 +158,7 @@ class pluginapi:
self.daemon = DaemonAPI(self)
self.plugins = PluginAPI(self)
self.commands = CommandAPI(self)
self.web = WebAPI(self)
def get_onionr(self):
return self.onionr
@ -167,5 +184,8 @@ class pluginapi:
def get_commandapi(self):
return self.commands
def get_webapi(self):
return self.web
def is_development_mode(self):
return self.get_onionr()._developmentMode