* made api servers lint compliant

* made bigbrother lint compliant
master
Kevin Froman 2019-12-20 02:34:52 -06:00
parent 9571ea519d
commit 1019ff0773
7 changed files with 106 additions and 78 deletions

View File

@ -1,4 +1,4 @@
"""Flask WSGI apps for the public and private API servers """Flask WSGI apps for the public and private API servers.
Public is net-facing server meant for other nodes Public is net-facing server meant for other nodes
Private is meant for controlling and accessing this node Private is meant for controlling and accessing this node

View File

@ -1,10 +1,9 @@
''' """Onionr - Private P2P Communication.
Onionr - Private P2P Communication
This file handles all incoming http requests to the client, using Flask This file handles all incoming http requests to the client, using Flask
''' """
import base64 from typing import Dict
import os import hmac
import flask import flask
from gevent.pywsgi import WSGIServer from gevent.pywsgi import WSGIServer
@ -18,7 +17,7 @@ from etc import waitforsetvar
from . import register_private_blueprints from . import register_private_blueprints
import config import config
from .. import public from .. import public
''' """
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -31,24 +30,22 @@ from .. import public
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' """
class PrivateAPI: class PrivateAPI:
''' """Client HTTP api for controlling onionr and using UI."""
Client HTTP api
'''
callbacks = {'public': {}, 'private': {}} callbacks: Dict[str, Dict] = {'public': {}, 'private': {}}
def __init__(self): def __init__(self):
''' """Initialize the api server, preping variables for later use.
Initialize the api server, preping variables for later use
This initialization defines all of the API entry points This initialization defines all of the API entry points
and handlers for the endpoints and errors and handlers for the endpoints and errors
This also saves the used host (random localhost IP address) to the data folder in host.txt This also saves the used host (random localhost IP address)
''' to the data folder in host.txt
"""
self.config = config self.config = config
self.startTime = epoch.get_epoch() self.startTime = epoch.get_epoch()
@ -58,7 +55,8 @@ class PrivateAPI:
self.clientToken = config.get('client.webpassword') self.clientToken = config.get('client.webpassword')
self.host = httpapi.apiutils.setbindip.set_bind_IP(private_API_host_file) self.host = httpapi.apiutils.setbindip.set_bind_IP(
private_API_host_file)
logger.info('Running api on %s:%s' % (self.host, self.bindPort)) logger.info('Running api on %s:%s' % (self.host, self.bindPort))
self.httpServer = '' self.httpServer = ''
@ -69,18 +67,25 @@ class PrivateAPI:
self.app = app self.app = app
def start(self): def start(self):
"""Start client gevent API web server with flask client app."""
waitforsetvar.wait_for_set_var(self, "_too_many") waitforsetvar.wait_for_set_var(self, "_too_many")
self.publicAPI = self._too_many.get(public.PublicAPI) fd_handler = httpapi.fdsafehandler.FDSafeHandler
self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=httpapi.fdsafehandler.FDSafeHandler) self.publicAPI = self._too_many.get( # pylint: disable=E1101
public.PublicAPI)
self.httpServer = WSGIServer((self.host, self.bindPort),
self.app, log=None,
handler_class=fd_handler)
self.httpServer.serve_forever() self.httpServer.serve_forever()
def setPublicAPIInstance(self, inst): def setPublicAPIInstance(self, inst):
"""Dynamically set public API instance."""
self.publicAPI = inst self.publicAPI = inst
def validateToken(self, token): def validateToken(self, token):
''' """Validate that the client token matches the given token.
Validate that the client token matches the given token. Used to prevent CSRF and data exfiltration
''' Used to prevent CSRF and other attacks.
"""
if not self.clientToken: if not self.clientToken:
logger.error("client password needs to be set") logger.error("client password needs to be set")
return False return False
@ -89,7 +94,8 @@ class PrivateAPI:
except TypeError: except TypeError:
return False return False
def getUptime(self)->int: def getUptime(self) -> int:
"""Safely wait for uptime to be set and return it."""
while True: while True:
try: try:
return epoch.get_epoch() - self.startTime return epoch.get_epoch() - self.startTime
@ -97,5 +103,10 @@ class PrivateAPI:
# Don't error on race condition with startup # Don't error on race condition with startup
pass pass
def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False): def getBlockData(self, bHash, decrypt=False, raw=False,
return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly) headerOnly=False) -> bytes:
"""Returns block data bytes."""
return self.get_block_data.get_block_data(bHash,
decrypt=decrypt,
raw=raw,
headerOnly=headerOnly)

View File

@ -1,9 +1,12 @@
''' """Onionr - Private P2P Communication.
Onionr - Private P2P Communication
This file registers blueprints for the private api server This file registers blueprints for the private api server
''' """
''' from httpapi import security, friendsapi, profilesapi, configapi, insertblock
from httpapi import miscclientapi, onionrsitesapi, apiutils
from httpapi import directconnections
from httpapi import themeapi
"""
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -16,24 +19,25 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' """
import os
from httpapi import security, friendsapi, profilesapi, configapi, insertblock, miscclientapi, onionrsitesapi, apiutils
from httpapi import directconnections
from httpapi import themeapi
def register_private_blueprints(private_api, app): def register_private_blueprints(private_api, app):
app.register_blueprint(security.client.ClientAPISecurity(private_api).client_api_security_bp) """Register private API plask blueprints."""
app.register_blueprint(security.client.ClientAPISecurity(
private_api).client_api_security_bp)
app.register_blueprint(friendsapi.friends) app.register_blueprint(friendsapi.friends)
app.register_blueprint(profilesapi.profile_BP) app.register_blueprint(profilesapi.profile_BP)
app.register_blueprint(configapi.config_BP) app.register_blueprint(configapi.config_BP)
app.register_blueprint(insertblock.ib) app.register_blueprint(insertblock.ib)
app.register_blueprint(miscclientapi.getblocks.client_get_blocks) app.register_blueprint(miscclientapi.getblocks.client_get_blocks)
app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(private_api).private_endpoints_bp) app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(
private_api).private_endpoints_bp)
app.register_blueprint(miscclientapi.motd.bp) app.register_blueprint(miscclientapi.motd.bp)
app.register_blueprint(onionrsitesapi.site_api) app.register_blueprint(onionrsitesapi.site_api)
app.register_blueprint(apiutils.shutdown.shutdown_bp) app.register_blueprint(apiutils.shutdown.shutdown_bp)
app.register_blueprint(miscclientapi.staticfiles.static_files_bp) app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
app.register_blueprint(directconnections.DirectConnectionManagement(private_api).direct_conn_management_bp) app.register_blueprint(directconnections.DirectConnectionManagement(
private_api).direct_conn_management_bp)
app.register_blueprint(themeapi.theme_blueprint) app.register_blueprint(themeapi.theme_blueprint)
return app return app

View File

@ -1,9 +1,19 @@
''' """Onionr - Private P2P Communication.
Onionr - Private P2P Communication
This file handles all incoming http requests to the public api server, using Flask This file handles all incoming http requests
''' to the public api server, using Flask
''' """
import time
import threading
import flask
from gevent.pywsgi import WSGIServer
from httpapi import apiutils, security, fdsafehandler, miscpublicapi
import logger
import config
import filepaths
from utils import gettransports
from etc import onionrvalues, waitforsetvar
"""
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -16,15 +26,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' """
import time
import threading
import flask
from gevent.pywsgi import WSGIServer
from httpapi import apiutils, security, fdsafehandler, miscpublicapi
import logger, config, filepaths
from utils import gettransports
from etc import onionrvalues, waitforsetvar
def _get_tor_adder(pub_api): def _get_tor_adder(pub_api):
transports = [] transports = []
@ -33,32 +36,41 @@ def _get_tor_adder(pub_api):
time.sleep(0.3) time.sleep(0.3)
pub_api.torAdder = transports[0] pub_api.torAdder = transports[0]
class PublicAPI: class PublicAPI:
''' """The new client api server, isolated from the public api."""
The new client api server, isolated from the public api
'''
def __init__(self): def __init__(self):
"""Setup the public api app."""
app = flask.Flask('PublicAPI') app = flask.Flask('PublicAPI')
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024 app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024
self.i2pEnabled = config.get('i2p.host', False) self.i2pEnabled = config.get('i2p.host', False)
self.hideBlocks = [] # Blocks to be denied sharing self.hideBlocks = [] # Blocks to be denied sharing
self.host = apiutils.setbindip.set_bind_IP(filepaths.public_API_host_file) self.host = apiutils.setbindip.set_bind_IP(
filepaths.public_API_host_file)
threading.Thread(target=_get_tor_adder, args=[self], daemon=True).start() threading.Thread(target=_get_tor_adder,
args=[self], daemon=True).start()
self.torAdder = "" self.torAdder = ""
self.bindPort = config.get('client.public.port') self.bindPort = config.get('client.public.port')
self.lastRequest = 0 self.lastRequest = 0
self.hitCount = 0 # total rec requests to public api since server started # total rec requests to public api since server started
self.hitCount = 0
self.config = config self.config = config
self.API_VERSION = onionrvalues.API_VERSION self.API_VERSION = onionrvalues.API_VERSION
logger.info('Running public api on %s:%s' % (self.host, self.bindPort)) logger.info('Running public api on %s:%s' % (self.host, self.bindPort))
app.register_blueprint(security.public.PublicAPISecurity(self).public_api_security_bp) app.register_blueprint(
app.register_blueprint(miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp) security.public.PublicAPISecurity(self).public_api_security_bp)
app.register_blueprint(
miscpublicapi.endpoints.PublicEndpoints(self).public_endpoints_bp)
self.app = app self.app = app
def start(self): def start(self):
"""Start the Public API server."""
waitforsetvar.wait_for_set_var(self, "_too_many") waitforsetvar.wait_for_set_var(self, "_too_many")
self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=fdsafehandler.FDSafeHandler) self.httpServer = WSGIServer((self.host, self.bindPort),
self.httpServer.serve_forever() self.app, log=None,
handler_class=fdsafehandler.FDSafeHandler)
self.httpServer.serve_forever()

View File

@ -54,7 +54,7 @@ def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'):
else: else:
if len(comm_inst.onlinePeers) == 0: if len(comm_inst.onlinePeers) == 0:
logger.debug('Couldn\'t connect to any peers.' + logger.debug('Couldn\'t connect to any peers.' +
f' Last node seen {last_seen} ago.') f' Last node seen {last_seen} ago.')
else: else:
comm_inst.lastNodeSeen = time.time() comm_inst.lastNodeSeen = time.time()
comm_inst.decrementThreadCount('get_online_peers') comm_inst.decrementThreadCount('get_online_peers')

View File

@ -34,10 +34,10 @@ def pick_online_peer(comm_inst):
try: try:
# Get a random online peer, securely. # Get a random online peer, securely.
# May get stuck in loop if network is lost or if all peers in pool magically disconnect at once # May get stuck in loop if network is lost
ret_data = comm_inst.onlinePeers[secrets.randbelow(peer_length)] ret_data = comm_inst.onlinePeers[secrets.randbelow(peer_length)]
except IndexError: except IndexError:
pass pass
else: else:
break break
return ret_data return ret_data

View File

@ -1,9 +1,8 @@
''' """Onionr - Private P2P Communication.
Onionr - Private P2P Communication
remove an online peer from the pool in a communicator instance remove an online peer from the pool in a communicator instance
''' """
''' """
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -16,9 +15,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' """
def remove_online_peer(comm_inst, peer): def remove_online_peer(comm_inst, peer):
'''Remove an online peer''' """Remove an online peer."""
try: try:
del comm_inst.connectTimes[peer] del comm_inst.connectTimes[peer]
except KeyError: except KeyError:
@ -30,4 +31,4 @@ def remove_online_peer(comm_inst, peer):
try: try:
comm_inst.onlinePeers.remove(peer) comm_inst.onlinePeers.remove(peer)
except ValueError: except ValueError:
pass pass