Onionr/onionr/apiservers/private/__init__.py

96 lines
3.5 KiB
Python
Raw Normal View History

2017-12-26 07:25:29 +00:00
'''
Onionr - Private P2P Communication
This file handles all incoming http requests to the client, using Flask
'''
'''
2017-12-26 07:25:29 +00:00
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 <https://www.gnu.org/licenses/>.
'''
2019-08-05 04:08:56 +00:00
import base64, os, time
import flask
2019-07-12 07:07:30 +00:00
from gevent.pywsgi import WSGIServer
from onionrutils import epoch
2019-07-18 17:40:48 +00:00
import httpapi, filepaths, logger
2019-07-12 07:07:30 +00:00
from . import register_private_blueprints
2019-08-04 04:52:57 +00:00
from etc import waitforsetvar
2019-08-02 23:00:04 +00:00
import serializeddata, config
2019-08-04 04:52:57 +00:00
from .. import public
2019-07-12 07:07:30 +00:00
class PrivateAPI:
2019-01-08 05:51:39 +00:00
'''
Client HTTP api
'''
2019-01-08 05:51:39 +00:00
callbacks = {'public' : {}, 'private' : {}}
2018-12-09 17:29:39 +00:00
2019-08-02 23:00:04 +00:00
def __init__(self):
2019-01-08 05:51:39 +00:00
'''
Initialize the api server, preping variables for later use
This initialization defines all of the API entry points and handlers for the endpoints and errors
2019-01-08 05:51:39 +00:00
This also saves the used host (random localhost IP address) to the data folder in host.txt
'''
2019-07-12 07:07:30 +00:00
self.config = config
self.startTime = epoch.get_epoch()
2019-01-08 05:51:39 +00:00
app = flask.Flask(__name__)
bindPort = int(config.get('client.client.port', 59496))
self.bindPort = bindPort
2019-01-08 05:51:39 +00:00
self.clientToken = config.get('client.webpassword')
self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
2019-07-18 17:40:48 +00:00
self.host = httpapi.apiutils.setbindip.set_bind_IP(filepaths.private_API_host_file)
2019-01-08 05:51:39 +00:00
logger.info('Running api on %s:%s' % (self.host, self.bindPort))
self.httpServer = ''
self.queueResponse = {}
2019-07-12 22:31:11 +00:00
self.get_block_data = httpapi.apiutils.GetBlockData(self)
register_private_blueprints.register_private_blueprints(self, app)
2019-07-12 22:31:11 +00:00
httpapi.load_plugin_blueprints(app)
2019-08-04 04:52:57 +00:00
self.app = app
def start(self):
waitforsetvar.wait_for_set_var(self, "_too_many")
self.publicAPI = self._too_many.get(public.PublicAPI)
self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=httpapi.fdsafehandler.FDSafeHandler)
2019-01-08 05:51:39 +00:00
self.httpServer.serve_forever()
2018-07-30 00:37:12 +00:00
2019-01-08 05:51:39 +00:00
def setPublicAPIInstance(self, inst):
self.publicAPI = inst
2018-07-30 00:37:12 +00:00
2019-01-08 05:51:39 +00:00
def validateToken(self, token):
'''
2019-02-12 05:30:56 +00:00
Validate that the client token matches the given token. Used to prevent CSRF and data exfiltration
2019-01-08 05:51:39 +00:00
'''
2019-08-07 22:46:57 +00:00
if not self.clientToken:
2019-01-08 05:51:39 +00:00
logger.error("client password needs to be set")
return False
try:
if not hmac.compare_digest(self.clientToken, token):
return False
else:
return True
except TypeError:
return False
2019-09-26 07:43:03 +00:00
def getUptime(self)->int:
2019-01-28 22:49:04 +00:00
while True:
try:
return epoch.get_epoch() - self.startTime
except (AttributeError, NameError):
2019-01-28 22:49:04 +00:00
# Don't error on race condition with startup
pass
2019-02-04 23:48:21 +00:00
def getBlockData(self, bHash, decrypt=False, raw=False, headerOnly=False):
2019-09-23 19:48:35 +00:00
return self.get_block_data.get_block_data(bHash, decrypt=decrypt, raw=raw, headerOnly=headerOnly)