diff --git a/src/__init__.py b/src/__init__.py
index 7ee2fd0e..2120af0b 100755
--- a/src/__init__.py
+++ b/src/__init__.py
@@ -70,7 +70,6 @@ createdirs.create_dirs()
import bigbrother # noqa
from onionrcommands import parser # noqa
from onionrplugins import onionrevents as events # noqa
-from onionrblocks.deleteplaintext import delete_plaintext_no_blacklist # noqa
setup.setup_config()
@@ -84,8 +83,6 @@ if config.get('advanced.security_auditing', True):
except onionrexceptions.PythonVersion:
pass
-if not config.get('general.store_plaintext_blocks', True):
- delete_plaintext_no_blacklist()
setup.setup_default_plugins()
diff --git a/src/apiservers/private/__init__.py b/src/apiservers/private/__init__.py
index a480ce96..61f2f40f 100644
--- a/src/apiservers/private/__init__.py
+++ b/src/apiservers/private/__init__.py
@@ -68,7 +68,6 @@ class PrivateAPI:
self.httpServer = ''
self.queueResponse = {}
- self.get_block_data = httpapi.apiutils.GetBlockData(self)
register_private_blueprints.register_private_blueprints(self, app)
httpapi.load_plugin_blueprints(app)
self.app = app
diff --git a/src/apiservers/private/register_private_blueprints.py b/src/apiservers/private/register_private_blueprints.py
index bbbad6d7..40be1ad8 100644
--- a/src/apiservers/private/register_private_blueprints.py
+++ b/src/apiservers/private/register_private_blueprints.py
@@ -6,7 +6,7 @@ from threading import Thread
from gevent import sleep
from httpapi import security, friendsapi, configapi
-from httpapi import miscclientapi, onionrsitesapi, apiutils
+from httpapi import miscclientapi, apiutils
from httpapi import themeapi
from httpapi import fileoffsetreader
from httpapi.sse.private import private_sse_blueprint
@@ -35,8 +35,6 @@ def register_private_blueprints(private_api, app):
app.register_blueprint(configapi.config_BP)
app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(
private_api).private_endpoints_bp)
- app.register_blueprint(miscclientapi.motd.bp)
- app.register_blueprint(onionrsitesapi.site_api)
app.register_blueprint(apiutils.shutdown.shutdown_bp)
app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
app.register_blueprint(themeapi.theme_blueprint)
diff --git a/src/coredb/__init__.py b/src/coredb/__init__.py
index d60f2150..6d5a3268 100644
--- a/src/coredb/__init__.py
+++ b/src/coredb/__init__.py
@@ -1 +1 @@
-from . import keydb, blockmetadb
\ No newline at end of file
+from . import keydb
\ No newline at end of file
diff --git a/src/coredb/blockmetadb/__init__.py b/src/coredb/blockmetadb/__init__.py
deleted file mode 100644
index 10e36f0a..00000000
--- a/src/coredb/blockmetadb/__init__.py
+++ /dev/null
@@ -1,84 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Work with information relating to blocks stored on the node
-"""
-import sqlite3
-
-from etc import onionrvalues
-from . import expiredblocks, updateblockinfo, add
-from .. import dbfiles
-"""
- 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 .
-"""
-
-update_block_info = updateblockinfo.update_block_info
-add_to_block_DB = add.add_to_block_DB
-
-
-def get_block_list(date_rec=None, unsaved=False):
- """Get list of our blocks."""
- if date_rec is None:
- date_rec = 0
-
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
-
- execute = 'SELECT hash FROM hashes WHERE dateReceived' + \
- ' >= ? ORDER BY dateReceived ASC;'
- args = (date_rec,)
- rows = list()
- for row in c.execute(execute, args):
- for i in row:
- rows.append(i)
- conn.close()
- return rows
-
-
-def get_block_date(blockHash):
- """Return the date a block was received."""
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
-
- execute = 'SELECT dateReceived FROM hashes WHERE hash=?;'
- args = (blockHash,)
- for row in c.execute(execute, args):
- for i in row:
- return int(i)
- conn.close()
- return None
-
-
-def get_blocks_by_type(blockType, orderDate=True):
- """Return a list of blocks by the type."""
-
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
-
- if orderDate:
- execute = 'SELECT hash FROM hashes WHERE dataType=? ORDER BY dateReceived;'
- else:
- execute = 'SELECT hash FROM hashes WHERE dataType=?;'
-
- args = (blockType,)
- rows = list()
-
- for row in c.execute(execute, args):
- for i in row:
- rows.append(i)
- conn.close()
- return rows
-
diff --git a/src/coredb/blockmetadb/add.py b/src/coredb/blockmetadb/add.py
deleted file mode 100644
index ec1ab861..00000000
--- a/src/coredb/blockmetadb/add.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Add an entry to the block metadata database
-"""
-import sqlite3
-import secrets
-from onionrutils import epoch
-from onionrblocks import blockmetadata
-from etc import onionrvalues
-from .. import dbfiles
-from onionrexceptions import BlockMetaEntryExists
-"""
- 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 .
-"""
-
-
-def add_to_block_DB(newHash, selfInsert=False, dataSaved=False):
- """
- Add a hash value to the block db
-
- Should be in hex format!
- """
-
- if blockmetadata.has_block(newHash):
- raise BlockMetaEntryExists
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- currentTime = epoch.get_epoch() + secrets.randbelow(61)
- if selfInsert or dataSaved:
- selfInsert = 1
- else:
- selfInsert = 0
- data = (newHash, currentTime, '', selfInsert)
- c.execute(
- 'INSERT INTO hashes (hash, dateReceived, dataType, dataSaved) VALUES(?, ?, ?, ?);', data)
- conn.commit()
- conn.close()
diff --git a/src/coredb/blockmetadb/expiredblocks.py b/src/coredb/blockmetadb/expiredblocks.py
deleted file mode 100644
index efaa75a4..00000000
--- a/src/coredb/blockmetadb/expiredblocks.py
+++ /dev/null
@@ -1,41 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Get a list of expired blocks still stored
-"""
-import sqlite3
-from onionrutils import epoch
-from .. import dbfiles
-from etc import onionrvalues
-"""
- 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 .
-"""
-
-
-def get_expired_blocks():
- """Return a list of expired blocks."""
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- date = int(epoch.get_epoch())
-
- compiled = (date,)
- execute = 'SELECT hash FROM hashes WHERE ' + \
- 'expire <= ? ORDER BY dateReceived;'
-
- rows = list()
- for row in c.execute(execute, compiled):
- for i in row:
- rows.append(i)
- conn.close()
- return rows
diff --git a/src/coredb/blockmetadb/updateblockinfo.py b/src/coredb/blockmetadb/updateblockinfo.py
deleted file mode 100644
index 41a67cca..00000000
--- a/src/coredb/blockmetadb/updateblockinfo.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Update block information in the metadata database by a field name
-"""
-import sqlite3
-
-from .. import dbfiles
-from etc import onionrvalues
-"""
- 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 .
-"""
-
-
-def update_block_info(hash, key, data):
- """set info associated with a block
-
- hash - the hash of a block
- dateReceived - the date the block was recieved, not necessarily when it was created
- decrypted - if we can successfully decrypt the block
- dataType - data type of the block
- dataFound - if the data has been found for the block
- dataSaved - if the data has been saved for the block
- sig - defunct
- author - defunct
- dateClaimed - timestamp claimed inside the block, only as trustworthy as the block author is
- expire - expire date for a block
- """
- if key not in ('dateReceived', 'decrypted', 'dataType', 'dataFound',
- 'dataSaved', 'sig', 'author', 'dateClaimed', 'expire'):
- raise ValueError('Key must be in the allowed list')
-
- conn = sqlite3.connect(dbfiles.block_meta_db,
- timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- args = (data, hash)
- # Unfortunately, not really possible to prepare this statement
- c.execute("UPDATE hashes SET " + key + " = ? where hash = ?;", args)
- conn.commit()
- conn.close()
-
- return True
diff --git a/src/coredb/dbfiles.py b/src/coredb/dbfiles.py
index 3d1e8383..695b89eb 100644
--- a/src/coredb/dbfiles.py
+++ b/src/coredb/dbfiles.py
@@ -3,8 +3,6 @@ import filepaths
home = identifyhome.identify_home()
if not home.endswith('/'): home += '/'
-block_meta_db = '%sblock-metadata.db' % (home)
-block_data_db = '%s/block-data.db' % (filepaths.block_data_location,)
address_info_db = '%saddress.db' % (home,)
user_id_info_db = '%susers.db' % (home,)
forward_keys_db = '%sforward-keys.db' % (home,)
diff --git a/src/httpapi/apiutils/__init__.py b/src/httpapi/apiutils/__init__.py
index cab13c98..d8c4f227 100644
--- a/src/httpapi/apiutils/__init__.py
+++ b/src/httpapi/apiutils/__init__.py
@@ -1,3 +1 @@
-from . import shutdown, setbindip, getblockdata
-
-GetBlockData = getblockdata.GetBlockData
\ No newline at end of file
+from . import shutdown, setbindip
\ No newline at end of file
diff --git a/src/httpapi/apiutils/getblockdata.py b/src/httpapi/apiutils/getblockdata.py
deleted file mode 100644
index 9da1ee59..00000000
--- a/src/httpapi/apiutils/getblockdata.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import ujson as json
-
-from onionrblocks import onionrblockapi
-from onionrutils import bytesconverter, stringvalidators
-import onionrexceptions
-class GetBlockData:
- def __init__(self, client_api_inst=None):
- return
-
- def get_block_data(self, bHash, decrypt=False, raw=False, headerOnly=False):
- if not stringvalidators.validate_hash(bHash):
- raise onionrexceptions.InvalidHexHash(
- "block hash not valid hash format")
- bl = onionrblockapi.Block(bHash)
- if decrypt:
- bl.decrypt()
- if bl.isEncrypted and not bl.decrypted:
- raise ValueError
-
- if not raw:
- if not headerOnly:
- retData = {'meta':bl.bheader, 'metadata': bl.bmetadata, 'content': bl.bcontent}
- for x in list(retData.keys()):
- try:
- retData[x] = retData[x].decode()
- except AttributeError:
- pass
- else:
- validSig = False
- signer = bytesconverter.bytes_to_str(bl.signer)
- if bl.isSigned() and stringvalidators.validate_pub_key(signer) and bl.isSigner(signer):
- validSig = True
- bl.bheader['validSig'] = validSig
- bl.bheader['meta'] = ''
- retData = {'meta': bl.bheader, 'metadata': bl.bmetadata}
- return json.dumps(retData)
- else:
- return bl.raw
\ No newline at end of file
diff --git a/src/httpapi/miscclientapi/__init__.py b/src/httpapi/miscclientapi/__init__.py
index b850723c..1d917684 100644
--- a/src/httpapi/miscclientapi/__init__.py
+++ b/src/httpapi/miscclientapi/__init__.py
@@ -1 +1 @@
-from . import staticfiles, endpoints, motd
\ No newline at end of file
+from . import staticfiles, endpoints
\ No newline at end of file
diff --git a/src/httpapi/miscclientapi/endpoints.py b/src/httpapi/miscclientapi/endpoints.py
index ed10d969..3e91c08c 100644
--- a/src/httpapi/miscclientapi/endpoints.py
+++ b/src/httpapi/miscclientapi/endpoints.py
@@ -78,10 +78,6 @@ class PrivateEndpoints:
subprocess.Popen([SCRIPT_NAME, 'restart'])
return Response("bye")
- @private_endpoints_bp.route('/gethidden')
- def get_hidden_blocks():
- return Response('\n'.join(client_api.publicAPI.hideBlocks))
-
@private_endpoints_bp.route('/getuptime')
def show_uptime():
diff --git a/src/httpapi/miscclientapi/motd/__init__.py b/src/httpapi/miscclientapi/motd/__init__.py
deleted file mode 100644
index ad57b91a..00000000
--- a/src/httpapi/miscclientapi/motd/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from flask import Blueprint
-from flask import Response
-import unpaddedbase32
-
-from coredb import blockmetadb
-import onionrblocks
-from etc import onionrvalues
-import config
-from onionrutils import bytesconverter
-
-bp = Blueprint('motd', __name__)
-
-signer = config.get("motd.motd_key", onionrvalues.MOTD_SIGN_KEY)
-
-@bp.route('/getmotd')
-def get_motd()->Response:
- motds = blockmetadb.get_blocks_by_type("motd")
- newest_time = 0
- message = "No MOTD currently present."
- for x in motds:
- bl = onionrblocks.onionrblockapi.Block(x)
- if not bl.verifySig() or bl.signer != bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))): continue
- if not bl.isSigner(signer): continue
- if bl.claimedTime > newest_time:
- newest_time = bl.claimedTime
- message = bl.bcontent
- return Response(message, headers={"Content-Type": "text/plain"})
diff --git a/src/httpapi/onionrsitesapi/__init__.py b/src/httpapi/onionrsitesapi/__init__.py
deleted file mode 100644
index 9526aa76..00000000
--- a/src/httpapi/onionrsitesapi/__init__.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-view and interact with onionr sites
-"""
-import base64
-import binascii
-import mimetypes
-
-import unpaddedbase32
-
-from flask import Blueprint, Response, request, abort
-
-from onionrblocks import onionrblockapi
-import onionrexceptions
-from onionrutils import stringvalidators
-from onionrutils import mnemonickeys
-from . import sitefiles
-"""
- 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 .
-"""
-
-
-site_api = Blueprint('siteapi', __name__)
-
-@site_api.route('/site//', endpoint='site')
-def site(name: str)->Response:
- """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
- resp: str = 'Not Found'
- mime_type = 'text/html'
-
- # If necessary convert the name to base32 from mnemonic
- if mnemonickeys.DELIMITER in name:
- name = mnemonickeys.get_base32(name)
-
- # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
- if stringvalidators.validate_pub_key(name):
- name = unpaddedbase32.repad(name)
- resp = sitefiles.get_file(name, 'index.html')
-
- elif stringvalidators.validate_hash(name):
- try:
- resp = onionrblockapi.Block(name).bcontent
- except onionrexceptions.NoDataAvailable:
- abort(404)
- except TypeError:
- pass
- try:
- resp = base64.b64decode(resp)
- except binascii.Error:
- pass
- if resp == 'Not Found' or not resp:
- abort(404)
- return Response(resp)
-
-@site_api.route('/site//', endpoint='siteFile')
-def site_file(name: str, file: str)->Response:
- """Accept a site 'name', if pubkey then show multi-page site, if hash show single page site"""
- resp: str = 'Not Found'
- mime_type = mimetypes.MimeTypes().guess_type(file)[0]
-
- # If necessary convert the name to base32 from mnemonic
- if mnemonickeys.DELIMITER in name:
- name = mnemonickeys.get_base32(name)
-
- # Now make sure the key is regardless a valid base32 format ed25519 key (readding padding if necessary)
- if stringvalidators.validate_pub_key(name):
- name = unpaddedbase32.repad(name)
- resp = sitefiles.get_file(name, file)
-
- elif stringvalidators.validate_hash(name):
- try:
- resp = onionrblockapi.Block(name).bcontent
- except onionrexceptions.NoDataAvailable:
- abort(404)
- except TypeError:
- pass
- try:
- resp = base64.b64decode(resp)
- except binascii.Error:
- pass
- if resp == 'Not Found' or not resp:
- abort(404)
- return Response(resp, mimetype=mime_type)
diff --git a/src/httpapi/onionrsitesapi/findsite.py b/src/httpapi/onionrsitesapi/findsite.py
deleted file mode 100644
index 6811ae4c..00000000
--- a/src/httpapi/onionrsitesapi/findsite.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""
- Onionr - Private P2P Communication
-
- view and interact with onionr sites
-"""
-
-from typing import Union
-
-import onionrexceptions
-from onionrutils import mnemonickeys
-from onionrutils import stringvalidators
-from coredb import blockmetadb
-from onionrblocks.onionrblockapi import Block
-from onionrtypes import BlockHash
-
-"""
- 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 .
-"""
-
-
-def find_site(user_id: str) -> Union[BlockHash, None]:
- """Returns block hash str for latest block for a site by a given user id"""
- # If mnemonic delim in key, convert to base32 version
- if mnemonickeys.DELIMITER in user_id:
- user_id = mnemonickeys.get_base32(user_id)
-
- if not stringvalidators.validate_pub_key(user_id):
- raise onionrexceptions.InvalidPubkey
-
- found_site = None
- sites = blockmetadb.get_blocks_by_type('osite')
-
- # Find site by searching all site blocks. eww O(N) ☹️, TODO: event based
- for site in sites:
- site = Block(site)
- if site.isSigner(user_id) and site.verifySig():
- found_site = site.hash
- return found_site
diff --git a/src/httpapi/onionrsitesapi/sitefiles.py b/src/httpapi/onionrsitesapi/sitefiles.py
deleted file mode 100644
index f9171926..00000000
--- a/src/httpapi/onionrsitesapi/sitefiles.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Read onionr site files
-"""
-from typing import Union, Tuple
-import tarfile
-import io
-import os
-
-import unpaddedbase32
-
-from coredb import blockmetadb
-from onionrblocks import onionrblockapi
-from onionrblocks import insert
-
-# Import types. Just for type hiting
-from onionrtypes import UserID, DeterministicKeyPassphrase, BlockHash
-
-from onionrcrypto import generate_deterministic
-"""
- 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 .
-"""
-
-
-def find_site_gzip(user_id: str)->tarfile.TarFile:
- """Return verified site tar object"""
- sites = blockmetadb.get_blocks_by_type('osite')
- user_site = None
- unpadded_user = user_id
- user_id = unpaddedbase32.repad(user_id)
- for site in sites:
- block = onionrblockapi.Block(site)
- if block.isSigner(user_id) or block.isSigner(unpadded_user):
- user_site = block
- if not user_site is None:
- return tarfile.open(fileobj=io.BytesIO(user_site.bcontent), mode='r')
- return None
-
-
-def get_file(user_id, file)->Union[bytes, None]:
- """Get a site file content"""
- ret_data = ""
- site = find_site_gzip(user_id)
-
- if file.endswith('/'):
- file += 'index.html'
- if site is None: return None
- for t_file in site.getmembers():
-
- if t_file.name.replace('./', '') == file:
- return site.extractfile(t_file)
- return None
-
-
-def create_site(admin_pass: DeterministicKeyPassphrase, directory:str='.')->Tuple[UserID, BlockHash]:
- public_key, private_key = generate_deterministic(admin_pass)
-
- raw_tar = io.BytesIO()
-
- tar = tarfile.open(mode='x:gz', fileobj=raw_tar)
- tar.add(directory)
- tar.close()
-
- raw_tar.seek(0)
-
- block_hash = insert(raw_tar.read(), header='osite', signing_key=private_key, sign=True)
-
- return (public_key, block_hash)
diff --git a/src/httpapi/sse/private/__init__.py b/src/httpapi/sse/private/__init__.py
index 9d9ffaef..6e812341 100644
--- a/src/httpapi/sse/private/__init__.py
+++ b/src/httpapi/sse/private/__init__.py
@@ -9,9 +9,6 @@ from gevent import sleep
import gevent
import ujson
-from onionrblocks.onionrblockapi import Block
-from coredb.dbfiles import block_meta_db
-from coredb.blockmetadb import get_block_list
from onionrutils.epoch import get_epoch
from .. import wrapper
"""
@@ -42,27 +39,3 @@ def stream_hello():
sleep(1)
return SSEWrapper.handle_sse_request(print_hello)
-
-@private_sse_blueprint.route('/recentblocks')
-def stream_recent_blocks():
- def _compile_json(b_list):
- js = {}
- block_obj = None
- for block in b_list:
- block_obj = Block(block)
- if block_obj.isEncrypted:
- js[block] = 'encrypted'
- else:
- js[block] = Block(block).btype
- return ujson.dumps({"blocks": js}, reject_bytes=True)
-
- def _stream_recent():
- last_time = Path(block_meta_db).stat().st_ctime
- while True:
- if Path(block_meta_db).stat().st_ctime != last_time:
- last_time = Path(block_meta_db).stat().st_ctime
- yield "data: " + _compile_json(get_block_list(get_epoch() - 5)) + "\n\n"
- else:
- yield "data: none" + "\n\n"
- sleep(5)
- return SSEWrapper.handle_sse_request(_stream_recent)
diff --git a/src/onionrblocks/__init__.py b/src/onionrblocks/__init__.py
deleted file mode 100644
index 0e977261..00000000
--- a/src/onionrblocks/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from . import insert
-from .insert import time_insert
-from .blocklist import BlockList
-insert = insert.insert_block
-time_insert = time_insert
\ No newline at end of file
diff --git a/src/onionrblocks/blockdecrypt.py b/src/onionrblocks/blockdecrypt.py
deleted file mode 100644
index 5a3aad73..00000000
--- a/src/onionrblocks/blockdecrypt.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import ujson
-import nacl.utils
-from nacl.public import PrivateKey, SealedBox
-
-from .blockmetadata import get_block_metadata_from_data
-
-def block_decrypt(raw_block) -> DecryptedBlock:
- block_header, user_meta, block_data = get_block_metadata_from_data(
- raw_block)
-
-
diff --git a/src/onionrblocks/blockimporter.py b/src/onionrblocks/blockimporter.py
deleted file mode 100755
index 29fde84f..00000000
--- a/src/onionrblocks/blockimporter.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Import block data and save it
-"""
-from onionrexceptions import BlacklistedBlock
-from onionrexceptions import DiskAllocationReached
-from onionrexceptions import InvalidProof
-from onionrexceptions import InvalidMetadata
-import logger
-from onionrutils import validatemetadata
-from onionrutils import bytesconverter
-from coredb import blockmetadb
-from onionrblocks import blockmetadata
-import onionrstorage
-import onionrcrypto as crypto
-from . import onionrblacklist
-
-"""
- 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 .
-"""
-
-
-def import_block_from_data(content):
- blacklist = onionrblacklist.OnionrBlackList()
- ret_data = False
-
- content = bytesconverter.str_to_bytes(content)
-
- data_hash = crypto.hashers.sha3_hash(content)
-
- if blacklist.inBlacklist(data_hash):
- raise BlacklistedBlock(f'%s is a blacklisted block {data_hash}')
-
- # returns tuple(metadata, meta), meta is also in metadata
- metas = blockmetadata.get_block_metadata_from_data(content)
- metadata = metas[0]
-
- # check if metadata is valid
- if validatemetadata.validate_metadata(metadata, metas[2]):
- # check if POW is enough/correct
- if crypto.cryptoutils.verify_POW(content):
- logger.info(f'Imported block passed proof, saving: {data_hash}.',
- terminal=True)
- try:
- block_hash = onionrstorage.set_data(content)
- except DiskAllocationReached:
- logger.warn('Failed to save block due to full disk allocation')
- raise
- else:
- blockmetadb.add_to_block_DB(block_hash, dataSaved=True)
- # caches block metadata values to block database
- blockmetadata.process_block_metadata(block_hash)
- ret_data = block_hash
- else:
- raise InvalidProof
- else:
- raise InvalidMetadata
- return ret_data
diff --git a/src/onionrblocks/blocklist.py b/src/onionrblocks/blocklist.py
deleted file mode 100644
index 26c2f925..00000000
--- a/src/onionrblocks/blocklist.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Get an auto updating list of blocks
-"""
-from threading import Thread
-
-from watchdog.observers import Observer
-from watchdog.events import FileSystemEventHandler
-
-from utils.identifyhome import identify_home
-from coredb.dbfiles import block_meta_db
-from coredb.blockmetadb import get_block_list, get_blocks_by_type
-from onionrutils.epoch import get_epoch
-"""
- 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 .
-"""
-
-class BlockList:
- def __init__(self, auto_refresh=True, block_type=''):
- self.block_type = block_type
- self.refresh_db()
- self.check_time = get_epoch()
-
- class Refresher(FileSystemEventHandler):
- @staticmethod
- def on_modified(event):
- if event.src_path != block_meta_db:
- return
- self.refresh_db()
- if auto_refresh:
- def auto_refresher():
- observer = Observer()
- observer.schedule(
- Refresher(), identify_home(), recursive=False)
- observer.start()
- while observer.is_alive():
- # call import func with timeout
- observer.join(120)
- Thread(target=auto_refresher, daemon=True).start()
-
- def get(self):
- return self.block_list
-
- def refresh_db(self):
- self.check_time = get_epoch()
- if not self.block_type:
- self.block_list = get_block_list()
- else:
- self.block_list = get_blocks_by_type(self.block_type)
diff --git a/src/onionrblocks/blockmetadata/__init__.py b/src/onionrblocks/blockmetadata/__init__.py
deleted file mode 100644
index 29d3dc01..00000000
--- a/src/onionrblocks/blockmetadata/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-'''
- Onionr - Private P2P Communication
-
- Module to work with block metadata
-'''
-'''
- 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 . import hasblock, fromdata, process
-has_block = hasblock.has_block
-process_block_metadata = process.process_block_metadata
-get_block_metadata_from_data = fromdata.get_block_metadata_from_data
diff --git a/src/onionrblocks/blockmetadata/fromdata.py b/src/onionrblocks/blockmetadata/fromdata.py
deleted file mode 100644
index 6c98b282..00000000
--- a/src/onionrblocks/blockmetadata/fromdata.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""Onionr - Private P2P Communication.
-
- Return a useful tuple of (metadata (header), meta, and data) by accepting raw block data
-"""
-from json import JSONDecodeError
-import ujson as json
-
-from onionrutils import bytesconverter
-import logger
-"""
- 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 .
-"""
-
-
-def get_block_metadata_from_data(block_data):
- """
- accepts block contents as string, returns a tuple of
- metadata, meta (meta being internal metadata, which will be
- returned as an encrypted base64 string if it is encrypted, dict if not).
- """
- meta = {}
- metadata = {}
- data = block_data
- try:
- block_data = block_data.encode()
- except AttributeError:
- pass
-
- try:
- metadata = json.loads(bytesconverter.bytes_to_str(block_data[:block_data.find(b'\n')]))
- except JSONDecodeError:
- pass
- except ValueError:
- logger.warn("Could not get metadata from:", terminal=True)
- logger.warn(block_data, terminal=True)
- else:
- data = block_data[block_data.find(b'\n'):]
-
- meta = metadata['meta']
- return (metadata, meta, data)
diff --git a/src/onionrblocks/blockmetadata/hasblock.py b/src/onionrblocks/blockmetadata/hasblock.py
deleted file mode 100644
index 72b6d6eb..00000000
--- a/src/onionrblocks/blockmetadata/hasblock.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Return a bool if a block is in the block metadata db or not
-"""
-import sqlite3
-from coredb import dbfiles
-import onionrexceptions
-from onionrutils import stringvalidators
-from etc import onionrvalues
-"""
- 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 .
-"""
-
-
-def has_block(hash: str) -> bool:
- """Check for new block in the block meta db."""
- conn = sqlite3.connect(
- dbfiles.block_meta_db,
- timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- if not stringvalidators.validate_hash(hash):
- raise onionrexceptions.InvalidHexHash("Invalid hash")
- for result in c.execute("SELECT COUNT() FROM hashes WHERE hash = ?", (hash,)):
- if result[0] >= 1:
- conn.commit()
- conn.close()
- return True
- else:
- conn.commit()
- conn.close()
- return False
- return False
diff --git a/src/onionrblocks/blockmetadata/process.py b/src/onionrblocks/blockmetadata/process.py
deleted file mode 100644
index fe094977..00000000
--- a/src/onionrblocks/blockmetadata/process.py
+++ /dev/null
@@ -1,71 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Process block metadata with relevant actions
-"""
-from etc import onionrvalues
-from onionrblocks import onionrblockapi
-from onionrutils import epoch, bytesconverter
-from coredb import blockmetadb
-import logger
-from onionrplugins import onionrevents
-import onionrexceptions
-from onionrusers import onionrusers
-from onionrutils import updater
-"""
- 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 .
-"""
-
-
-def process_block_metadata(blockHash: str):
- """
- Read metadata from a block and cache it to the block database.
-
- blockHash -> sha3_256 hex formatted hash of Onionr block
- """
- curTime = epoch.get_rounded_epoch(roundS=60)
- myBlock = onionrblockapi.Block(blockHash)
- if myBlock.isEncrypted:
- myBlock.decrypt()
- if (myBlock.isEncrypted and myBlock.decrypted) or (not myBlock.isEncrypted):
- blockType = myBlock.getMetadata('type') # we would use myBlock.getType() here, but it is bugged with encrypted blocks
-
- signer = bytesconverter.bytes_to_str(myBlock.signer)
- valid = myBlock.verifySig()
- if valid:
- if myBlock.getMetadata('newFSKey') is not None:
- try:
- onionrusers.OnionrUser(signer).addForwardKey(myBlock.getMetadata('newFSKey'))
- except onionrexceptions.InvalidPubkey:
- logger.warn('%s has invalid forward secrecy key to add: %s' % (signer, myBlock.getMetadata('newFSKey')))
-
- try:
- if len(blockType) <= onionrvalues.MAX_BLOCK_TYPE_LENGTH:
- blockmetadb.update_block_info(blockHash, 'dataType', blockType)
- except TypeError:
- logger.warn("Missing block information")
- pass
- # Set block expire time if specified
- try:
- expireTime = int(myBlock.getHeader('expire'))
- # test that expire time is an integer of sane length (for epoch)
- # doesn't matter if its too large because of the min() func below
- if not len(str(expireTime)) < 20: raise ValueError('timestamp invalid')
- except (ValueError, TypeError) as e:
- expireTime = onionrvalues.DEFAULT_EXPIRE + curTime
- finally:
- expireTime = min(expireTime, curTime + onionrvalues.DEFAULT_EXPIRE)
- blockmetadb.update_block_info(blockHash, 'expire', expireTime)
-
- if blockType == 'update': updater.update_event(myBlock)
- onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid})
diff --git a/src/onionrblocks/deleteplaintext.py b/src/onionrblocks/deleteplaintext.py
deleted file mode 100644
index 427283be..00000000
--- a/src/onionrblocks/deleteplaintext.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""Onionr - P2P Anonymous Storage Network.
-
-Delete but do not blacklist plaintext blocks
-"""
-from coredb import blockmetadb
-from onionrstorage.removeblock import remove_block
-import onionrstorage
-from .onionrblockapi import Block
-import onionrexceptions
-"""
- 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 .
-"""
-
-
-def delete_plaintext_no_blacklist():
- """Delete, but do not blacklist, plaintext blocks."""
-
- block_list = blockmetadb.get_block_list()
-
- for block in block_list:
- block = Block(hash=block, decrypt=False)
- if not block.isEncrypted:
- remove_block(block.hash) # delete metadata entry
- onionrstorage.deleteBlock(block.hash) # delete block data
diff --git a/src/onionrblocks/insert/__init__.py b/src/onionrblocks/insert/__init__.py
deleted file mode 100644
index e516f6b6..00000000
--- a/src/onionrblocks/insert/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from . import main, timeinsert
-
-insert_block = main.insert_block
-time_insert = timeinsert.time_insert
\ No newline at end of file
diff --git a/src/onionrblocks/insert/main.py b/src/onionrblocks/insert/main.py
deleted file mode 100644
index 77acf276..00000000
--- a/src/onionrblocks/insert/main.py
+++ /dev/null
@@ -1,267 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Create and insert Onionr blocks
-"""
-from typing import Union
-import ujson as json
-
-from gevent import spawn
-
-from onionrutils import bytesconverter, epoch
-import filepaths
-import onionrstorage
-from .. import storagecounter
-from onionrplugins import onionrevents as events
-from etc import onionrvalues
-import config
-import onionrcrypto as crypto
-import onionrexceptions
-from onionrusers import onionrusers
-from onionrutils import localcommand, stringvalidators
-from .. import blockmetadata
-import coredb
-from onionrproofs import subprocesspow
-import logger
-from onionrtypes import UserIDSecretKey
-"""
- 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 .
-"""
-storage_counter = storagecounter.StorageCounter()
-
-
-def _check_upload_queue():
- """
- Return the current upload queue len.
-
- raises OverflowError if max, false if api not running
- """
- max_upload_queue: int = 5000
- queue = localcommand.local_command('/gethidden', max_wait=10)
- up_queue = False
-
- try:
- up_queue = len(queue.splitlines())
- except AttributeError:
- pass
- else:
- if up_queue >= max_upload_queue:
- raise OverflowError
- return up_queue
-
-
-def insert_block(data: Union[str, bytes], header: str = 'txt',
- sign: bool = False, encryptType: str = '', symKey: str = '',
- asymPeer: str = '', meta: dict = {},
- expire: Union[int, None] = None, disableForward: bool = False,
- signing_key: UserIDSecretKey = '') -> Union[str, bool]:
- """
- Create and insert a block into the network.
-
- encryptType must be specified to encrypt a block
- if expire is less than date, assumes seconds into future.
- if not assume exact epoch
- """
- our_private_key = crypto.priv_key
- our_pub_key = crypto.pub_key
-
- allocationReachedMessage = 'Cannot insert block, disk allocation reached.'
- if storage_counter.is_full():
- logger.error(allocationReachedMessage)
- raise onionrexceptions.DiskAllocationReached
-
- if signing_key != '':
- # if it was specified to use an alternative private key
- our_private_key = signing_key
- our_pub_key = bytesconverter.bytes_to_str(
- crypto.cryptoutils.get_pub_key_from_priv(our_private_key))
-
- retData = False
-
- if type(data) is None:
- raise ValueError('Data cannot be none')
-
- createTime = epoch.get_epoch()
-
- dataNonce = bytesconverter.bytes_to_str(crypto.hashers.sha3_hash(data))
- try:
- with open(filepaths.data_nonce_file, 'r') as nonces:
- if dataNonce in nonces:
- return retData
- except FileNotFoundError:
- pass
- # record nonce
- with open(filepaths.data_nonce_file, 'a') as nonce_file:
- nonce_file.write(dataNonce + '\n')
-
- plaintext = data
- plaintextMeta = {}
- plaintextPeer = asymPeer
-
- retData = ''
- signature = ''
- signer = ''
- metadata = {}
-
- # metadata is full block metadata
- # meta is internal, user specified metadata
-
- # only use header if not set in provided meta
-
- meta['type'] = str(header)
-
- if encryptType in ('asym', 'sym'):
- metadata['encryptType'] = encryptType
- else:
- if not config.get('general.store_plaintext_blocks', True):
- raise onionrexceptions.InvalidMetadata(
- "Plaintext blocks are disabled, " +
- "yet a plaintext block was being inserted")
- if encryptType not in ('', None):
- raise onionrexceptions.InvalidMetadata(
- 'encryptType must be asym or sym, or blank')
-
- try:
- data = data.encode()
- except AttributeError:
- pass
-
- if encryptType == 'asym':
- # Duplicate the time in encrypted messages to help prevent replays
- meta['rply'] = createTime
- if sign and asymPeer != our_pub_key:
- try:
- forwardEncrypted = onionrusers.OnionrUser(
- asymPeer).forwardEncrypt(data)
- data = forwardEncrypted[0]
- meta['forwardEnc'] = True
- # Expire time of key. no sense keeping block after that
- expire = forwardEncrypted[2]
- except onionrexceptions.InvalidPubkey:
- pass
- if not disableForward:
- fsKey = onionrusers.OnionrUser(asymPeer).generateForwardKey()
- meta['newFSKey'] = fsKey
- jsonMeta = json.dumps(meta)
- plaintextMeta = jsonMeta
- if sign:
- signature = crypto.signing.ed_sign(
- jsonMeta.encode() + data, key=our_private_key, encodeResult=True)
- signer = our_pub_key
-
- if len(jsonMeta) > 1000:
- raise onionrexceptions.InvalidMetadata(
- 'meta in json encoded form must not exceed 1000 bytes')
-
- # encrypt block metadata/sig/content
- if encryptType == 'sym':
- raise NotImplementedError("not yet implemented")
- elif encryptType == 'asym':
- if stringvalidators.validate_pub_key(asymPeer):
- # Encrypt block data with forward secrecy key first, but not meta
- jsonMeta = json.dumps(meta)
- jsonMeta = crypto.encryption.pub_key_encrypt(
- jsonMeta, asymPeer, encodedData=True).decode()
- data = crypto.encryption.pub_key_encrypt(
- data, asymPeer, encodedData=False)
- signature = crypto.encryption.pub_key_encrypt(
- signature, asymPeer, encodedData=True).decode()
- signer = crypto.encryption.pub_key_encrypt(
- signer, asymPeer, encodedData=True).decode()
- try:
- onionrusers.OnionrUser(asymPeer, saveUser=True)
- except ValueError:
- # if peer is already known
- pass
- else:
- logger.warn(f"{asymPeer} is not a valid key to make a block to")
- raise onionrexceptions.InvalidPubkey(
- 'tried to make block to invalid key is not a valid base32 encoded ed25519 key')
-
- # compile metadata
- metadata['meta'] = jsonMeta
- if len(signature) > 0: # I don't like not pattern
- metadata['sig'] = signature
- metadata['signer'] = signer
- metadata['time'] = createTime
-
- # ensure expire is integer and of sane length
- if type(expire) is not type(None): # noqa
- if not len(str(int(expire))) < 20:
- raise ValueError(
- 'expire must be valid int less than 20 digits in length')
- # if expire is less than date, assume seconds into future
- if expire < epoch.get_epoch():
- expire = epoch.get_epoch() + expire
- metadata['expire'] = expire
-
- # send block data (and metadata) to POW module to get tokenized block data
- payload = subprocesspow.SubprocessPOW(data, metadata).start()
-
- if payload != False: # noqa
- try:
- retData = onionrstorage.set_data(payload)
- except onionrexceptions.DiskAllocationReached:
- logger.error(allocationReachedMessage)
- retData = False
- else:
- if disableForward:
- logger.warn(
- f'{retData} asym encrypted block created w/o ephemerality')
- """
- Tell the api server through localCommand to wait for the daemon to
- upload this block to make statistical analysis more difficult
- """
- spawn(
- localcommand.local_command,
- '/daemon-event/upload_event',
- post=True,
- is_json=True,
- post_data={'block': retData}
- ).get(timeout=5)
- coredb.blockmetadb.add.add_to_block_DB(
- retData, selfInsert=True, dataSaved=True)
-
- if expire is None:
- coredb.blockmetadb.update_block_info(
- retData, 'expire',
- createTime + onionrvalues.DEFAULT_EXPIRE)
- else:
- coredb.blockmetadb.update_block_info(retData, 'expire', expire)
-
- blockmetadata.process_block_metadata(retData)
-
- if retData != False: # noqa
- if plaintextPeer == onionrvalues.DENIABLE_PEER_ADDRESS:
- events.event('insertdeniable',
- {'content': plaintext, 'meta': plaintextMeta,
- 'hash': retData,
- 'peer': bytesconverter.bytes_to_str(asymPeer)},
- threaded=True)
- else:
- events.event('insertblock',
- {'content': plaintext, 'meta': plaintextMeta,
- 'hash': retData,
- 'peer': bytesconverter.bytes_to_str(asymPeer)},
- threaded=True)
-
- spawn(
- localcommand.local_command,
- '/daemon-event/remove_from_insert_queue_wrapper',
- post=True,
- post_data={'block_hash':
- bytesconverter.bytes_to_str(
- crypto.hashers.sha3_hash(data))},
- is_json=True
- ).get(timeout=5)
- return retData
diff --git a/src/onionrblocks/insert/timeinsert.py b/src/onionrblocks/insert/timeinsert.py
deleted file mode 100644
index 41d8fcaa..00000000
--- a/src/onionrblocks/insert/timeinsert.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Wrapper to insert blocks with variable delay
-"""
-from . import main
-"""
- 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 .
-"""
-
-
-def time_insert(*args, **kwargs):
- """Block insert wrapper to allow for insertions independent of mixmate.
-
- Takes exact args as insert_block, with additional keyword:
- delay=n; where n=seconds to tell initial nodes to delay share for.
-
- defaults to 0 or previously set value in current block meta
- """
- try:
- kwargs['meta']
- except KeyError:
- kwargs['meta'] = {}
-
- try:
- delay = int(kwargs['meta']['dly'])
- except KeyError:
- delay = 0
- try:
- delay = kwargs['delay']
- del kwargs['delay']
- except KeyError:
- delay = 0
-
- # Ensure delay >=0
- if delay < 0:
- raise ValueError('delay cannot be less than 0')
-
- kwargs['meta']['dly'] = delay
-
- return main.insert_block(*args, **kwargs)
diff --git a/src/onionrblocks/onionrblacklist.py b/src/onionrblocks/onionrblacklist.py
deleted file mode 100755
index 673e9a62..00000000
--- a/src/onionrblocks/onionrblacklist.py
+++ /dev/null
@@ -1,130 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Handle maintenance of a blacklist database, for blocks and peers
-"""
-import sqlite3
-import os
-
-from onionrplugins.onionrevents import event
-import onionrcrypto
-from onionrutils import epoch, bytesconverter
-from coredb import dbfiles
-from etc.onionrvalues import DATABASE_LOCK_TIMEOUT
-"""
- 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 .
-"""
-
-
-class OnionrBlackList:
- def __init__(self):
- self.blacklistDB = dbfiles.blacklist_db
-
- if not os.path.exists(dbfiles.blacklist_db):
- self.generateDB()
- return
-
- def inBlacklist(self, data):
- hashed = bytesconverter.bytes_to_str(
- onionrcrypto.hashers.sha3_hash(data))
- retData = False
-
- if not hashed.isalnum():
- raise Exception("Hashed data is not alpha numeric")
- if len(hashed) > 64:
- raise Exception("Hashed data is too large")
-
- for i in self._dbExecute(
- "SELECT * FROM blacklist WHERE hash = ?", (hashed,)):
- # this only executes if an entry is present by that hash
- retData = True
- break
-
- return retData
-
- def _dbExecute(self, toExec, params=()):
- conn = sqlite3.connect(self.blacklistDB, timeout=DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- retData = c.execute(toExec, params)
- conn.commit()
- return retData
-
- def deleteBeforeDate(self, date):
- # TODO, delete blacklist entries before date
- return
-
- def deleteExpired(self, dataType=0):
- """Delete expired entries"""
- deleteList = []
- curTime = epoch.get_epoch()
-
- try:
- int(dataType)
- except AttributeError:
- raise TypeError("dataType must be int")
-
- for i in self._dbExecute(
- 'SELECT * FROM blacklist WHERE dataType = ?', (dataType,)):
- if i[1] == dataType:
- if (curTime - i[2]) >= i[3]:
- deleteList.append(i[0])
-
- for thing in deleteList:
- self._dbExecute("DELETE FROM blacklist WHERE hash = ?", (thing,))
-
- def generateDB(self):
- return
-
- def clearDB(self):
- self._dbExecute("""DELETE FROM blacklist;""")
-
- def getList(self):
- data = self._dbExecute('SELECT * FROM blacklist')
- myList = []
- for i in data:
- myList.append(i[0])
- return myList
-
- def addToDB(self, data, dataType=0, expire=0):
- """Add to the blacklist. Intended to be block hash, block data, peers, or transport addresses
- 0=block
- 1=peer
- 2=pubkey
- """
-
- # we hash the data so we can remove data entirely from our node's disk
- hashed = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(data))
-
- event('blacklist_add', data={'data': data, 'hash': hashed})
-
- if len(hashed) > 64:
- raise Exception("Hashed data is too large")
-
- if not hashed.isalnum():
- raise Exception("Hashed data is not alpha numeric")
- try:
- int(dataType)
- except ValueError:
- raise Exception("dataType is not int")
- try:
- int(expire)
- except ValueError:
- raise Exception("expire is not int")
- if self.inBlacklist(hashed):
- return
- insert = (hashed,)
- blacklistDate = epoch.get_epoch()
- try:
- self._dbExecute("INSERT INTO blacklist (hash, dataType, blacklistDate, expire) VALUES(?, ?, ?, ?);", (str(hashed), dataType, blacklistDate, expire))
- except sqlite3.IntegrityError:
- pass
diff --git a/src/onionrblocks/onionrblockapi.py b/src/onionrblocks/onionrblockapi.py
deleted file mode 100755
index 875d8faf..00000000
--- a/src/onionrblocks/onionrblockapi.py
+++ /dev/null
@@ -1,443 +0,0 @@
-"""Onionr - P2P Anonymous Storage Network.
-
-OnionrBlocks class for abstraction of blocks
-"""
-import datetime
-import onionrstorage
-
-import unpaddedbase32
-import ujson as json
-import nacl.exceptions
-
-import logger
-import onionrexceptions
-from onionrusers import onionrusers
-from onionrutils import stringvalidators, epoch
-from coredb import blockmetadb
-from onionrutils import bytesconverter
-import onionrblocks
-from onionrcrypto import encryption, cryptoutils as cryptoutils, signing
-"""
- 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 .
-"""
-
-
-class Block:
- blockCacheOrder = list() # NEVER write your own code that writes to this!
- blockCache = dict() # should never be accessed directly, look at Block.getCache()
-
- def __init__(self, hash = None, type = None, content = None, expire=None, decrypt=False, bypassReplayCheck=False):
- # take from arguments
- # sometimes people input a bytes object instead of str in `hash`
- if (not hash is None) and isinstance(hash, bytes):
- hash = hash.decode()
-
- self.hash = hash
- self.btype = type
- self.bcontent = content
- self.expire = expire
- self.bypassReplayCheck = bypassReplayCheck
-
- # initialize variables
- self.valid = True
- self.raw = None
- self.signed = False
- self.signature = None
- self.signedData = None
- self.blockFile = None
- self.bheader = {}
- self.bmetadata = {}
- self.isEncrypted = False
- self.decrypted = False
- self.signer = None
- self.validSig = False
- self.autoDecrypt = decrypt
- self.claimedTime = None
-
- self.update()
-
- def decrypt(self, encodedData = True):
- """
- Decrypt a block, loading decrypted data into their vars
- """
-
- if self.decrypted:
- return True
- retData = False
- # decrypt data
- if self.getHeader('encryptType') == 'asym':
- try:
- self.bcontent = encryption.pub_key_decrypt(self.bcontent, encodedData=False)
-
- bmeta = encryption.pub_key_decrypt(self.bmetadata, encodedData=encodedData)
-
- try:
- bmeta = bmeta.decode()
- except AttributeError:
- # yet another bytes fix
- pass
- self.bmetadata = json.loads(bmeta)
- self.signature = encryption.pub_key_decrypt(self.signature, encodedData=encodedData)
-
- self.signer = encryption.pub_key_decrypt(self.signer, encodedData=encodedData)
-
- self.bheader['signer'] = self.signer.decode()
- self.signedData = json.dumps(self.bmetadata).encode() + self.bcontent
-
- if not self.signer is None:
- if not self.verifySig():
- raise onionrexceptions.SignatureError("Block has invalid signature")
-
- # Check for replay attacks
- try:
- if epoch.get_epoch() - blockmetadb.get_block_date(self.hash) > 60:
- if not cryptoutils.replay_validator(self.bmetadata['rply']): raise onionrexceptions.ReplayAttack
- except (AssertionError, KeyError, TypeError, onionrexceptions.ReplayAttack) as e:
- if not self.bypassReplayCheck:
- # Zero out variables to prevent reading of replays
- self.bmetadata = {}
- self.signer = ''
- self.bheader['signer'] = ''
- self.signedData = ''
- self.signature = ''
- raise onionrexceptions.ReplayAttack('Signature is too old. possible replay attack')
- try:
- if not self.bmetadata['forwardEnc']: raise KeyError
- except (AssertionError, KeyError) as e:
- pass
- else:
- try:
- self.bcontent = onionrusers.OnionrUser(self.signer).forwardDecrypt(self.bcontent)
- except (onionrexceptions.DecryptionError, nacl.exceptions.CryptoError) as e:
- logger.error(str(e))
- pass
- except (nacl.exceptions.CryptoError,) as e:
- logger.debug(f'Could not decrypt block. encodedData: {encodedData}. Either invalid key or corrupted data ' + str(e))
- except onionrexceptions.ReplayAttack:
- logger.warn('%s is possibly a replay attack' % (self.hash,))
- else:
- retData = True
- self.decrypted = True
- return retData
-
- def verifySig(self):
- """
- Verify if a block's signature is signed by its claimed signer
- """
- if self.signer is None:
- return False
- if signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
- self.validSig = True
- else:
- self.validSig = False
- return self.validSig
-
- def update(self, data = None, file = None):
- """
- Loads data from a block in to the current object.
-
- Inputs:
- - data (str):
- - if None: will load from file by hash
- - else: will load from `data` string
- - file (str):
- - if None: will load from file specified in this parameter
- - else: will load from wherever block is stored by hash
-
- Outputs:
- - (bool): indicates whether or not the operation was successful
- """
- try:
- # import from string
- blockdata = data
-
- # import from file
- if blockdata is None:
- try:
- blockdata = onionrstorage.getData(self.getHash())#.decode()
- except AttributeError:
- raise onionrexceptions.NoDataAvailable('Block does not exist')
- else:
- self.blockFile = None
- # parse block
- self.raw = blockdata
- self.bheader = json.loads(self.getRaw()[:self.getRaw().index(b'\n')])
- self.bcontent = self.getRaw()[self.getRaw().index(b'\n') + 1:]
- if ('encryptType' in self.bheader) and (self.bheader['encryptType'] in ('asym', 'sym')):
- self.bmetadata = self.getHeader('meta', None)
- self.isEncrypted = True
- else:
- self.bmetadata = json.loads(self.getHeader('meta', None))
- self.btype = self.getMetadata('type', None)
- self.signed = ('sig' in self.getHeader() and self.getHeader('sig') != '')
- # TODO: detect if signer is hash of pubkey or not
- self.signer = self.getHeader('signer', None)
- self.signature = self.getHeader('sig', None)
- # signed data is jsonMeta + block content (no linebreak)
- self.signedData = (None if not self.isSigned() else self.getHeader('meta').encode() + self.getContent())
- self.date = blockmetadb.get_block_date(self.getHash())
- self.claimedTime = self.getHeader('time', None)
-
- if not self.getDate() is None:
- self.date = datetime.datetime.fromtimestamp(self.getDate())
-
- self.valid = True
-
- if self.autoDecrypt:
- self.decrypt()
-
- return True
- except Exception as e:
- logger.warn('Failed to parse block %s' % self.getHash(), error = e, timestamp = False)
-
-
- self.valid = False
- return False
-
-
- # getters
-
- def getExpire(self):
- """
- Returns the expire time for a block
-
- Outputs:
- - (int): the expire time for a block, or None
- """
- return self.expire
-
- def getHash(self):
- """
- Returns the hash of the block if saved to file
-
- Outputs:
- - (str): the hash of the block, or None
- """
-
- return self.hash
-
- def getType(self):
- """
- Returns the type of the block
-
- Outputs:
- - (str): the type of the block
- """
- return self.btype
-
- def getRaw(self):
- """
- Returns the raw contents of the block, if saved to file
-
- Outputs:
- - (bytes): the raw contents of the block, or None
- """
-
- return self.raw
-
- def getHeader(self, key = None, default = None):
- """
- Returns the header information
-
- Inputs:
- - key (str): only returns the value of the key in the header
-
- Outputs:
- - (dict/str): either the whole header as a dict, or one value
- """
-
- if not key is None:
- if key in self.getHeader():
- return self.getHeader()[key]
- return default
- return self.bheader
-
- def getMetadata(self, key = None, default = None):
- """
- Returns the metadata information
-
- Inputs:
- - key (str): only returns the value of the key in the metadata
-
- Outputs:
- - (dict/str): either the whole metadata as a dict, or one value
- """
-
- if not key is None:
- if key in self.getMetadata():
- return self.getMetadata()[key]
- return default
- return self.bmetadata
-
- def getContent(self):
- """
- Returns the contents of the block
-
- Outputs:
- - (str): the contents of the block
- """
-
- return self.bcontent
-
- def getDate(self):
- """
- Returns the date that the block was received, if loaded from file
-
- Outputs:
- - (datetime): the date that the block was received
- """
-
- return self.date
-
- def getBlockFile(self):
- """
- Returns the location of the block file if it is saved
-
- Outputs:
- - (str): the location of the block file, or None
- """
-
- return self.blockFile
-
- def isValid(self):
- """
- Checks if the block is valid
-
- Outputs:
- - (bool): whether or not the block is valid
- """
-
- return self.valid
-
- def isSigned(self):
- """
- Checks if the block was signed
-
- Outputs:
- - (bool): whether or not the block is signed
- """
-
- return self.signed
-
- def getSignature(self):
- """
- Returns the base64-encoded signature
-
- Outputs:
- - (str): the signature, or None
- """
-
- return self.signature
-
- def getSignedData(self):
- """
- Returns the data that was signed
-
- Outputs:
- - (str): the data that was signed, or None
- """
-
- return self.signedData
-
- def isSigner(self, signer, encodedData = True):
- """
- Checks if the block was signed by the signer inputted
-
- Inputs:
- - signer (str): the public key of the signer to check against
- - encodedData (bool): whether or not the `signer` argument is base64 encoded
-
- Outputs:
- - (bool): whether or not the signer of the block is the signer inputted
- """
- signer = unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))
- try:
- if (not self.isSigned()) or (not stringvalidators.validate_pub_key(signer)):
- return False
-
- return bool(signing.ed_verify(self.getSignedData(), signer, self.getSignature(), encodedData = encodedData))
- except:
- return False
-
- # setters
-
- def setType(self, btype):
- """
- Sets the type of the block
-
- Inputs:
- - btype (str): the type of block to be set to
-
- Outputs:
- - (Block): the Block instance
- """
-
- self.btype = btype
- return self
-
- def setMetadata(self, key, val):
- """
- Sets a custom metadata value
-
- Metadata should not store block-specific data structures.
-
- Inputs:
- - key (str): the key
- - val: the value (type is irrelevant)
-
- Outputs:
- - (Block): the Block instance
- """
-
- self.bmetadata[key] = val
- return self
-
- def setContent(self, bcontent):
- """
- Sets the contents of the block
-
- Inputs:
- - bcontent (str): the contents to be set to
-
- Outputs:
- - (Block): the Block instance
- """
-
- self.bcontent = str(bcontent)
- return self
-
- # static functions
- def exists(bHash):
- """
- Checks if a block is saved to file or not
-
- Inputs:
- - hash (str/Block):
- - if (Block): check if this block is saved to file
- - if (str): check if a block by this hash is in file
-
- Outputs:
- - (bool): whether or not the block file exists
- """
-
- # no input data? scrap it.
- if bHash is None:
- return False
-
- if isinstance(bHash, Block):
- bHash = bHash.getHash()
-
- ret = isinstance(onionrstorage.getData(bHash), type(None))
-
- return not ret
diff --git a/src/onionrblocks/storagecounter.py b/src/onionrblocks/storagecounter.py
deleted file mode 100755
index 7ff0fe9a..00000000
--- a/src/onionrblocks/storagecounter.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""
-Onionr - Private P2P Communication.
-
-Keep track of how much disk space we're using
-"""
-from pathlib import Path
-
-from threading import Thread
-
-from watchdog.observers import Observer
-from watchdog.events import FileSystemEventHandler
-
-import config
-from filepaths import usage_file
-"""
- 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 .
-"""
-config.reload()
-
-
-def _read_data_file(f) -> int:
- amount = 0
- try:
- with open(f, 'r') as f:
- amount = int(f.read())
- except FileNotFoundError:
- pass
- except ValueError:
- pass # Possibly happens when the file is empty
- return amount
-
-
-class StorageCounter:
- def __init__(self):
- self.data_file = usage_file
- self.amount: int = None
- Path(self.data_file).touch()
-
- def auto_refresher():
- class Refresher(FileSystemEventHandler):
- @staticmethod
- def on_modified(event):
- self.amount = _read_data_file(self.data_file)
- observer = Observer()
- observer.schedule(Refresher(), usage_file)
- observer.start()
- while observer.is_alive():
- # call import func with timeout
- observer.join(120)
- Thread(target=auto_refresher, daemon=True).start()
- self.amount = _read_data_file(self.data_file)
-
- def is_full(self) -> bool:
- """Returns if the allocated disk space is full (this is Onionr config,
- not true FS capacity)"""
- ret_data = False
- if config.get('allocations.disk', 1073741824) <= (self.amount + 1000):
- ret_data = True
- return ret_data
-
- def _update(self, data):
- with open(self.data_file, 'w') as data_file:
- data_file.write(str(data))
-
- def get_percent(self) -> int:
- """Return percent (decimal/float) of disk space we're using"""
- amount = self.amount
- return round(amount / config.get('allocations.disk', 2000000000), 2)
-
- def add_bytes(self, amount) -> int:
- """Record that we are now using more disk space,
- unless doing so would exceed configured max"""
- new_amount = amount + self.amount
- ret_data = new_amount
- if new_amount > config.get('allocations.disk', 2000000000):
- ret_data = 0
- else:
- self._update(new_amount)
- return ret_data
-
- def remove_bytes(self, amount) -> int:
- """Record that we are now using less disk space"""
- new_amount = self.amount - amount
- self._update(new_amount)
- return new_amount
diff --git a/src/onionrcommands/banblocks.py b/src/onionrcommands/banblocks.py
deleted file mode 100755
index 49fa21f8..00000000
--- a/src/onionrcommands/banblocks.py
+++ /dev/null
@@ -1,56 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-This file contains the command for banning blocks from the node
-"""
-import sys
-import logger
-from onionrutils import stringvalidators
-from onionrstorage import removeblock
-from onionrstorage import deleteBlock
-from onionrblocks import onionrblacklist
-from utils import reconstructhash
-"""
- 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 .
-"""
-
-
-def ban_block():
- """Delete a block, permanently blacklisting it."""
- blacklist = onionrblacklist.OnionrBlackList()
- try:
- ban = sys.argv[2]
- except IndexError:
- # Get the hash if its not provided as a CLI argument
- ban = logger.readline('Enter a block hash:').strip()
- # Make sure the hash has no truncated zeroes
- ban = reconstructhash.reconstruct_hash(ban)
- if stringvalidators.validate_hash(ban):
- if not blacklist.inBlacklist(ban):
- try:
- blacklist.addToDB(ban)
- removeblock.remove_block(ban)
- deleteBlock(ban)
- except Exception as error: # pylint: disable=W0703
- logger.error('Could not blacklist block',
- error=error, terminal=True)
- else:
- logger.info('Block blacklisted', terminal=True)
- else:
- logger.warn('That block is already blacklisted', terminal=True)
- else:
- logger.error('Invalid block hash', terminal=True)
-
-
-ban_block.onionr_help = ": " # type: ignore
-ban_block.onionr_help += "deletes and blacklists a block" # type: ignore
diff --git a/src/onionrcommands/daemonlaunch/__init__.py b/src/onionrcommands/daemonlaunch/__init__.py
index d54c7452..1fad7b89 100755
--- a/src/onionrcommands/daemonlaunch/__init__.py
+++ b/src/onionrcommands/daemonlaunch/__init__.py
@@ -35,7 +35,6 @@ from utils.bettersleep import better_sleep
from .killdaemon import kill_daemon # noqa
from .showlogo import show_logo
-from sneakernet import sneakernet_import_thread
from setupkvvars import setup_kv
"""
This program is free software: you can redistribute it and/or modify
@@ -142,9 +141,6 @@ def daemon():
events.event('init', threaded=False)
events.event('daemon_start')
- if config.get('transports.sneakernet', True):
- Thread(target=sneakernet_import_thread, daemon=True).start()
-
better_sleep(5)
diff --git a/src/onionrcommands/exportblocks.py b/src/onionrcommands/exportblocks.py
deleted file mode 100755
index 404a6f92..00000000
--- a/src/onionrcommands/exportblocks.py
+++ /dev/null
@@ -1,59 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-This file handles the command for exporting blocks to disk
-"""
-import sys
-
-import logger
-import onionrstorage
-from utils import createdirs
-from onionrutils import stringvalidators
-from etc.onionrvalues import BLOCK_EXPORT_FILE_EXT
-import filepaths
-
-import os
-from coredb import blockmetadb
-"""
- 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 .
-"""
-
-
-def _do_export(b_hash):
- createdirs.create_dirs()
- data = onionrstorage.getData(b_hash)
- with open('%s/%s%s' % (filepaths.export_location,
- b_hash, BLOCK_EXPORT_FILE_EXT), 'wb') as export:
- export.write(data)
- logger.info('Block exported as file', terminal=True)
-
-
-def export_block(*args):
- """Export block based on hash from stdin or argv."""
- if args:
- b_hash = args[0]
- else:
- try:
- if not stringvalidators.validate_hash(sys.argv[2]):
- raise ValueError
- except (IndexError, ValueError):
- logger.error('No valid block hash specified.', terminal=True)
- sys.exit(1)
- else:
- b_hash = sys.argv[2]
- _do_export(b_hash)
-
-
-export_block.onionr_help = ": Export block to " # type: ignore
-export_block.onionr_help += "a file. Export directory is in " # type: ignore
-export_block.onionr_help += "Onionr home under block-export" # type: ignore
diff --git a/src/onionrcommands/filecommands.py b/src/onionrcommands/filecommands.py
deleted file mode 100755
index 315441df..00000000
--- a/src/onionrcommands/filecommands.py
+++ /dev/null
@@ -1,106 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-This file handles the commands for adding
-and getting files from the Onionr network
-"""
-import sys
-import os
-import logger
-from onionrblocks.onionrblockapi import Block
-import onionrexceptions
-from onionrutils import stringvalidators
-from etc import onionrvalues
-from onionrblocks import insert
-"""
- 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 .
-"""
-
-_ORIG_DIR = onionrvalues.ORIG_RUN_DIR_ENV_VAR
-
-
-def _get_dir(path: str) -> str:
- if not os.getenv(_ORIG_DIR) is None:
- return os.getenv(_ORIG_DIR) + '/' + path # type: ignore
- else:
- return path
-
-
-def add_html(singleBlock=True, blockType='html'):
- """Create one-off web page from HTML file, no ext resources."""
- add_file(blockType=blockType)
-
-
-add_html.onionr_help = "Adds an HTML file into Onionr. Does " # type: ignore
-add_html.onionr_help += "not include dependant resources" # type: ignore
-
-
-def add_file(blockType='bin'):
- """Add a file to the onionr network."""
- if len(sys.argv) >= 3:
- filename = sys.argv[2]
-
- if not os.path.exists(_get_dir(filename)):
- logger.error(
- 'That file does not exist. Improper path (specify full path)?',
- terminal=True)
- return
- logger.info('Adding file, this might take a long time.',
- terminal=True)
- try:
- with open(_get_dir(filename), 'rb') as single_file:
- blockhash = insert(single_file.read(), header=blockType)
- if len(blockhash) > 0:
- logger.info('File %s saved in block %s' %
- (filename, blockhash), terminal=True)
- except Exception as err: # pylint: disable=W0703
- logger.error('Failed to save file in block ' +
- str(err), timestamp=False, terminal=True)
- else:
- logger.error('%s add-file ' %
- sys.argv[0], timestamp=False, terminal=True)
-
-
-add_file.onionr_help = " Add a file into " # type: ignore
-add_file.onionr_help += "the Onionr network" # type: ignore
-
-
-def get_file():
- """Get a file from onionr blocks."""
- try:
- file_name = _get_dir(sys.argv[2])
- bHash = sys.argv[3]
- except IndexError:
- logger.error("Syntax %s %s" % (
- sys.argv[0], '/path/to/filename '), terminal=True)
- else:
- logger.info(file_name, terminal=True)
-
- if os.path.exists(file_name):
- logger.error("File already exists", terminal=True)
- return
- if not stringvalidators.validate_hash(bHash):
- logger.error('Block hash is invalid', terminal=True)
- return
-
- try:
- with open(file_name, 'wb') as my_file:
- my_file.write(Block(bHash).bcontent)
- except onionrexceptions.NoDataAvailable:
- logger.error(
- 'That block is not available. Trying again later may work.',
- terminal=True)
-
-
-get_file.onionr_help = ": Download " # type: ignore
-get_file.onionr_help += "a file from the onionr network." # type: ignore
diff --git a/src/onionrcommands/listsites.py b/src/onionrcommands/listsites.py
deleted file mode 100644
index 3f874cfe..00000000
--- a/src/onionrcommands/listsites.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Dumb listing of Onionr sites
-"""
-from coredb.blockmetadb import get_blocks_by_type
-from onionrblocks.onionrblockapi import Block
-import logger
-"""
- 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 .
-"""
-
-
-def print_site_list():
- """Create a new MOTD message for the Onionr network."""
- block_list = get_blocks_by_type('osite')
- if not block_list:
- logger.info('No sites saved right now', terminal=True)
- for block in block_list:
- block = Block(block)
- if block.isSigned():
- logger.info(block.signer.replace('=', ''), terminal=True)
- else:
- logger.info(block.hash, terminal=True)
-
-
-print_site_list.onionr_help = "Dumbly list all Onionr sites currently saved" # type: ignore
diff --git a/src/onionrcommands/onionrstatistics.py b/src/onionrcommands/onionrstatistics.py
index 6502e86c..fd54146a 100755
--- a/src/onionrcommands/onionrstatistics.py
+++ b/src/onionrcommands/onionrstatistics.py
@@ -4,10 +4,9 @@ This module defines commands to show stats/details about the local node
"""
import os
import logger
-from onionrblocks import onionrblacklist
from onionrutils import mnemonickeys
from utils import sizeutils, getconsolewidth, identifyhome
-from coredb import blockmetadb, keydb
+from coredb import keydb
import onionrcrypto
import config
from etc import onionrvalues
@@ -43,9 +42,8 @@ def show_stats():
"""Print/log statistic info about our Onionr install."""
try:
# define stats messages here
- totalBlocks = len(blockmetadb.get_block_list())
home = identifyhome.identify_home()
- totalBanned = len(onionrblacklist.OnionrBlackList().getList())
+
messages = {
# info about local client
@@ -69,9 +67,7 @@ def show_stats():
'div2': True,
'Enabled Plugins':
str(len(config.get('plugins.enabled', list()))) + ' / ' +
- str(len(os.listdir(home + 'plugins/'))),
- 'Stored Blocks': str(totalBlocks),
- 'Deleted Blocks': str(totalBanned)
+ str(len(os.listdir(home + 'plugins/')))
}
# color configuration
diff --git a/src/onionrcommands/parser/arguments.py b/src/onionrcommands/parser/arguments.py
index d2669004..ad5fa698 100644
--- a/src/onionrcommands/parser/arguments.py
+++ b/src/onionrcommands/parser/arguments.py
@@ -6,19 +6,14 @@ from typing import Callable
from .. import onionrstatistics, version, daemonlaunch
from .. import openwebinterface
-from .. import banblocks # Command to blacklist a block by its hash
-from .. import filecommands # commands to share files with onionr
-from .. import exportblocks # commands to export blocks
from .. import pubkeymanager # commands to add or change id
from .. import resetplugins # command to reinstall default plugins
from .. import softreset # command to delete onionr blocks
from .. import restartonionr # command to restart Onionr
from .. import runtimetestcmd # cmd to execute the runtime integration tests
-from .. import sitecreator # cmd to create multi-page sites
-from ..listsites import print_site_list # cmd to list list ids
+
import onionrexceptions
-from onionrutils import importnewblocks # func to import new blocks
"""
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
@@ -42,8 +37,6 @@ def get_arguments() -> dict:
dynamically modify them with plugins
"""
args = {
- ('blacklist', 'blacklist-block', 'remove-block',
- 'removeblock', 'banblock', 'ban-block'): banblocks.ban_block,
('details', 'info'): onionrstatistics.show_details,
('stats', 'statistics'): onionrstatistics.show_stats,
('version',): version.version,
@@ -53,15 +46,6 @@ def get_arguments() -> dict:
('openhome', 'gui', 'openweb',
'open-home', 'open-web'): openwebinterface.open_home,
('get-url', 'url', 'get-web'): openwebinterface.get_url,
- ('addhtml', 'add-html'): filecommands.add_html,
- ('addsite', 'add-site',
- 'update-site', 'updatesite'): sitecreator.create_multipage_site,
- ('listsites', 'list-sites'): print_site_list,
- ('addfile', 'add-file'): filecommands.add_file,
- ('get-file', 'getfile'): filecommands.get_file,
- ('export-block', 'exportblock'): exportblocks.export_block,
- ('importblocks',
- 'import-blocks', 'import-block'): importnewblocks.import_new_blocks,
('addid', 'add-id'): pubkeymanager.add_ID,
('changeid', 'change-id'): pubkeymanager.change_ID,
('add-vanity', 'addvanity'): pubkeymanager.add_vanity,
diff --git a/src/onionrcommands/sitecreator.py b/src/onionrcommands/sitecreator.py
deleted file mode 100644
index 29733105..00000000
--- a/src/onionrcommands/sitecreator.py
+++ /dev/null
@@ -1,72 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Command to create Onionr mutli-page sites
-"""
-import sys
-import os
-import getpass
-
-from niceware import generate_passphrase
-
-from httpapi import onionrsitesapi
-import logger
-from etc import onionrvalues
-"""
- 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 .
-"""
-
-
-def create_multipage_site():
- """Command to create mutlipage sites with specified dir and password."""
- error_encountered = False
- orig_dir = os.getcwd()
- try:
- directory = sys.argv[2]
- os.chdir(directory)
- directory = '.'
- except IndexError:
- directory = '.'
- try:
- passphrase = sys.argv[3]
- except IndexError:
- logger.warn('''It is critical that this passphrase is long.
-If you want to update your site later you must remember the passphrase.''',
- terminal=True)
-
- passphrase = "-".join(generate_passphrase(32))
- print("Site restore phrase:", passphrase)
-
- if len(passphrase) < onionrvalues.PASSWORD_LENGTH:
- error_encountered = True
- logger.error(
- f'Passphrase must be at least {onionrvalues.PASSWORD_LENGTH}' +
- ' characters.', terminal=True)
-
- if error_encountered:
- sys.exit(1)
- logger.info('Generating site...', terminal=True)
- results = onionrsitesapi.sitefiles.create_site(
- passphrase, directory=directory)
- results = (results[0].replace('=', ''), results[1])
- logger.info(f'Site address {results[0]}', terminal=True)
- logger.info(f'Block for this version {results[1]}', terminal=True)
- os.chdir(orig_dir)
-
-
-create_multipage_site.onionr_help = "[directory path " # type: ignore
-create_multipage_site.onionr_help += "(default relative)] " # type: ignore
-create_multipage_site.onionr_help += "- packages a whole " # type: ignore
-create_multipage_site.onionr_help += "directory and makes " # type: ignore
-create_multipage_site.onionr_help += "it available as " # type: ignore
-create_multipage_site.onionr_help += "an Onionr site." # type: ignore
diff --git a/src/onionrcrypto/cryptoutils/__init__.py b/src/onionrcrypto/cryptoutils/__init__.py
index 0f6251d4..635099d4 100644
--- a/src/onionrcrypto/cryptoutils/__init__.py
+++ b/src/onionrcrypto/cryptoutils/__init__.py
@@ -1,7 +1,6 @@
-from . import safecompare, replayvalidation, verifypow
+from . import safecompare, replayvalidation
from . import getpubfrompriv
replay_validator = replayvalidation.replay_timestamp_validation
safe_compare = safecompare.safe_compare
-verify_POW = verifypow.verify_POW
get_pub_key_from_priv = getpubfrompriv.get_pub_key_from_priv
diff --git a/src/onionrproofs/__init__.py b/src/onionrproofs/__init__.py
deleted file mode 100755
index 17730e01..00000000
--- a/src/onionrproofs/__init__.py
+++ /dev/null
@@ -1,67 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Proof of work module
-"""
-import multiprocessing, time, math, threading, binascii, sys, json
-import nacl.encoding, nacl.hash, nacl.utils
-
-import config
-import logger
-from onionrblocks import onionrblockapi
-from onionrutils import bytesconverter
-from onionrcrypto import hashers
-
-from .blocknoncestart import BLOCK_NONCE_START_INT
-from .vdf import create_vdf
-"""
- 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 .
-"""
-config.reload()
-
-
-def getDifficultyForNewBlock(data):
- """
- Get difficulty for block. Accepts size in integer, Block instance, or str/bytes full block contents
- """
- if isinstance(data, onionrblockapi.Block):
- dataSizeInBytes = len(bytesconverter.str_to_bytes(data.getRaw()))
- else:
- dataSizeInBytes = len(bytesconverter.str_to_bytes(data))
-
- minDifficulty = config.get('general.minimum_send_pow', 4)
- totalDifficulty = max(minDifficulty, math.floor(dataSizeInBytes / 1000000.0))
-
- return totalDifficulty
-
-
-def getHashDifficulty(h: str):
- """
- Return the amount of leading zeroes in a hex hash string (hexHash)
- """
- return len(h) - len(h.lstrip('0'))
-
-
-def hashMeetsDifficulty(hexHash):
- """
- Return bool for a hash string to see if it meets pow difficulty defined in config
- """
- hashDifficulty = getHashDifficulty(hexHash)
-
- try:
- expected = int(config.get('general.minimum_block_pow'))
- except TypeError:
- raise ValueError('Missing general.minimum_block_pow config')
-
- return hashDifficulty >= expected
-
diff --git a/src/onionrproofs/blocknoncestart.py b/src/onionrproofs/blocknoncestart.py
deleted file mode 100644
index 93bf4908..00000000
--- a/src/onionrproofs/blocknoncestart.py
+++ /dev/null
@@ -1 +0,0 @@
-BLOCK_NONCE_START_INT = -10000000
\ No newline at end of file
diff --git a/src/onionrproofs/subprocesspow.py b/src/onionrproofs/subprocesspow.py
deleted file mode 100755
index a988b366..00000000
--- a/src/onionrproofs/subprocesspow.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env python3
-"""Onionr - Private P2P Communication.
-
-Multiprocess proof of work
-"""
-
-import os
-from multiprocessing import Pipe, Process
-import threading
-import time
-import secrets
-
-import onionrproofs
-
-import ujson as json
-
-import logger
-from onionrutils import bytesconverter
-from onionrcrypto.hashers import sha3_hash
-
-"""
- 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 .
-"""
-
-
-class SubprocessPOW:
- def __init__(self, data, metadata, subproc_count=None):
- """
- Onionr proof of work using multiple processes
- Accepts block data, block metadata
- if subproc_count is not set,
- os.cpu_count() is used to determine the number of processes
-
- Due to Python GIL multiprocessing/use of external libraries
- is necessary to accelerate CPU bound tasks
- """
- # No known benefit to using more processes than there are cores.
- # Note: os.cpu_count perhaps not always accurate
- if subproc_count is None:
- subproc_count = os.cpu_count()
- self.subproc_count = subproc_count
- self.result = ''
- self.shutdown = False
- self.data = data
- self.metadata = metadata
-
- """dump dict to measure bytes of json metadata
- Cannot reuse later bc the pow token must be added
- """
- json_metadata = json.dumps(metadata).encode()
-
- self.data = bytesconverter.str_to_bytes(data)
-
- compiled_data = bytes(json_metadata + b'\n' + self.data)
-
- # Calculate difficulty. May use better algorithm in the future.
- self.difficulty = onionrproofs.getDifficultyForNewBlock(compiled_data)
-
- logger.info('Computing POW (difficulty: %s)...' % (self.difficulty,))
-
- self.main_hash = '0' * 64
- self.puzzle = self.main_hash[0:min(self.difficulty,
- len(self.main_hash))]
- self.shutdown = False
- self.payload = None
-
- def start(self):
- """spawn the multiproc handler threads"""
- # Create a new thread for each subprocess
- for _ in range(self.subproc_count): # noqa
- threading.Thread(target=self._spawn_proc, daemon=True).start()
- # Monitor the processes for a payload, shut them down when its found
- while True:
- if self.payload is None:
- time.sleep(0.1)
- else:
- self.shutdown = True
- return self.payload
-
- def _spawn_proc(self):
- """Create a child proof of work process
- wait for data and send shutdown signal when its found"""
- # The importerror started happening in 3.9.x
- # not worth fixing because this POW will be replaced by VDF
- try:
- parent_conn, child_conn = Pipe()
- p = Process(target=self.do_pow, args=(child_conn,), daemon=True)
- p.start()
- except ImportError:
- logger.error(
- "Error in subprocess module when getting new POW " +
- "pipe.\nThis is related to a problem in 3.9.x", terminal=True)
- return
- payload = None
- try:
- while True:
- data = parent_conn.recv()
- if len(data) >= 1:
- payload = data
- break
- except KeyboardInterrupt:
- pass
- finally:
- p.terminate()
- self.payload = payload
-
- def do_pow(self, pipe):
- """find partial hash colision generating nonce for a block"""
- nonce = 0
- data = self.data
- metadata = self.metadata
- metadata['n'] = secrets.randbits(16)
- puzzle = self.puzzle
- difficulty = self.difficulty
- try:
- while True:
- #logger.info('still running', terminal=True)
- # Break if shutdown received
- try:
- if pipe.poll() and pipe.recv() == 'shutdown':
- break
- except KeyboardInterrupt:
- break
- # Load nonce into block metadata
- metadata['c'] = nonce
- # Serialize metadata, combine with block data
- payload = json.dumps(metadata).encode() + b'\n' + data
- # Check sha3_256 hash of block, compare to puzzle
- # Send payload if puzzle finished
- token = sha3_hash(payload)
- # ensure token is string
- token = bytesconverter.bytes_to_str(token)
- if puzzle == token[0:difficulty]:
- pipe.send(payload)
- break
- nonce += 1
- except KeyboardInterrupt:
- pass
diff --git a/src/onionrproofs/vdf.py b/src/onionrproofs/vdf.py
deleted file mode 100644
index c48af161..00000000
--- a/src/onionrproofs/vdf.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import multiprocessing
-
-import mimcvdf
-
-
-def _wrap_vdf_create(queue, block_data_bytes, rounds):
- queue.put(mimcvdf.vdf_create(block_data_bytes, rounds))
-
-
-def _wrap_vdf_verify(queue, block_data_bytes, block_hash_hex, rounds):
- queue.put(mimcvdf.vdf_verify(block_data_bytes, block_hash_hex, rounds))
-
-
-
-def rounds_for_bytes(byte_count: int):
- return byte_count * 1000
-
-
-
-def create_vdf(block_data_bytes):
- rounds = rounds_for_bytes(block_data_bytes)
- queue = multiprocessing.Queue()
- vdf_proc = multiprocessing.Process(
- target=_wrap_vdf_create,
- args=(queue, block_data_bytes, rounds))
- vdf_proc.start()
- vdf_proc.join()
- return queue.get()
-
-
-def verify_vdf(block_hash_hex, block_data_bytes):
- rounds = rounds_for_bytes(block_data_bytes)
- if rounds < 10 ** 6:
- # >million rounds it starts to take long enough to warrant a subprocess
- queue = multiprocessing.Queue()
- vdf_proc = multiprocessing.Process(
- target=_wrap_vdf_verify,
- args=(queue, block_data_bytes, block_hash_hex, rounds))
- vdf_proc.start()
- vdf_proc.join()
- return queue.get()
- return mimcvdf.vdf_verify(block_data_bytes, block_hash_hex, rounds)
-
diff --git a/src/onionrsetup/dbcreator.py b/src/onionrsetup/dbcreator.py
index d9b8e626..1bc6a9d1 100755
--- a/src/onionrsetup/dbcreator.py
+++ b/src/onionrsetup/dbcreator.py
@@ -77,57 +77,6 @@ def createPeerDB():
conn.close()
return
-def createBlockDB():
- '''
- Create a database for blocks
-
- hash - the hash of a block
- dateReceived - the date the block was recieved, not necessarily when it was created
- decrypted - if we can successfully decrypt the block (does not describe its current state)
- dataType - data type of the block
- dataFound - if the data has been found for the block
- dataSaved - if the data has been saved for the block
- sig - optional signature by the author (not optional if author is specified)
- author - multi-round partial sha3-256 hash of authors public key
- dateClaimed - timestamp claimed inside the block, only as trustworthy as the block author is
- expire int - block expire date in epoch
- '''
- if os.path.exists(dbfiles.block_meta_db):
- raise FileExistsError("Block database already exists")
- conn = sqlite3.connect(dbfiles.block_meta_db)
- c = conn.cursor()
- c.execute('''CREATE TABLE hashes(
- hash text not null,
- dateReceived int,
- decrypted int,
- dataType text,
- dataFound int,
- dataSaved int,
- sig text,
- author text,
- dateClaimed int,
- expire int
- );
- ''')
- conn.commit()
- conn.close()
- return
-
-def createBlockDataDB():
- if os.path.exists(dbfiles.block_data_db):
- raise FileExistsError("Block data database already exists")
- else:
- if not os.path.exists(filepaths.block_data_location):
- os.mkdir(filepaths.block_data_location)
- conn = sqlite3.connect(dbfiles.block_data_db)
- c = conn.cursor()
- c.execute('''CREATE TABLE blockData(
- hash text not null,
- data blob not null
- );
- ''')
- conn.commit()
- conn.close()
def createForwardKeyDB():
'''
@@ -168,5 +117,4 @@ def create_blacklist_db():
create_funcs = [createAddressDB, createPeerDB,
- createBlockDB, createBlockDataDB,
createForwardKeyDB, create_blacklist_db]
\ No newline at end of file
diff --git a/src/onionrstorage/__init__.py b/src/onionrstorage/__init__.py
deleted file mode 100755
index 1b964d46..00000000
--- a/src/onionrstorage/__init__.py
+++ /dev/null
@@ -1,116 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Handle block storage, providing an abstraction for
-storing blocks between file system and database
-"""
-import sys
-import sqlite3
-import os
-from onionrutils import bytesconverter
-from onionrutils import stringvalidators
-from coredb import dbfiles
-from filepaths import block_data_location
-import onionrexceptions
-from onionrcrypto import hashers
-from . import setdata, removeblock
-from etc.onionrvalues import DATABASE_LOCK_TIMEOUT, BLOCK_EXPORT_FILE_EXT
-"""
- 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 .
-"""
-
-
-DB_ENTRY_SIZE_LIMIT = 10000 # Will be a config option
-
-set_data = setdata.set_data
-
-
-def _dbInsert(block_hash, data):
- conn = sqlite3.connect(dbfiles.block_data_db,
- timeout=DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- data = (block_hash, data)
- c.execute('INSERT INTO blockData (hash, data) VALUES(?, ?);', data)
- conn.commit()
- conn.close()
-
-
-def _dbFetch(block_hash):
- conn = sqlite3.connect(dbfiles.block_data_db,
- timeout=DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- for i in c.execute(
- 'SELECT data from blockData where hash = ?', (block_hash,)):
- return i[0]
- conn.commit()
- conn.close()
- return None
-
-
-def deleteBlock(block_hash):
- # Call removeblock.remove_block to automatically want to remove storage byte count
- if os.path.exists(f'{block_data_location}/{block_hash}{BLOCK_EXPORT_FILE_EXT}'):
- os.remove(f'{block_data_location}/{block_hash}{BLOCK_EXPORT_FILE_EXT}')
- return True
- conn = sqlite3.connect(dbfiles.block_data_db,
- timeout=DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- data = (block_hash,)
- c.execute('DELETE FROM blockData where hash = ?', data)
- conn.commit()
- conn.close()
- return True
-
-
-def store(data, block_hash=''):
- if not stringvalidators.validate_hash(block_hash):
- raise ValueError
- ourHash = hashers.sha3_hash(data)
- if block_hash != '':
- if not ourHash == block_hash:
- raise ValueError('Hash specified does not meet internal hash check')
- else:
- block_hash = ourHash
-
- if DB_ENTRY_SIZE_LIMIT >= sys.getsizeof(data):
- _dbInsert(block_hash, data)
- else:
- with open(
- f'{block_data_location}/{block_hash}{BLOCK_EXPORT_FILE_EXT}', 'wb') as blck_file:
- blck_file.write(data)
-
-
-def getData(bHash):
-
- if not stringvalidators.validate_hash(bHash):
- raise ValueError
-
- bHash = bytesconverter.bytes_to_str(bHash)
- bHash = bHash.strip()
- # First check DB for data entry by hash
- # if no entry, check disk
- # If no entry in either, raise an exception
- ret_data = None
- fileLocation = '%s/%s%s' % (
- block_data_location,
- bHash, BLOCK_EXPORT_FILE_EXT)
- not_found_msg = "Block data not found for: " + str(bHash)
- if os.path.exists(fileLocation):
- with open(fileLocation, 'rb') as block:
- ret_data = block.read()
- else:
- ret_data = _dbFetch(bHash)
-
- if ret_data is None:
- raise onionrexceptions.NoDataAvailable(not_found_msg)
- return ret_data
diff --git a/src/onionrstorage/removeblock.py b/src/onionrstorage/removeblock.py
deleted file mode 100644
index 6b9452ea..00000000
--- a/src/onionrstorage/removeblock.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-remove onionr block from meta db
-"""
-import sys
-import sqlite3
-
-import onionrexceptions
-import onionrstorage
-from onionrutils import stringvalidators
-from coredb import dbfiles
-from onionrblocks import storagecounter
-from etc.onionrvalues import DATABASE_LOCK_TIMEOUT
-"""
- 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 .
-"""
-storage_counter = storagecounter.StorageCounter()
-
-
-def remove_block(block):
- """Remove a block from this node.
-
- (does not automatically blacklist).
- **You may want blacklist.addToDB(blockHash)
- """
- if stringvalidators.validate_hash(block):
- try:
- data_size = sys.getsizeof(onionrstorage.getData(block))
- except onionrexceptions.NoDataAvailable:
- data_size = 0
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- t = (block,)
- c.execute('Delete from hashes where hash=?;', t)
- conn.commit()
- conn.close()
- if data_size:
- storage_counter.remove_bytes(data_size)
- else:
- raise onionrexceptions.InvalidHexHash
diff --git a/src/onionrstorage/setdata.py b/src/onionrstorage/setdata.py
deleted file mode 100644
index 502ec086..00000000
--- a/src/onionrstorage/setdata.py
+++ /dev/null
@@ -1,70 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Test Onionr as it is running
-"""
-import sys
-import sqlite3
-
-import onionrstorage
-import onionrexceptions
-import onionrcrypto as crypto
-import filepaths
-from onionrblocks import storagecounter, blockmetadata
-from coredb import dbfiles
-from onionrutils import bytesconverter
-from etc.onionrvalues import DATABASE_LOCK_TIMEOUT
-from onionrtypes import BlockHash
-"""
- 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 .
-"""
-storage_counter = storagecounter.StorageCounter()
-
-
-def set_data(data):
- """Set the data assciated with a hash."""
- dataSize = sys.getsizeof(data)
- nonce_hash = crypto.hashers.sha3_hash(
- bytesconverter.str_to_bytes(
- blockmetadata.fromdata.get_block_metadata_from_data(data)[2]))
- nonce_hash = bytesconverter.bytes_to_str(nonce_hash)
-
- if not type(data) is bytes:
- data = data.encode()
-
- dataHash = crypto.hashers.sha3_hash(data)
-
- if type(dataHash) is bytes:
- dataHash = dataHash.decode()
- try:
- onionrstorage.getData(dataHash)
- except onionrexceptions.NoDataAvailable:
- if storage_counter.add_bytes(dataSize):
- onionrstorage.store(data, block_hash=dataHash)
- conn = sqlite3.connect(
- dbfiles.block_meta_db, timeout=DATABASE_LOCK_TIMEOUT)
- c = conn.cursor()
- c.execute(
- "UPDATE hashes SET dataSaved=1 WHERE hash = ?;",
- (dataHash,))
- conn.commit()
- conn.close()
- with open(filepaths.data_nonce_file, 'a') as nonceFile:
- nonceFile.write(nonce_hash + '\n')
- else:
- raise onionrexceptions.DiskAllocationReached
- else:
- raise onionrexceptions.DataExists(
- "Data is already set for " + dataHash)
-
- return dataHash
diff --git a/src/onionrutils/importnewblocks.py b/src/onionrutils/importnewblocks.py
deleted file mode 100644
index 11ae89c5..00000000
--- a/src/onionrutils/importnewblocks.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-import new blocks from disk, providing transport agnosticism
-"""
-import glob
-
-import logger
-from onionrblocks import blockmetadata
-from coredb import blockmetadb
-import filepaths
-import onionrcrypto as crypto
-from etc.onionrvalues import BLOCK_EXPORT_FILE_EXT
-"""
- 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 .
-"""
-
-
-def import_new_blocks(scanDir=''):
- """Scan for new blocks ON THE DISK and import them"""
- blockList = blockmetadb.get_block_list()
- exist = False
- if scanDir == '':
- scanDir = filepaths.block_data_location
- if not scanDir.endswith('/'):
- scanDir += '/'
- for block in glob.glob(scanDir + "*%s" % (BLOCK_EXPORT_FILE_EXT,)):
- if block.replace(scanDir, '').replace(BLOCK_EXPORT_FILE_EXT, '') \
- not in blockList:
- exist = True
- logger.info('Found new block on dist %s' % block, terminal=True)
- with open(block, 'rb') as newBlock:
- block = block.replace(scanDir, '').replace(
- BLOCK_EXPORT_FILE_EXT, '')
- if crypto.hashers.sha3_hash(newBlock.read()) == block.replace(
- BLOCK_EXPORT_FILE_EXT, ''):
- blockmetadb.add_to_block_DB(block.replace(
- BLOCK_EXPORT_FILE_EXT, ''), dataSaved=True)
- logger.info('Imported block %s' % block, terminal=True)
- blockmetadata.process_block_metadata(block)
- else:
- logger.warn('Failed to verify hash for %s' % block,
- terminal=True)
- if not exist:
- logger.info('No blocks found to import', terminal=True)
-
-
-import_new_blocks.onionr_help = \
- f"Scan the Onionr data directory under {filepaths.block_data_location}" + \
- "for new block files (.db not supported) to import"
diff --git a/src/runtests/__init__.py b/src/runtests/__init__.py
index addc0edf..4e7f6ee0 100644
--- a/src/runtests/__init__.py
+++ b/src/runtests/__init__.py
@@ -8,12 +8,9 @@ from secrets import SystemRandom
import logger
from onionrutils import epoch
-from . import uicheck, inserttest, stresstest
+from . import uicheck
from .webpasstest import webpass_test
from .osver import test_os_ver_endpoint
-from .clearnettor import test_clearnet_tor_request
-from .housekeeping import test_inserted_housekeeping
-from .sneakernettest import test_sneakernet_import
from .dnsrebindingtest import test_dns_rebinding
"""
This program is free software: you can redistribute it and/or modify
@@ -31,14 +28,8 @@ from .dnsrebindingtest import test_dns_rebinding
"""
RUN_TESTS = [uicheck.check_ui,
- inserttest.insert_bin_test,
- stresstest.stress_test_block_insert,
webpass_test,
test_os_ver_endpoint,
- test_clearnet_tor_request,
- test_inserted_housekeeping,
- sneakernettest.test_sneakernet_import,
- test_dns_rebinding
]
SUCCESS_FILE = os.path.dirname(os.path.realpath(__file__)) + '/../../tests/runtime-result.txt'
diff --git a/src/runtests/clearnettor.py b/src/runtests/clearnettor.py
deleted file mode 100644
index e17bc9bb..00000000
--- a/src/runtests/clearnettor.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Ensure that clearnet cannot be reached
-"""
-from onionrutils.basicrequests import do_get_request
-from onionrutils import localcommand
-import logger
-import config
-"""
- 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 .
-"""
-
-
-def test_clearnet_tor_request(testmanager):
- """Ensure that Tor cannot request clearnet address.
-
- Does not run if Tor is being reused
- """
-
- config.reload()
- leak_result = ""
-
- if config.get('tor.use_existing_tor', False):
- logger.warn(
- "Can't ensure Tor reqs to clearnet won't happen when reusing Tor")
- return
-
-
- socks_port = localcommand.local_command('/gettorsocks')
-
- # Don't worry, this request isn't meant to go through,
- # but if it did it would be through Tor
-
- try:
- leak_result: str = do_get_request(
- 'https://example.com/notvalidpage',
- port=socks_port, ignoreAPI=True).lower()
- except AttributeError:
- leak_result = ""
- except Exception as e:
- logger.warn(str(e))
- try:
- if 'example' in leak_result:
- logger.error('Tor was able to request a clearnet site')
- raise ValueError('Tor was able to request a clearnet site')
- except TypeError:
- pass
diff --git a/src/runtests/housekeeping.py b/src/runtests/housekeeping.py
deleted file mode 100644
index ccc46b9f..00000000
--- a/src/runtests/housekeeping.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-
-from gevent import sleep
-
-from onionrblocks import insert
-import logger
-from coredb.blockmetadb import get_block_list
-from onionrutils import epoch
-
-
-def test_inserted_housekeeping(testmanager):
- """Tests that inserted blocks are proprely deleted"""
- bl = insert('testdata', expire=12)
- wait_seconds = 132 # Wait two minutes plus expire time
- count = 0
- if bl in get_block_list():
- while count < wait_seconds:
- if bl in get_block_list():
- sleep(0.8)
- count += 1
- else:
- return
- raise ValueError('Inserted block with expiry not erased')
- else:
- raise ValueError('Inserted block in expiry test not present in list')
diff --git a/src/runtests/inserttest.py b/src/runtests/inserttest.py
deleted file mode 100644
index 12b78558..00000000
--- a/src/runtests/inserttest.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import os
-import time
-
-import onionrblocks
-import logger
-import coredb
-
-def _check_remote_node(testmanager):
- return
-
-def insert_bin_test(testmanager):
- data = os.urandom(32)
- b_hash = onionrblocks.insert(data)
- time.sleep(0.3)
- if b_hash not in testmanager._too_many.get_by_string("PublicAPI").hideBlocks:
- raise ValueError("Block not hidden")
-
- if b_hash not in coredb.blockmetadb.get_block_list():
- logger.error(str(b_hash) + 'is not in bl')
- raise ValueError
diff --git a/src/runtests/sneakernettest.py b/src/runtests/sneakernettest.py
deleted file mode 100644
index ac48ad30..00000000
--- a/src/runtests/sneakernettest.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import os
-from shutil import move
-
-from onionrblocks import insert
-from onionrstorage import deleteBlock
-from onionrcommands.exportblocks import export_block
-from filepaths import export_location, block_data_location, data_nonce_file
-from etc.onionrvalues import BLOCK_EXPORT_FILE_EXT
-from onionrstorage.removeblock import remove_block
-from onionrstorage import deleteBlock
-from coredb.blockmetadb import get_block_list
-from utils import bettersleep
-from gevent import sleep
-
-def test_sneakernet_import(test_manager):
- in_db = lambda b: b in get_block_list()
- bl = insert(os.urandom(10))
- assert in_db(bl)
- export_block(bl)
- assert os.path.exists(export_location + bl + BLOCK_EXPORT_FILE_EXT)
- remove_block(bl)
- deleteBlock(bl)
- assert not in_db(bl)
- os.remove(data_nonce_file)
- move(export_location + bl + BLOCK_EXPORT_FILE_EXT, block_data_location)
- sleep(1)
- assert in_db(bl)
diff --git a/src/runtests/stresstest.py b/src/runtests/stresstest.py
deleted file mode 100644
index 35a9967c..00000000
--- a/src/runtests/stresstest.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import os
-
-import onionrblocks
-import logger
-import coredb
-from onionrutils import epoch
-
-def stress_test_block_insert(testmanager):
- return
- start = epoch.get_epoch()
- count = 100
- max_insert_speed = 120
- for x in range(count): onionrblocks.insert(os.urandom(32))
- speed = epoch.get_epoch() - start
- if speed < max_insert_speed:
- raise ValueError(f'{count} blocks inserted too fast, {max_insert_speed}, got {speed}')
- logger.info(f'runtest stress block insertion: {count} blocks inserted in {speed}s')
diff --git a/src/sneakernet/__init__.py b/src/sneakernet/__init__.py
deleted file mode 100644
index 6b4002a8..00000000
--- a/src/sneakernet/__init__.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Detect new block files in a given directory
-"""
-import os
-
-from watchdog.observers import Observer
-from watchdog.events import FileSystemEventHandler
-
-import config
-from filepaths import block_data_location
-from etc.onionrvalues import BLOCK_EXPORT_FILE_EXT
-from onionrblocks.blockimporter import import_block_from_data
-import onionrexceptions
-"""
- 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 .
-"""
-
-watch_paths = config.get('transports.sneakernet.paths', list([]))
-if block_data_location not in watch_paths:
- watch_paths.append(block_data_location)
-
-
-class _Importer(FileSystemEventHandler):
- @staticmethod
- def on_created(event):
- if not event.src_path.endswith(BLOCK_EXPORT_FILE_EXT):
- return
- try:
- with open(event.src_path, 'rb') as block_file:
- block_data = block_file.read()
- except FileNotFoundError:
- return
- os.remove(event.src_path)
- try:
- import_block_from_data(block_data)
- except( # noqa
- onionrexceptions.DataExists,
- onionrexceptions.BlockMetaEntryExists,
- onionrexceptions.InvalidMetadata) as _:
- return
- if block_data_location in event.src_path:
- try:
- os.remove(event.src_path)
- except FileNotFoundError:
- pass
-
-
-def sneakernet_import_thread():
- """Add block data dir & confed paths to fs observer to watch for new bls"""
- observer = Observer()
- for path in watch_paths:
- observer.schedule(_Importer(), path, recursive=True)
- observer.start()
- while observer.is_alive():
- # call import func with timeout
- observer.join(60)
diff --git a/static-data/default-plugins/circles/flowapi.py b/static-data/default-plugins/circles/flowapi.py
deleted file mode 100755
index 30668e97..00000000
--- a/static-data/default-plugins/circles/flowapi.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-This file primarily serves to allow specific fetching of circles board messages
-"""
-import operator
-import os
-
-import ujson as json
-
-from flask import Response, Blueprint
-from flask import send_from_directory
-from deadsimplekv import DeadSimpleKV
-
-from utils import identifyhome
-"""
- 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 .
-"""
-
-flask_blueprint = Blueprint('circles', __name__)
-
-root = os.path.dirname(os.path.realpath(__file__))
-
-
-with open(
- os.path.dirname(
- os.path.realpath(__file__)) + '/info.json', 'r') as info_file:
- data = info_file.read().strip()
- version = json.loads(data)['version']
-
-BOARD_CACHE_FILE = identifyhome.identify_home() + '/board-index.cache.json'
-
-read_only_cache = DeadSimpleKV(
- BOARD_CACHE_FILE,
- flush_on_exit=False,
- refresh_seconds=30)
-
-@flask_blueprint.route('/board/', endpoint='circlesstatic')
-def load_mail(path):
- return send_from_directory(root + '/web/', path)
-
-
-@flask_blueprint.route('/board/', endpoint='circlesindex')
-def load_mail_index():
- return send_from_directory(root + '/web/', 'index.html')
-
-
-@flask_blueprint.route('/circles/getpostsbyboard/')
-def get_post_by_board(board):
- board_cache = DeadSimpleKV(
- BOARD_CACHE_FILE,
- flush_on_exit=False)
- board_cache.refresh()
- posts = board_cache.get(board)
- if posts is None:
- posts = ''
- else:
- posts = ','.join(posts)
- return Response(posts)
-
-
-@flask_blueprint.route('/circles/getpostsbyboard//')
-def get_post_by_board_with_offset(board, offset):
- offset = int(offset)
- OFFSET_COUNT = 10
- board_cache = DeadSimpleKV(
- BOARD_CACHE_FILE,
- flush_on_exit=False)
- board_cache.refresh()
- posts = board_cache.get(board)
- if posts is None:
- posts = ''
- else:
- posts.reverse()
- posts = ','.join(posts[offset:offset + OFFSET_COUNT])
- return Response(posts)
-
-
-@flask_blueprint.route('/circles/version')
-def get_version():
- return Response(version)
-
-
-@flask_blueprint.route('/circles/removefromcache//',
- methods=['POST'])
-def remove_from_cache(board, name):
- board_cache = DeadSimpleKV(BOARD_CACHE_FILE,
- flush_on_exit=False)
- board_cache.refresh()
- posts = board_cache.get(board)
- try:
- posts.remove(name)
- except ValueError:
- pass
- board_cache.put(board, posts)
- return Response('success')
-
-
-@flask_blueprint.route('/circles/getpopular/')
-def get_popular(count):
- read_only_cache.refresh()
- boards = json.loads(read_only_cache.get_raw_json())
- for board in boards:
- boards[board] = len(boards[board])
-
-
- top_boards = sorted(boards.items(), key=operator.itemgetter(1), reverse=True)[:int(count)]
-
- only_board_names = []
- for b in top_boards:
- only_board_names.append(b[0])
-
- return Response(','.join(only_board_names), content_type='text/csv')
diff --git a/static-data/default-plugins/circles/info.json b/static-data/default-plugins/circles/info.json
deleted file mode 100755
index 9e140e29..00000000
--- a/static-data/default-plugins/circles/info.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "name": "circles",
- "version": "1.0.0",
- "author": "onionr"
-}
\ No newline at end of file
diff --git a/static-data/default-plugins/circles/main.py b/static-data/default-plugins/circles/main.py
deleted file mode 100755
index 51e7815a..00000000
--- a/static-data/default-plugins/circles/main.py
+++ /dev/null
@@ -1,176 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-This default plugin handles "flow" messages
-(global chatroom style communication)
-"""
-import sys
-import os
-import deadsimplekv as simplekv
-from utils import identifyhome, reconstructhash
-from coredb import blockmetadb
-import threading
-import time
-import locale
-from onionrblocks.onionrblockapi import Block
-import logger
-import onionrblocks
-from onionrutils import escapeansi, epoch, bytesconverter
-
-locale.setlocale(locale.LC_ALL, '')
-sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
-# import after path insert
-import flowapi # noqa
-"""
- 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 .
-"""
-
-flask_blueprint = flowapi.flask_blueprint
-security_whitelist = ['circles.circlesstatic', 'circles.circlesindex']
-
-plugin_name = 'circles'
-PLUGIN_VERSION = '0.1.0'
-
-EXPIRE_TIME = 43200
-
-class OnionrFlow:
- def __init__(self):
- self.alreadyOutputed = []
- self.flowRunning = False
- self.channel = ""
- return
-
- def start(self):
- logger.warn(
- "Please note: everything said here is public, " +
- "even if a random channel name is used.", terminal=True)
- message = ""
- self.flowRunning = True
- try:
- self.channel = logger.readline(
- "Enter a channel name or none for default:").strip()
- except (KeyboardInterrupt, EOFError):
- self.flowRunning = False
- newThread = threading.Thread(target=self.showOutput, daemon=True)
- newThread.start()
- while self.flowRunning:
- if self.channel == "":
- self.channel = "global"
- try:
- message = logger.readline(f'\nInsert message into {plugin_name}:').strip().replace(
- '\n', '\\n').replace('\r', '\\r')
- except EOFError:
- pass
- except KeyboardInterrupt:
- self.flowRunning = False
- else:
- if message == "q":
- self.flowRunning = False
- expireTime = epoch.get_epoch() + EXPIRE_TIME
- if len(message) > 0:
- logger.info('Inserting message as block...', terminal=True)
- onionrblocks.insert(message, header='brd',
- expire=expireTime,
- meta = {
- 'ch': self.channel})
-
- logger.info(f"{plugin_name} is exiting, goodbye", terminal=True)
- return
-
- def showOutput(self):
- while isinstance(self.channel, type(None)) and self.flowRunning:
- time.sleep(1)
- try:
- while self.flowRunning:
- for block in blockmetadb.get_blocks_by_type('brd'):
- if block in self.alreadyOutputed:
- continue
- block = Block(block)
- b_hash = bytesconverter.bytes_to_str(block.getHash())
- if block.getMetadata('ch') != self.channel:
- continue
- if not self.flowRunning:
- break
- logger.info('\n------------------------',
- prompt=False, terminal=True)
- content = block.getContent()
- # Escape new lines, remove trailing whitespace, and escape ansi sequences
- content = escapeansi.escape_ANSI(content.replace(
- b'\n', b'\\n').replace(b'\r', b'\\r').strip().decode('utf-8'))
- logger.info(block.getDate().strftime(
- "%m/%d %H:%M") + ' - ' +
- logger.colors.reset + content,
- prompt=False, terminal=True)
- self.alreadyOutputed.append(b_hash)
- time.sleep(5)
- except KeyboardInterrupt:
- self.flowRunning = False
-
-
-def on_circles_cmd(api, data=None):
- OnionrFlow().start()
-
-
-def on_circlesend_cmd(api, data=None):
- err_msg = "Second arg is board name, third is quoted message"
- try:
- sys.argv[2]
- except IndexError:
- logger.error(err_msg, terminal=True)
- try:
- sys.argv[3]
- except IndexError:
- logger.error(err_msg, terminal=True)
-
- bl = onionrblocks.insert(sys.argv[3], header='brd',
- expire=(EXPIRE_TIME + epoch.get_epoch()),
- meta={'ch': sys.argv[2]})
- print(bl)
-
-
-
-def on_softreset(api, data=None):
- try:
- os.remove(identifyhome.identify_home() + '/board-index.cache.json')
- logger.info('Cleared Circles board cache')
- except FileNotFoundError:
- pass
-
-
-def on_processblocks(api, data=None):
- metadata = data['block'].bmetadata # Get the block metadata
- if data['type'] != 'brd':
- return
-
- b_hash = reconstructhash.deconstruct_hash(
- data['block'].hash) # Get the 0-truncated block hash
- board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home(
- ) + '/board-index.cache.json', flush_on_exit=False) # get the board index cache
- board_cache.refresh()
- # Validate the channel name is sane for caching
- try:
- ch = metadata['ch']
- except KeyError:
- ch = 'global'
- ch_len = len(ch)
- if ch_len == 0:
- ch = 'global'
- elif ch_len > 12:
- return
-
- existing_posts = board_cache.get(ch)
- if existing_posts is None:
- existing_posts = []
- existing_posts.append(data['block'].hash)
- board_cache.put(ch, existing_posts)
- board_cache.flush()
diff --git a/static-data/default-plugins/circles/web/autorefresh.js b/static-data/default-plugins/circles/web/autorefresh.js
deleted file mode 100644
index bb41fde1..00000000
--- a/static-data/default-plugins/circles/web/autorefresh.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- Auto refresh board posts
-
- 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 .
-*/
-var checkbox = document.getElementById('refreshCheckbox')
-function autoRefresh(){
- if (! checkbox.checked || document.hidden){return}
- getBlocks()
-}
-
-function setupInterval(){
- if (checkbox.checked){
- refreshInterval = setInterval(autoRefresh, 3000)
- autoRefresh()
- return
- }
- clearInterval(refreshInterval)
-}
-
-var refreshInterval = setInterval(autoRefresh, 3000)
-setupInterval()
-
-checkbox.onchange = function(){setupInterval}
-
-
-document.addEventListener("visibilitychange", function() {
- if (document.visibilityState === 'visible') {
- autoRefresh()
- }
- })
diff --git a/static-data/default-plugins/circles/web/board.js b/static-data/default-plugins/circles/web/board.js
deleted file mode 100755
index 8a2a3be5..00000000
--- a/static-data/default-plugins/circles/web/board.js
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- This file handles the boards/circles interface
-
- 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 .
-*/
-requested = []
-newPostForm = document.getElementById('addMsg')
-firstLoad = true
-lastLoadedBoard = 'global'
-loadingMessage = document.getElementById('loadingBoard')
-loadedAny = false
-loadingTimeout = 8000
-
-let toggleLoadingMessage = function(){
- switch (loadingMessage.style.display){
- case "inline-block":
- loadingMessage.style.display = "none"
- break;
- default:
- loadingMessage.style.display = "initial"
- break;
- }
-}
-
-fetch('/circles/version', {
- method: 'GET',
- headers: {
- "token": webpass
-}})
-.then((ver) => ver.text())
-.then(function(ver) {
- document.getElementById('circlesVersion').innerText = ver
-})
-
-function appendMessages(msg, blockHash, beforeHash, channel) {
- if (channel !== document.getElementById('feedIDInput').value) return // ignore if channel name isn't matching
- if (msg.length == 0) return // ignore empty messages
-
- var humanDate = new Date(0)
- var msgDate = msg['meta']['time']
- var feed = document.getElementById("feed")
- var beforeEl = null
-
- if (msgDate === undefined){
- msgDate = 'unknown'
- } else {
- humanDate.setUTCSeconds(msgDate)
- msgDate = humanDate.toLocaleString("en-US", {timeZone: "Etc/GMT"})
- }
-
- var el = document.createElement('div')
- el.innerText = msg['content']
-
- if (beforeHash !== null) {
- for (i = 0; i < feed.children.length; i++) {
- if (feed.children[i].getAttribute('data-bl') === beforeHash) {
- beforeEl = feed.children[i]
- }
- }
- }
-
- /* Template Test */
- // Test to see if the browser supports the HTML template element by checking
- // for the presence of the template element's content attribute.
- if ('content' in document.createElement('template')) {
-
- // Instantiate the table with the existing HTML tbody
- // and the row with the template
- var template = document.getElementById('cMsgTemplate')
-
- // Clone the new row and insert it into the table
- var clone = document.importNode(template.content, true)
- var div = clone.querySelectorAll("div")
- var identicon = clone.querySelectorAll("img")
-
- div[0].classList.add('entry')
- div[0].setAttribute('timestamp', msg['meta']['time'])
-
- div[0].setAttribute('data-bl', blockHash)
- div[2].textContent = msg['content']
- if (typeof msg['meta']['signer'] != 'undefined' && msg['meta']['signer'].length > 0){
- div[3].textContent = msg['meta']['signer'].substr(0, 5)
- setHumanReadableIDOnPost(div[3], msg['meta']['signer'])
- div[3].onclick = function(){
- navigator.clipboard.writeText(div[3].title).then(function() {
- PNotify.notice("Copied poster identity to clipboard")
- })
- }
- div[3].title = msg['meta']['signer']
- userIcon(msg['meta']['signer']).then(function(data){
- identicon[0].src = "data:image/svg+xml;base64," + data
- })
- }
- else{
- identicon[0].remove()
- }
- div[4].textContent = msgDate
-
- loadingMessage.style.display = "none"
- loadedAny = true
- if (firstLoad){
- //feed.appendChild(clone)
- feed.prepend(clone)
- firstLoad = false
- }
- else{
- if (beforeEl === null){
- feed.prepend(clone)
- }
- else{
- beforeEl.insertAdjacentElement("beforebegin", clone.children[0])
- }
-
- }
- }
-}
-
-function getBlocks(){
- var feed = document.getElementById("feed")
- var ch = document.getElementById('feedIDInput').value
- if (lastLoadedBoard !== ch){
- requested = []
-
- toggleLoadingMessage()
- loadedAny = false
-
- while (feed.firstChild) feed.removeChild(feed.firstChild); // remove all messages from feed
-
- setTimeout(function(){
- if (! loadedAny && ch == document.getElementById('feedIDInput').value){
- PNotify.notice("There are no posts for " + ch + ". You can be the first!")
- }
- }, loadingTimeout)
- }
-
- lastLoadedBoard = ch
- if (document.getElementById('none') !== null){
- document.getElementById('none').remove();
-
- }
-
- fetch('/circles/getpostsbyboard/' + ch, {
- method: 'GET',
- headers: {
- "token": webpass
- }})
- .then((resp) => resp.text())
- .then(function(feedText) {
- var blockList = feedText.split(',')
-
- for (i = 0; i < blockList.length; i++){
- blockList[i] = "0".repeat(64 - blockList[i].length) + blockList[i] // pad hash with zeroes
-
- if (! requested.includes(blockList[i])){
- if (blockList[i].length == 0) continue
- else requested.push(blockList[i])
- loadMessage(blockList[i], blockList, i, ch);
- }
- }
- sortEntries()
- })
-}
-
-function loadMessage(blockHash, blockList, count, channel){
- if (blockHash == '0000000000000000000000000000000000000000000000000000000000000000'){
- return
- }
- fetch('/getblockdata/' + blockHash, {
- method: 'GET',
- headers: {
- "token": webpass
- }}).then(function(response) {
- if (!response.ok) {
- let on404 = function() {
- if (response.status == 404){
- fetch('/circles/removefromcache/' + channel + '/' + blockHash, {
- method: 'POST',
- headers: {
- "content-type": "application/json",
- "token": webpass
- }
- })
- }
- else{
- console.log(error)
- }
- }()
- return
- }
- response.json().then(function(data){
- let before = blockList[count - 1]
- let delay = 2000
- if (typeof before == "undefined"){
- before = null
- } else {
- let existing = document.getElementsByClassName('cMsgBox')
- for (x = 0; x < existing.length; x++){
- if (existing[x].getAttribute('data-bl') === before){
- delay = 0
- }
- }
- }
- setTimeout(function(){appendMessages(data, blockHash, before, channel)}, delay)
- })
- return response;
- })
-}
-
-document.getElementById('refreshFeed').onclick = function() {
- getBlocks()
-}
-
-newPostForm.onsubmit = function(){
- var message = document.getElementById('newMsgText').value
- var channel = document.getElementById('feedIDInput').value
- var meta = {'ch': channel}
- let doSign = document.getElementById('postAnon').checked
- var postData = {'message': message, 'sign': doSign, 'type': 'brd', 'encrypt': false, 'meta': JSON.stringify(meta)}
- postData = JSON.stringify(postData)
- newPostForm.style.display = 'none'
- fetch('/insertblock', {
- method: 'POST',
- body: postData,
- headers: {
- "content-type": "application/json",
- "token": webpass
- }
- })
- .then((resp) => resp.text())
- .then(function(data) {
- newPostForm.style.display = 'block'
- if (data == 'failure due to duplicate insert'){
- PNotify.error({
- text: "This message is already queued"
- })
- return
- }
- PNotify.success({
- text: "Message queued for posting"
- })
- setTimeout(function(){getBlocks()}, 500)
- })
- return false
-}
-
-resetCirclePickers = function(){
- document.getElementById('recommendedBoards').value = ""
- document.getElementById('popularBoards').value = ""
-}
-
-document.getElementById('feedIDInput').onchange = resetCirclePickers
-
diff --git a/static-data/default-plugins/circles/web/default-circle-picker.js b/static-data/default-plugins/circles/web/default-circle-picker.js
deleted file mode 100644
index 4b6e29c2..00000000
--- a/static-data/default-plugins/circles/web/default-circle-picker.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- Handle default board picker
-
- 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 .
-*/
-
-recommendedIDs = document.getElementById('recommendedBoards')
-
-recommendedIDs.onchange = function(){
- document.getElementById('feedIDInput').value = recommendedIDs.value
- getBlocks()
- resetCirclePickers()
-}
\ No newline at end of file
diff --git a/static-data/default-plugins/circles/web/detect-plaintext-storage.js b/static-data/default-plugins/circles/web/detect-plaintext-storage.js
deleted file mode 100644
index de16f57f..00000000
--- a/static-data/default-plugins/circles/web/detect-plaintext-storage.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- detect for Circles if plaintext insert/storage is enabled
-
- 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 .
-*/
-plaintext_enabled = null
-
-fetch('/config/get/general.store_plaintext_blocks', {
- method: 'GET',
- headers: {
- "token": webpass
- }})
-.then((resp) => resp.text())
-.then(function(data) {
- plaintext_enabled = true
- if (data == "false"){
- plaintext_enabled = false
- PNotify.error({
- text: "Plaintext storage is disabled. You will not be able to see new posts or make posts yourself"
- })
- }
-})
diff --git a/static-data/default-plugins/circles/web/index.html b/static-data/default-plugins/circles/web/index.html
deleted file mode 100755
index 2b4b7a52..00000000
--- a/static-data/default-plugins/circles/web/index.html
+++ /dev/null
@@ -1,196 +0,0 @@
-
-
-
-
-
-
-
-
- Circles
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Note: All posts in Circles are publicly accessible.
-
-
-
-
-
-
-
-
-
-
-
- None yet, try refreshing 😃
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Message
-
-
-
-
- Date
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/static-data/default-plugins/circles/web/popular.js b/static-data/default-plugins/circles/web/popular.js
deleted file mode 100644
index 9fffb301..00000000
--- a/static-data/default-plugins/circles/web/popular.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- Load popular boards and show them in the UI. Handle selections of popular boards.
-
- 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 .
-*/
-
-
-fetch('/circles/getpopular/8', {
- method: 'GET',
- headers: {
- "token": webpass
-}})
-.then((popular) => popular.text())
-.then(function(popular) {
- var popularSelect = document.getElementById('popularBoards')
- let boards = popular.split(',')
- for (board of boards){
- let newOption = document.createElement('option')
- if (board == ""){continue}
- newOption.value = board
- newOption.innerText = board.charAt(0).toUpperCase() + board.slice(1)
- console.debug(board)
- popularSelect.appendChild(newOption)
- }
-})
-
-document.getElementById('popularBoards').onchange = function(){
- document.getElementById('feedIDInput').value = document.getElementById('popularBoards').value
- getBlocks()
- resetCirclePickers()
-}
-
diff --git a/static-data/default-plugins/circles/web/sethumanreadable.js b/static-data/default-plugins/circles/web/sethumanreadable.js
deleted file mode 100644
index 0d8f6eee..00000000
--- a/static-data/default-plugins/circles/web/sethumanreadable.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- Set human readable public keys onto post author elements
-
- 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 .
-*/
-humanReadableKeys = {}
-
-function setHumanReadableIDOnPost(el, key){
- if (typeof humanReadableKeys[key] == "undefined"){
- fetch('/getHumanReadable/' + key, {
- method: 'GET',
- headers: {
- "token": webpass
- }})
- .then((resp) => resp.text()) // Transform the data into json
- .then(function(data) {
- if (data.includes('HTML')){
- return
- }
- humanReadableKeys[key] = data
- setHumanReadableIDOnPost(el, key)
- })
- return
- }
- el.innerText = humanReadableKeys[key].split('-').slice(0, 3).join(' ')
-}
\ No newline at end of file
diff --git a/static-data/default-plugins/circles/web/sort-posts.js b/static-data/default-plugins/circles/web/sort-posts.js
deleted file mode 100644
index 59b9f880..00000000
--- a/static-data/default-plugins/circles/web/sort-posts.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- Sort post entries
-
- 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 .
-*/
-
-function sortEntries() {
- var entries = document.getElementsByClassName('entry')
-
- if (entries.length > 1) {
- const sortBy = 'timestamp'
- const parent = entries[0].parentNode
-
- const sorted = Array.from(entries).sort((a, b) => b.getAttribute(sortBy) - a.getAttribute(sortBy))
- sorted.forEach(element => parent.appendChild(element))
- }
-}
diff --git a/static-data/default-plugins/circles/web/theme.css b/static-data/default-plugins/circles/web/theme.css
deleted file mode 100755
index fa7ebd7c..00000000
--- a/static-data/default-plugins/circles/web/theme.css
+++ /dev/null
@@ -1,12 +0,0 @@
-
-.cMsg{
- word-wrap:break-word;
- word-break:break-word;
- white-space: pre-wrap;
- overflow: hidden;
-}
-
-body{
- background-color: #212224;
- color: white;
-}
diff --git a/static-data/default-plugins/debuginfo/debugapi.py b/static-data/default-plugins/debuginfo/debugapi.py
deleted file mode 100755
index d3b06ce5..00000000
--- a/static-data/default-plugins/debuginfo/debugapi.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-This file primarily serves to allow specific fetching of circles board messages
-"""
-from flask import Response, Blueprint, g
-
-from deadsimplekv import DeadSimpleKV
-
-"""
- 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 .
-"""
-
-flask_blueprint = Blueprint('debugAPI', __name__)
-
-
-@flask_blueprint.route('/debug/dump_shared_state')
-def get_shared_state() -> Response:
- """Return somewhat human-readable dump of shared toomanyobjects."""
- resp = ""
- for i in g.too_many.objects.keys:
- resp += i + dir(g.too_many.objects.keys[i]) + "\n"
- return Response(resp)
-
-
-@flask_blueprint.route('/debug/dump_shared_vars')
-def get_shared_vars() -> Response:
- """Return somewhat human-readable dump of pseudo globals (DeadSimpleKV)."""
- kv: DeadSimpleKV = g.too_many.get(DeadSimpleKV)
- resp = ""
- for i in kv.keys:
- resp += i + dir(g.too_many.objects.keys[i]) + "\n"
- return Response(resp)
-
diff --git a/static-data/default-plugins/debuginfo/info.json b/static-data/default-plugins/debuginfo/info.json
deleted file mode 100755
index 037c2854..00000000
--- a/static-data/default-plugins/debuginfo/info.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "name": "debug",
- "version": "0.0.0",
- "author": "onionr"
-}
\ No newline at end of file
diff --git a/static-data/default-plugins/debuginfo/main.py b/static-data/default-plugins/debuginfo/main.py
deleted file mode 100755
index 22eb4dd2..00000000
--- a/static-data/default-plugins/debuginfo/main.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Client HTTP API debug endpoints
-"""
-import sys
-import os
-import locale
-
-locale.setlocale(locale.LC_ALL, '')
-sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
-# import after path insert
-import debugapi # noqa
-"""
- 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 .
-"""
-
-flask_blueprint = debugapi.flask_blueprint
-
-plugin_name = 'debuginfo'
-PLUGIN_VERSION = '0.0.0'
diff --git a/static-data/default-plugins/encrypt/info.json b/static-data/default-plugins/encrypt/info.json
deleted file mode 100755
index d675197a..00000000
--- a/static-data/default-plugins/encrypt/info.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name" : "encrypt",
- "version" : "1.0",
- "author" : "onionr"
-}
diff --git a/static-data/default-plugins/encrypt/main.py b/static-data/default-plugins/encrypt/main.py
deleted file mode 100755
index feed4b03..00000000
--- a/static-data/default-plugins/encrypt/main.py
+++ /dev/null
@@ -1,130 +0,0 @@
-'''
- Onionr - Private P2P Communication
-
- This default plugin allows users to encrypt/decrypt messages without using blocks
-'''
-'''
- 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 .
-'''
-
-# Imports some useful libraries
-import logger, config, threading, time, datetime, sys
-
-import ujson as json
-from nacl.exceptions import TypeError as NaclTypeError
-
-from onionrutils import stringvalidators, bytesconverter
-from onionrcrypto import encryption, keypair, signing, getourkeypair
-import onionrexceptions, onionrusers
-
-import locale
-locale.setlocale(locale.LC_ALL, '')
-
-import binascii
-
-plugin_name = 'encrypt'
-
-class PlainEncryption:
- def __init__(self, api):
- self.api = api
- return
- def encrypt(self):
- # peer, data
- plaintext = ""
- encrypted = ""
- # detect if signing is enabled
- sign = True
- try:
- if sys.argv[3].lower() == 'false':
- sign = False
- except IndexError:
- pass
-
- try:
- if not stringvalidators.validate_pub_key(sys.argv[2]):
- raise onionrexceptions.InvalidPubkey
- except (ValueError, IndexError) as e:
- logger.error("Peer public key not specified", terminal=True)
- except onionrexceptions.InvalidPubkey:
- logger.error("Invalid public key", terminal=True)
- else:
- pubkey = sys.argv[2]
- # Encrypt if public key is valid
- logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
- try:
- for line in sys.stdin:
- if line == '-q\n':
- break
- plaintext += line
- except KeyboardInterrupt:
- sys.exit(1)
- # Build Message to encrypt
- data = {}
- myPub = keypair[0]
- if sign:
- data['sig'] = signing.ed_sign(plaintext, key=keypair[1], encodeResult=True)
- data['sig'] = bytesconverter.bytes_to_str(data['sig'])
- data['signer'] = myPub
- data['data'] = plaintext
- data = json.dumps(data)
- plaintext = data
- encrypted = encryption.pub_key_encrypt(plaintext, pubkey, encodedData=True)
- encrypted = bytesconverter.bytes_to_str(encrypted)
- logger.info('Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,), terminal=True)
-
- def decrypt(self):
- plaintext = ""
- data = ""
- logger.info("Please enter your message (ctrl-d or -q to stop):", terminal=True)
- keypair = getourkeypair.get_keypair()
- try:
- for line in sys.stdin:
- if line == '-q\n':
- break
- data += line
- except KeyboardInterrupt:
- sys.exit(1)
- if len(data) <= 1:
- return
- encrypted = data.replace('ONIONR ENCRYPTED DATA ', '').replace('END ENCRYPTED DATA', '')
- myPub = keypair[0]
- decrypted = encryption.pub_key_decrypt(encrypted, privkey=keypair[1], encodedData=True)
- if decrypted == False:
- logger.error("Decryption failed", terminal=True)
- else:
- data = json.loads(decrypted)
- logger.info('Decrypted Message: \n\n%s' % data['data'], terminal=True)
- try:
- logger.info("Signing public key: %s" % (data['signer'],), terminal=True)
- if not signing.ed_verify(data['data'], data['signer'], data['sig']): raise ValueError
- except (ValueError, KeyError) as e:
- logger.warn("WARNING: THIS MESSAGE HAS A MISSING OR INVALID SIGNATURE", terminal=True)
- else:
- logger.info("Message has good signature.", terminal=True)
- return
-
-def on_decrypt_cmd(api, data=None):
- try:
- PlainEncryption(api).decrypt()
- except binascii.Error:
- logger.error("Invalid ciphertext padding", terminal=True)
- except NaclTypeError:
- logger.error("Ciphertext too short.", terminal=True)
-
-def on_encrypt_cmd(api, data=None):
- PlainEncryption(api).encrypt()
-
-on_encrypt_cmd.onionr_help = """encrypt \nEncrypt text data to an Onionr user key. Similar to PGP"""
-on_decrypt_cmd.onionr_help = """decrypt\nDecrypt text data with your Onionr key. Similar to PGP"""
-ONIONR_COMMANDS = ['encrypt', 'decrypt']
\ No newline at end of file
diff --git a/static-data/default-plugins/pms/info.json b/static-data/default-plugins/pms/info.json
deleted file mode 100755
index 72ce2b39..00000000
--- a/static-data/default-plugins/pms/info.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name" : "pms",
- "version" : "0.1.2",
- "author" : "onionr"
-}
diff --git a/static-data/default-plugins/pms/loadinbox.py b/static-data/default-plugins/pms/loadinbox.py
deleted file mode 100755
index 6a215f71..00000000
--- a/static-data/default-plugins/pms/loadinbox.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Load the user's inbox and return it as a list
-"""
-from onionrblocks import onionrblockapi
-from coredb import blockmetadb
-from utils import reconstructhash, identifyhome
-import deadsimplekv as simplekv
-"""
- 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 .
-"""
-
-inbox_cache = {}
-def load_inbox():
- inbox_list = []
- deleted = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/mailcache.dat').get('deleted_mail')
- if deleted is None:
- deleted = []
-
- for blockHash in blockmetadb.get_blocks_by_type('pm'):
- if blockHash in deleted:
- continue
- if blockHash in inbox_cache:
- inbox_list.append(blockHash)
- continue
- block = onionrblockapi.Block(blockHash)
- block.decrypt()
- if block.decrypted and reconstructhash.deconstruct_hash(blockHash):
- inbox_cache[blockHash] = True
- inbox_list.append(blockHash)
- return inbox_list
diff --git a/static-data/default-plugins/pms/mailapi.py b/static-data/default-plugins/pms/mailapi.py
deleted file mode 100755
index 53783a09..00000000
--- a/static-data/default-plugins/pms/mailapi.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-HTTP endpoints for mail plugin
-"""
-import sys
-import os
-
-import ujson as json
-from flask import Response, request, redirect, Blueprint, abort
-from flask import send_from_directory
-import deadsimplekv as simplekv
-
-from httpapi.sse.wrapper import SSEWrapper
-from onionrusers import contactmanager
-from onionrutils import stringvalidators
-from utils import reconstructhash, identifyhome
-from utils.bettersleep import better_sleep as sleep
-
-sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
-import loadinbox
-import sentboxdb
-"""
- 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 .
-"""
-flask_blueprint = Blueprint('mail', __name__)
-kv = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/mailcache.dat')
-root = os.path.dirname(os.path.realpath(__file__))
-
-sse_wrapper = SSEWrapper()
-
-@flask_blueprint.route('/mail/', endpoint='mailstatic')
-def load_mail(path):
- return send_from_directory(root + '/web/', path)
-
-
-@flask_blueprint.route('/mail/', endpoint='mailindex')
-def load_mail_index():
- return send_from_directory(root + '/web/', 'index.html')
-
-
-@flask_blueprint.route('/mail/ping')
-def mail_ping():
- return 'pong!'
-
-@flask_blueprint.route('/mail/deletemsg/', methods=['POST'])
-def mail_delete(block):
- if not stringvalidators.validate_hash(block):
- abort(504)
- block = reconstructhash.deconstruct_hash(block)
- existing = kv.get('deleted_mail')
- if existing is None:
- existing = []
- if block not in existing:
- existing.append(block)
- kv.put('deleted_mail', existing)
- kv.flush()
- return 'success'
-
-@flask_blueprint.route('/mail/getinbox')
-def list_inbox():
- return ','.join(loadinbox.load_inbox())
-
-
-@flask_blueprint.route('/mail/streaminbox')
-def stream_inbox():
- def _stream():
- while True:
- yield "data: " + ','.join(loadinbox.load_inbox()) + "\n\n"
- sleep(1)
- return sse_wrapper.handle_sse_request(_stream)
-
-
-@flask_blueprint.route('/mail/getsentbox')
-def list_sentbox():
- kv.refresh()
- sentbox_list = sentboxdb.SentBox().listSent()
- list_copy = list(sentbox_list)
- deleted = kv.get('deleted_mail')
- if deleted is None:
- deleted = []
- for sent in list_copy:
- if sent['hash'] in deleted:
- sentbox_list.remove(sent)
- continue
- sent['name'] = contactmanager.ContactManager(sent['peer'], saveUser=False).get_info('name')
- return json.dumps(sentbox_list)
diff --git a/static-data/default-plugins/pms/main.py b/static-data/default-plugins/pms/main.py
deleted file mode 100755
index 4d2219f2..00000000
--- a/static-data/default-plugins/pms/main.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""Onionr - Private P2P Communication.
-
-Private messages in an email like fashion
-"""
-import locale
-import sys
-import os
-
-import ujson as json
-
-from onionrusers import contactmanager
-from utils import reconstructhash
-from onionrutils import bytesconverter
-import config
-import notifier
-"""
- 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 .
-"""
-
-locale.setlocale(locale.LC_ALL, '')
-
-plugin_name = 'pms'
-PLUGIN_VERSION = '0.1.2'
-
-sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
-import sentboxdb, mailapi, loadinbox # import after path insert
-from onblacklist import on_blacklist_add
-
-flask_blueprint = mailapi.flask_blueprint
-security_whitelist = ['mail.mailstatic', 'mail.mailindex']
-
-
-def add_deleted(keyStore, b_hash):
- existing = keyStore.get('deleted_mail')
- bHash = reconstructhash.reconstruct_hash(b_hash)
- if existing is None:
- existing = []
- else:
- if bHash in existing:
- return
- keyStore.put('deleted_mail', existing.append(b_hash))
-
-
-def on_insertblock(api, data={}):
- meta = json.loads(data['meta'])
- if meta['type'] == 'pm':
- sentboxTools = sentboxdb.SentBox()
- sentboxTools.addToSent(data['hash'], data['peer'], data['content'], meta['subject'])
-
-
-def on_processblocks(api, data=None):
- if data['type'] != 'pm':
- return
- notification_func = notifier.notify
- data['block'].decrypt()
- metadata = data['block'].bmetadata
-
- signer = bytesconverter.bytes_to_str(data['block'].signer)
- user = contactmanager.ContactManager(signer, saveUser=False)
- name = user.get_info("name")
- if name != 'anonymous' and name != None:
- signer = name.title()
- else:
- signer = signer[:5]
-
-
- if data['block'].decrypted:
- config.reload()
-
- if config.get('mail.notificationSound', True):
- notification_func = notifier.notification_with_sound
- if config.get('mail.notificationSetting', True):
- if not config.get('mail.strangersNotification', True):
- if not user.isFriend():
- return
- notification_func(title="Onionr Mail - New Message", message="From: %s\n\nSubject: %s" % (signer, metadata['subject']))
diff --git a/static-data/default-plugins/pms/onblacklist.py b/static-data/default-plugins/pms/onblacklist.py
deleted file mode 100644
index 0e521967..00000000
--- a/static-data/default-plugins/pms/onblacklist.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from threading import Thread
-
-from onionrutils import localcommand
-
-
-def on_blacklist_add(api, data=None):
- blacklisted_data = data['data']
-
- def remove():
- localcommand.local_command(f'/mail/deletemsg/{blacklisted_data}', post=True)
-
- Thread(target=remove).start()
diff --git a/static-data/default-plugins/pms/sentboxdb.py b/static-data/default-plugins/pms/sentboxdb.py
deleted file mode 100755
index b5d37330..00000000
--- a/static-data/default-plugins/pms/sentboxdb.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""
- Onionr - Private P2P Communication
-
- This file handles the sentbox for the mail plugin
-"""
-import sqlite3
-import os
-from onionrutils import epoch
-from utils import identifyhome, reconstructhash
-"""
- 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 .
-"""
-
-
-class SentBox:
- def __init__(self):
- self.dbLocation = identifyhome.identify_home() + '/sentbox.db'
- if not os.path.exists(self.dbLocation):
- self.createDB()
- return
-
- def connect(self):
- self.conn = sqlite3.connect(self.dbLocation, timeout=30)
- self.cursor = self.conn.cursor()
-
- def close(self):
- self.conn.close()
-
- def createDB(self):
- conn = sqlite3.connect(self.dbLocation)
- cursor = conn.cursor()
- cursor.execute("""CREATE TABLE sent(
- hash id not null,
- peer text not null,
- message text not null,
- subject text not null,
- date int not null
- );
- """)
- conn.commit()
- conn.close()
- return
-
- def listSent(self):
- self.connect()
- retData = []
- for entry in self.cursor.execute('SELECT * FROM sent;'):
- retData.append({'hash': entry[0], 'peer': entry[1], 'message': entry[2], 'subject': entry[3], 'date': entry[4]})
- self.close()
- return retData
-
- def addToSent(self, blockID, peer, message, subject=''):
- blockID = reconstructhash.deconstruct_hash(blockID)
- self.connect()
- args = (blockID, peer, message, subject, epoch.get_epoch())
- self.cursor.execute('INSERT INTO sent VALUES(?, ?, ?, ?, ?)', args)
- self.conn.commit()
- self.close()
- return
-
- def removeSent(self, blockID):
- blockID = reconstructhash.deconstruct_hash(blockID)
- self.connect()
- args = (blockID,)
- self.cursor.execute('DELETE FROM sent where hash=?', args)
- self.conn.commit()
- self.close()
- return
diff --git a/static-data/default-plugins/pms/web/closesettings.js b/static-data/default-plugins/pms/web/closesettings.js
deleted file mode 100644
index 5f91cc5b..00000000
--- a/static-data/default-plugins/pms/web/closesettings.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- Onionr - Private P2P Communication
-
- Settings modal closing
-
- 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 .
-*/
-
-document.getElementById('closeSettingsModalButton').onclick = function(){
- document.getElementById('settingsModal').classList.remove('is-active')
- setActiveTab('inbox')
-}
-
-document.querySelector("#settingsModal .modal-background").onclick = function(){
- document.getElementById('settingsModal').classList.remove('is-active')
- setActiveTab('inbox')
-}
diff --git a/static-data/default-plugins/pms/web/index.html b/static-data/default-plugins/pms/web/index.html
deleted file mode 100755
index c838d30b..00000000
--- a/static-data/default-plugins/pms/web/index.html
+++ /dev/null
@@ -1,262 +0,0 @@
-
-
-
-
-
-
-
- Onionr Mail
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-