From ec2f24b257e801eda62d3b19b5ac2f643290af5f Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 12 Jul 2019 02:07:30 -0500 Subject: [PATCH] refactored api servers into module --- onionr/apiservers/__init__.py | 3 + .../private/__init__.py} | 80 ++++--------------- .../private/register_private_blueprints.py | 31 +++++++ onionr/apiservers/public/__init__.py | 56 +++++++++++++ onionr/onionr.py | 3 +- onionr/onionrcommands/daemonlaunch.py | 6 +- 6 files changed, 110 insertions(+), 69 deletions(-) create mode 100755 onionr/apiservers/__init__.py rename onionr/{api.py => apiservers/private/__init__.py} (50%) mode change 100755 => 100644 create mode 100644 onionr/apiservers/private/register_private_blueprints.py create mode 100644 onionr/apiservers/public/__init__.py diff --git a/onionr/apiservers/__init__.py b/onionr/apiservers/__init__.py new file mode 100755 index 00000000..c7c693ba --- /dev/null +++ b/onionr/apiservers/__init__.py @@ -0,0 +1,3 @@ +from . import public, private +PublicAPI = public.PublicAPI +ClientAPI = private.PrivateAPI \ No newline at end of file diff --git a/onionr/api.py b/onionr/apiservers/private/__init__.py old mode 100755 new mode 100644 similarity index 50% rename from onionr/api.py rename to onionr/apiservers/private/__init__.py index 51f103f3..9b9ca66e --- a/onionr/api.py +++ b/onionr/apiservers/private/__init__.py @@ -17,55 +17,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import threading, hmac, base64, time, os -from gevent.pywsgi import WSGIServer +import base64, os import flask -from flask import request, Response, abort, send_from_directory -import core -import onionrexceptions, onionrcrypto, logger, config +from gevent.pywsgi import WSGIServer +import logger +from onionrutils import epoch import httpapi -from httpapi import friendsapi, profilesapi, configapi, miscpublicapi, miscclientapi, insertblock, onionrsitesapi -from onionrservices import httpheaders -import onionr -from onionrutils import bytesconverter, stringvalidators, epoch, mnemonickeys -from httpapi import apiutils, security, fdsafehandler - -config.reload() - -class PublicAPI: - ''' - The new client api server, isolated from the public api - ''' - def __init__(self, clientAPI): - assert isinstance(clientAPI, API) - app = flask.Flask('PublicAPI') - app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024 - self.i2pEnabled = config.get('i2p.host', False) - self.hideBlocks = [] # Blocks to be denied sharing - self.host = apiutils.setbindip.set_bind_IP(clientAPI._core.publicApiHostFile, clientAPI._core) - self.torAdder = clientAPI._core.hsAddress - self.i2pAdder = clientAPI._core.i2pAddress - self.bindPort = config.get('client.public.port') - self.lastRequest = 0 - self.hitCount = 0 # total rec requests to public api since server started - self.config = config - self.clientAPI = clientAPI - self.API_VERSION = onionr.API_VERSION - logger.info('Running public api on %s:%s' % (self.host, self.bindPort)) - - # Set instances, then startup our public api server - clientAPI.setPublicAPIInstance(self) - while self.torAdder == '': - clientAPI._core.refreshFirstStartVars() - self.torAdder = clientAPI._core.hsAddress - time.sleep(0.1) - - app.register_blueprint(security.public.PublicAPISecurity(self).public_api_security_bp) - app.register_blueprint(miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp) - self.httpServer = WSGIServer((self.host, self.bindPort), app, log=None, handler_class=fdsafehandler.FDSafeHandler) - self.httpServer.serve_forever() - -class API: +from . import register_private_blueprints +class PrivateAPI: ''' Client HTTP api ''' @@ -79,11 +38,12 @@ class API: This initialization defines all of the API entry points and handlers for the endpoints and errors This also saves the used host (random localhost IP address) to the data folder in host.txt ''' - + config = onionrInst.config + self.config = config self.debug = debug self._core = onionrInst.onionrCore self.startTime = epoch.get_epoch() - self._crypto = onionrcrypto.OnionrCrypto(self._core) + self._crypto = self._core._crypto app = flask.Flask(__name__) bindPort = int(config.get('client.client.port', 59496)) self.bindPort = bindPort @@ -93,30 +53,20 @@ class API: self.publicAPI = None # gets set when the thread calls our setter... bad hack but kinda necessary with flask #threading.Thread(target=PublicAPI, args=(self,)).start() - self.host = apiutils.setbindip.set_bind_IP(self._core.privateApiHostFile, self._core) + self.host = httpapi.apiutils.setbindip.set_bind_IP(self._core.privateApiHostFile, self._core) logger.info('Running api on %s:%s' % (self.host, self.bindPort)) self.httpServer = '' self.queueResponse = {} onionrInst.setClientAPIInst(self) - app.register_blueprint(security.client.ClientAPISecurity(self).client_api_security_bp) - app.register_blueprint(friendsapi.friends) - app.register_blueprint(profilesapi.profile_BP) - app.register_blueprint(configapi.config_BP) - app.register_blueprint(insertblock.ib) - app.register_blueprint(miscclientapi.getblocks.client_get_blocks) - app.register_blueprint(miscclientapi.staticfiles.static_files_bp) - app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(self).private_endpoints_bp) - app.register_blueprint(onionrsitesapi.site_api) - app.register_blueprint(apiutils.shutdown.shutdown_bp) - httpapi.load_plugin_blueprints(app) - self.get_block_data = apiutils.GetBlockData(self) - self.httpServer = WSGIServer((self.host, bindPort), app, log=None, handler_class=fdsafehandler.FDSafeHandler) + httpapi.load_plugin_blueprints(self, app) + self.get_block_data = httpapi.apiutils.GetBlockData(self) + + self.httpServer = WSGIServer((self.host, bindPort), app, log=None, handler_class=httpapi.fdsafehandler.FDSafeHandler) self.httpServer.serve_forever() def setPublicAPIInstance(self, inst): - assert isinstance(inst, PublicAPI) self.publicAPI = inst def validateToken(self, token): @@ -143,4 +93,4 @@ class API: pass def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False): - return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly) + return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly) \ No newline at end of file diff --git a/onionr/apiservers/private/register_private_blueprints.py b/onionr/apiservers/private/register_private_blueprints.py new file mode 100644 index 00000000..b9fa3f3b --- /dev/null +++ b/onionr/apiservers/private/register_private_blueprints.py @@ -0,0 +1,31 @@ +''' + Onionr - Private P2P Communication + + This file registers blueprints for the private api server +''' +''' + 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 . +''' +from httpapi import security, friendsapi, profilesapi, configapi, insertblock, miscclientapi, onionrsitesapi, apiutils +def register_private_blueprints(private_api, app): + app.register_blueprint(security.client.ClientAPISecurity(self).client_api_security_bp) + app.register_blueprint(friendsapi.friends) + app.register_blueprint(profilesapi.profile_BP) + app.register_blueprint(configapi.config_BP) + app.register_blueprint(insertblock.ib) + app.register_blueprint(miscclientapi.getblocks.client_get_blocks) + app.register_blueprint(miscclientapi.staticfiles.static_files_bp) + app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(self).private_endpoints_bp) + app.register_blueprint(onionrsitesapi.site_api) + app.register_blueprint(apiutils.shutdown.shutdown_bp) \ No newline at end of file diff --git a/onionr/apiservers/public/__init__.py b/onionr/apiservers/public/__init__.py new file mode 100644 index 00000000..b5594e6d --- /dev/null +++ b/onionr/apiservers/public/__init__.py @@ -0,0 +1,56 @@ +''' + Onionr - Private P2P Communication + + This file handles all incoming http requests to the public api server, using Flask +''' +''' + 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 time +import flask +from gevent.pywsgi import WSGIServer +from httpapi import apiutils, security, fdsafehandler, miscpublicapi +import logger, onionr +class PublicAPI: + ''' + The new client api server, isolated from the public api + ''' + def __init__(self, clientAPI): + config = clientAPI.config + app = flask.Flask('PublicAPI') + app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024 + self.i2pEnabled = config.get('i2p.host', False) + self.hideBlocks = [] # Blocks to be denied sharing + self.host = apiutils.setbindip.set_bind_IP(clientAPI._core.publicApiHostFile, clientAPI._core) + self.torAdder = clientAPI._core.hsAddress + self.i2pAdder = clientAPI._core.i2pAddress + self.bindPort = config.get('client.public.port') + self.lastRequest = 0 + self.hitCount = 0 # total rec requests to public api since server started + self.config = config + self.clientAPI = clientAPI + self.API_VERSION = onionr.API_VERSION + logger.info('Running public api on %s:%s' % (self.host, self.bindPort)) + + # Set instances, then startup our public api server + clientAPI.setPublicAPIInstance(self) + while self.torAdder == '': + clientAPI._core.refreshFirstStartVars() + self.torAdder = clientAPI._core.hsAddress + time.sleep(0.1) + + app.register_blueprint(security.public.PublicAPISecurity(self).public_api_security_bp) + app.register_blueprint(miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp) + self.httpServer = WSGIServer((self.host, self.bindPort), app, log=None, handler_class=fdsafehandler.FDSafeHandler) + self.httpServer.serve_forever() \ No newline at end of file diff --git a/onionr/onionr.py b/onionr/onionr.py index 6ca5002e..ebb035bf 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -37,7 +37,7 @@ if detectoptimization.detect_optimization(): import os, base64, random, shutil, time, platform, signal from threading import Thread -import api, core, config, logger, onionrplugins as plugins, onionrevents as events +import core, config, logger, onionrplugins as plugins, onionrevents as events import netcontroller from netcontroller import NetController from onionrblockapi import Block @@ -58,6 +58,7 @@ class Onionr: self.API_VERSION = API_VERSION self.userRunDir = os.getcwd() # Directory user runs the program from self.killed = False + self.config = config if sys.argv[0] == os.path.basename(__file__): try: diff --git a/onionr/onionrcommands/daemonlaunch.py b/onionr/onionrcommands/daemonlaunch.py index c82d13de..d24b2dff 100755 --- a/onionr/onionrcommands/daemonlaunch.py +++ b/onionr/onionrcommands/daemonlaunch.py @@ -20,7 +20,7 @@ import os, time, sys, platform, sqlite3, signal from threading import Thread -import onionr, api, logger, communicator +import onionr, apiservers, logger, communicator import onionrevents as events from netcontroller import NetController from onionrutils import localcommand @@ -39,8 +39,8 @@ def daemon(o_inst): logger.debug('Runcheck file found on daemon start, deleting in advance.') os.remove('%s/.runcheck' % (o_inst.onionrCore.dataDir,)) - Thread(target=api.API, args=(o_inst, o_inst.debug, onionr.API_VERSION), daemon=True).start() - Thread(target=api.PublicAPI, args=[o_inst.getClientApi()], daemon=True).start() + Thread(target=apiservers.ClientAPI, args=(o_inst, o_inst.debug, onionr.API_VERSION), daemon=True).start() + Thread(target=apiservers.PublicAPI, args=[o_inst.getClientApi()], daemon=True).start() apiHost = '' while apiHost == '':