
10 changed files with 189 additions and 95 deletions
@ -0,0 +1,6 @@
|
||||
from . import announce, upload, getblocks |
||||
|
||||
announce = announce.handle_announce # endpoint handler for accepting peer announcements |
||||
upload = upload.accept_upload # endpoint handler for accepting public uploads |
||||
public_block_list = getblocks.get_public_block_list # endpoint handler for getting block lists |
||||
public_get_block_data = getblocks.get_block_data # endpoint handler for responding to peers requests for block data |
@ -0,0 +1,63 @@
|
||||
''' |
||||
Onionr - P2P Microblogging Platform & Social network |
||||
|
||||
Handle announcements to the public 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 <https://www.gnu.org/licenses/>. |
||||
''' |
||||
import base64 |
||||
from flask import Response |
||||
import logger |
||||
from etc import onionrvalues |
||||
def handle_announce(clientAPI, request): |
||||
''' |
||||
accept announcement posts, validating POW |
||||
clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request |
||||
''' |
||||
resp = 'failure' |
||||
powHash = '' |
||||
randomData = '' |
||||
newNode = '' |
||||
ourAdder = clientAPI._core.hsAddress.encode() |
||||
try: |
||||
newNode = request.form['node'].encode() |
||||
except KeyError: |
||||
logger.warn('No node specified for upload') |
||||
pass |
||||
else: |
||||
try: |
||||
randomData = request.form['random'] |
||||
randomData = base64.b64decode(randomData) |
||||
except KeyError: |
||||
logger.warn('No random data specified for upload') |
||||
else: |
||||
nodes = newNode + clientAPI._core.hsAddress.encode() |
||||
nodes = clientAPI._core._crypto.blake2bHash(nodes) |
||||
powHash = clientAPI._core._crypto.blake2bHash(randomData + nodes) |
||||
try: |
||||
powHash = powHash.decode() |
||||
except AttributeError: |
||||
pass |
||||
if powHash.startswith('0' * onionrvalues.OnionrValues().announce_pow): |
||||
newNode = clientAPI._core._utils.bytesToStr(newNode) |
||||
if clientAPI._core._utils.validateID(newNode) and not newNode in clientAPI._core.onionrInst.communicatorInst.newPeers: |
||||
clientAPI._core.onionrInst.communicatorInst.newPeers.append(newNode) |
||||
resp = 'Success' |
||||
else: |
||||
logger.warn(newNode.decode() + ' failed to meet POW: ' + powHash) |
||||
resp = Response(resp) |
||||
if resp == 'failure': |
||||
return resp, 406 |
||||
return resp |
@ -0,0 +1,50 @@
|
||||
''' |
||||
Onionr - P2P Microblogging Platform & Social network |
||||
|
||||
Public endpoints to get block data and lists |
||||
''' |
||||
''' |
||||
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/>. |
||||
''' |
||||
from flask import Response, abort |
||||
import config |
||||
def get_public_block_list(clientAPI, publicAPI, request): |
||||
# Provide a list of our blocks, with a date offset |
||||
dateAdjust = request.args.get('date') |
||||
bList = clientAPI._core.getBlockList(dateRec=dateAdjust) |
||||
if config.get('general.hide_created_blocks', True): |
||||
for b in publicAPI.hideBlocks: |
||||
if b in bList: |
||||
# Don't share blocks we created if they haven't been *uploaded* yet, makes it harder to find who created a block |
||||
bList.remove(b) |
||||
return Response('\n'.join(bList)) |
||||
|
||||
def get_block_data(clientAPI, publicAPI, data): |
||||
'''data is the block hash in hex''' |
||||
resp = '' |
||||
if clientAPI._utils.validateHash(data): |
||||
if not config.get('general.hide_created_blocks', True) or data not in publicAPI.hideBlocks: |
||||
if data in clientAPI._core.getBlockList(): |
||||
block = clientAPI.getBlockData(data, raw=True) |
||||
try: |
||||
block = block.encode() # Encode in case data is binary |
||||
except AttributeError: |
||||
abort(404) |
||||
block = clientAPI._core._utils.strToBytes(block) |
||||
resp = block |
||||
if len(resp) == 0: |
||||
abort(404) |
||||
resp = "" |
||||
# Has to be octet stream, otherwise binary data fails hash check |
||||
return Response(resp, mimetype='application/octet-stream') |
@ -0,0 +1,43 @@
|
||||
''' |
||||
Onionr - P2P Microblogging Platform & Social network |
||||
|
||||
Accept block uploads to the public 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 <https://www.gnu.org/licenses/>. |
||||
''' |
||||
import sys |
||||
from flask import Response, abort |
||||
import blockimporter, onionrexceptions, logger |
||||
def accept_upload(clientAPI, request): |
||||
resp = 'failure' |
||||
try: |
||||
data = request.form['block'] |
||||
except KeyError: |
||||
logger.warn('No block specified for upload') |
||||
pass |
||||
else: |
||||
if sys.getsizeof(data) < 100000000: |
||||
try: |
||||
if blockimporter.importBlockFromData(data, clientAPI._core): |
||||
resp = 'success' |
||||
else: |
||||
logger.warn('Error encountered importing uploaded block') |
||||
except onionrexceptions.BlacklistedBlock: |
||||
logger.debug('uploaded block is blacklisted') |
||||
pass |
||||
if resp == 'failure': |
||||
abort(400) |
||||
resp = Response(resp) |
||||
return resp |
Loading…
Reference in new issue