diff --git a/Makefile b/Makefile index f4e4a81a..78ff7939 100644 --- a/Makefile +++ b/Makefile @@ -23,11 +23,11 @@ test: @mv onionr/data-backup onionr/data | true > /dev/null 2>&1 soft-reset: - rm -f onionr/data/blocks/*.dat | true > /dev/null 2>&1 - rm -f onionr/data/*.db | true > /dev/null 2>&1 + @echo "Soft-resetting Onionr..." + rm -f onionr/data/blocks/*.dat onionr/data/*.db | true > /dev/null 2>&1 + @./RUN-LINUX.sh version | grep -v "Failed" --color=always reset: @echo "Hard-resetting Onionr..." rm -rf onionr/data/ | true > /dev/null 2>&1 @./RUN-LINUX.sh version | grep -v "Failed" --color=always - diff --git a/onionr/onionr.py b/onionr/onionr.py index 416735c6..d862a402 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -41,9 +41,6 @@ ONIONR_VERSION = '0.0.0' # for debugging and stuff API_VERSION = '1' # 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. class Onionr: - cmds = {} - cmdhelp = {} - def __init__(self): ''' Main Onionr class. This is for the CLI program, and does not handle much of the logic. @@ -210,10 +207,16 @@ class Onionr: return self.cmdhelp def addCommand(self, command, function): - cmds[str(command).lower()] = function + self.cmds[str(command).lower()] = function def addHelp(self, command, description): - cmdhelp[str(command).lower()] = str(description) + self.cmdhelp[str(command).lower()] = str(description) + + def delCommand(self, command): + return self.cmds.pop(str(command).lower(), None) + + def delHelp(self, command): + return self.cmdhelp.pop(str(command).lower(), None) def configure(self): ''' @@ -243,6 +246,8 @@ class Onionr: command = commands.get(argument, self.notFound) command() + + return ''' THIS SECTION DEFINES THE COMMANDS @@ -257,6 +262,8 @@ class Onionr: logger.info(ONIONR_TAGLINE) if verbosity >= 2: logger.info('Running on ' + platform.platform() + ' ' + platform.release()) + + return def sendEncrypt(self): ''' @@ -362,7 +369,7 @@ class Onionr: if len(sys.argv) >= 3: plugin_name = sys.argv[2] logger.info('Enabling plugin \"' + plugin_name + '\"...') - plugins.enable(plugin_name) + plugins.enable(plugin_name, self) else: logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' ') @@ -376,7 +383,7 @@ class Onionr: if len(sys.argv) >= 3: plugin_name = sys.argv[2] logger.info('Disabling plugin \"' + plugin_name + '\"...') - plugins.disable(plugin_name) + plugins.disable(plugin_name, self) else: logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' ') @@ -390,11 +397,11 @@ class Onionr: if len(sys.argv) >= 3: plugin_name = sys.argv[2] logger.info('Reloading plugin \"' + plugin_name + '\"...') - plugins.stop(plugin_name) - plugins.start(plugin_name) + plugins.stop(plugin_name, self) + plugins.start(plugin_name, self) else: logger.info('Reloading all plugins...') - plugins.reload() + plugins.reload(self) return diff --git a/onionr/onionrevents.py b/onionr/onionrevents.py index 2c148d8f..9b386a31 100644 --- a/onionr/onionrevents.py +++ b/onionr/onionrevents.py @@ -18,7 +18,10 @@ along with this program. If not, see . ''' -import config, logger, onionrplugins as plugins +import config, logger, onionrplugins as plugins, onionrpluginapi as pluginapi + +def get_pluginapi(onionr): + return pluginapi.PluginAPI(onionr) def event(event_name, data = None, onionr = None): ''' @@ -27,11 +30,11 @@ def event(event_name, data = None, onionr = None): for plugin in plugins.get_enabled_plugins(): try: - call(plugins.get_plugin(plugin), event_name, data, onionr) + call(plugins.get_plugin(plugin), event_name, data, self.get_pluginapi(onionr)) except: logger.warn('Event \"' + event_name + '\" failed for plugin \"' + plugin + '\".') -def call(plugin, event_name, data = None, onionr = None): +def call(plugin, event_name, data = None, pluginapi = None): ''' Calls an event on a plugin if one is defined ''' @@ -43,7 +46,7 @@ def call(plugin, event_name, data = None, onionr = None): # TODO: Use multithreading perhaps? if hasattr(plugin, attribute): logger.debug('Calling event ' + str(event_name)) - getattr(plugin, attribute)(onionr, data) + getattr(plugin, attribute)(pluginapi, data) return True except: diff --git a/onionr/onionrpluginapi.py b/onionr/onionrpluginapi.py new file mode 100644 index 00000000..67d37694 --- /dev/null +++ b/onionr/onionrpluginapi.py @@ -0,0 +1,150 @@ +''' + Onionr - P2P Microblogging Platform & Social network + + This file deals with the object that is passed with each event +''' +''' + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +''' + +import onionrplugins as plugins, logger + +class PluginAPI: + def __init__(self, onionr): + self.onionr = onionr + + self.daemon = DaemonAPI(self) + self.plugin = PluginAPI(self) + self.command = CommandAPI(self) + + def get_onionr(self): + return self.onionr + + def get_core(self): + return self.get_onionr().onionrCore + + def get_utils(self): + return self.get_onionr().onionrUtils + + def get_daemonapi(self): + return self.daemon + + def get_pluginapi(self): + return self.plugin + + def get_commandapi(self): + return self.command + + def is_development_mode(self): + return self.get_onionr()._developmentMode + + class DaemonAPI: + def __init__(self, pluginapi): + self.pluginapi = pluginapi + + def start(self): + self.pluginapi.get_onionr().daemon() + + return + + def stop(self): + self.pluginapi.get_onionr().killDaemon() + + return + + def queue(self, command, data = ''): + self.pluginapi.get_core().daemonQueueAdd(command, data) + + return + + def local_command(self, command): + self.pluginapi.get_utils().localCommand(self, command) + + return + + def queue_pop(self): + return self.get_core().daemonQueue() + + class PluginAPI: + def __init__(self, pluginapi): + self.pluginapi = pluginapi + + def start(self, name): + plugins.start(name) + + def stop(self, name): + plugins.stop(name) + + def reload(self, name): + plugins.reload(name) + + def enable(self, name): + plugins.enable(name) + + def disable(self, name): + plugins.disable(name) + + def is_enabled(self, name): + return plugins.is_enabled(name) + + def get_enabled_plugins(self): + return plugins.get_enabled_plugins() + + class CommandAPI: + def __init__(self, pluginapi): + self.pluginapi = pluginapi + + def register(self, names, call = None): + if isinstance(names, str): + names = [names] + + for name in names: + self.pluginapi.get_onionr().addCommand(name, call) + + return + + def unregister(self, names): + if isinstance(names, str): + names = [names] + + for name in names: + self.pluginapi.get_onionr().delCommand(name) + + return + + def register_help(self, names, description): + if isinstance(names, str): + names = [names] + + for name in names: + self.pluginapi.get_onionr().addHelp(name, description) + + return + + def unregister_help(self, names): + if isinstance(names, str): + names = [names] + + for name in names: + self.pluginapi.get_onionr().delHelp(name) + + return + + def call(self, name): + self.pluginapi.get_onionr().execute(name) + + return + + def get_commands(self): + return self.pluginapi.get_onionr().getCommands() diff --git a/onionr/onionrplugins.py b/onionr/onionrplugins.py index 8ae098bb..f75836cd 100644 --- a/onionr/onionrplugins.py +++ b/onionr/onionrplugins.py @@ -24,7 +24,7 @@ import onionrevents as events _pluginsfolder = 'data/plugins/' _instances = dict() -def reload(stop_event = True): +def reload(onionr = None, stop_event = True): ''' Reloads all the plugins ''' @@ -41,10 +41,10 @@ def reload(stop_event = True): if stop_event is True: for plugin in enabled_plugins: - stop(plugin) + stop(plugin, onionr) for plugin in enabled_plugins: - start(plugin) + start(plugin, onionr) return True except: @@ -53,7 +53,7 @@ def reload(stop_event = True): return False -def enable(name, start_event = True): +def enable(name, onionr = None, start_event = True): ''' Enables a plugin ''' @@ -67,7 +67,7 @@ def enable(name, start_event = True): config_plugins['enabled'] = enabled_plugins config.set('plugins', config_plugins, True) - events.call(get_plugin(name), 'enable') + events.call(get_plugin(name), 'enable', onionr) if start_event is True: start(name) @@ -80,7 +80,7 @@ def enable(name, start_event = True): return False -def disable(name, stop_event = True): +def disable(name, onionr = None, stop_event = True): ''' Disables a plugin ''' @@ -95,12 +95,12 @@ def disable(name, stop_event = True): config.set('plugins', config_plugins, True) if exists(name): - events.call(get_plugin(name), 'disable') + events.call(get_plugin(name), 'disable', onionr) if stop_event is True: stop(name) -def start(name): +def start(name, onionr = None): ''' Starts the plugin ''' @@ -114,7 +114,7 @@ def start(name): if plugin is None: raise Exception('Failed to import module.') else: - events.call(plugin, 'start') + events.call(plugin, 'start', onionr) return plugin except: @@ -124,7 +124,7 @@ def start(name): return None -def stop(name): +def stop(name, onionr = None): ''' Stops the plugin ''' @@ -138,7 +138,7 @@ def stop(name): if plugin is None: raise Exception('Failed to import module.') else: - events.call(plugin, 'stop') + events.call(plugin, 'stop', onionr) return plugin except: @@ -225,10 +225,5 @@ def check(): if not os.path.exists(os.path.dirname(get_plugins_folder())): logger.debug('Generating plugin data folder...') os.makedirs(os.path.dirname(get_plugins_folder())) - - #if not exists('test'): - #os.makedirs(get_plugins_folder('test')) - #with open(get_plugins_folder('test') + '/main.py', 'a') as main: - #main.write("print('Running')\n\ndef on_test(onionr = None, data = None):\n print('received test event!')\n return True\n\ndef on_start(onionr = None, data = None):\n print('start event called')\n\ndef on_stop(onionr = None, data = None):\n print('stop event called')\n\ndef on_enable(onionr = None, data = None):\n print('enable event called')\n\ndef on_disable(onionr = None, data = None):\n print('disable event called')\n") - #enable('test') + return diff --git a/onionr/timedHmac.py b/onionr/timedhmac.py similarity index 93% rename from onionr/timedHmac.py rename to onionr/timedhmac.py index 2f23317f..a6163ead 100644 --- a/onionr/timedHmac.py +++ b/onionr/timedhmac.py @@ -12,7 +12,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' + import hmac, base64, time, math + class TimedHMAC: def __init__(self, base64Key, data, hashAlgo): ''' @@ -23,6 +25,7 @@ class TimedHMAC: Maximum of 10 seconds grace period ''' + self.data = data self.expire = math.floor(time.time()) self.hashAlgo = hashAlgo @@ -34,11 +37,14 @@ class TimedHMAC: return def check(self, data): - # Check a hash (and verify time is sane) + ''' + Check a hash (and verify time is sane) + ''' + testHash = hmac.HMAC(base64.b64decode(base64Key).decode(), digestmod=self.hashAlgo) testHash.update(data + math.floor(time.time())) testHash = testHash.hexdigest() if hmac.compare_digest(testHash, self.HMACResult): return true - else: - return false + + return false