added config observers, delete plaintext blocks when plaintext storage is disabled

This commit is contained in:
Kevin Froman 2020-01-07 05:44:53 -06:00
parent 2e31155a5d
commit f78809fa2a
9 changed files with 156 additions and 116 deletions

View file

@ -1,9 +1,12 @@
'''
Onionr - Private P2P Communication
"""Onionr - Private P2P Communication.
This file deals with configuration management.
'''
'''
This file deals with configuration management.
"""
import os, json, logger
import filepaths
from . import onboarding
"""
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
@ -16,20 +19,14 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import os, json, logger
import filepaths
from . import onboarding
"""
_configfile = filepaths.config_file
_config = {}
def get(key, default = None, save = False):
'''
Gets the key from configuration, or returns `default`
'''
"""Gets the key from configuration, or returns `default`"""
key = str(key).split('.')
data = _config
@ -41,20 +38,24 @@ def get(key, default = None, save = False):
return default
data = data[item]
if not last in data:
if last not in data:
if save:
set(key, default, savefile = True)
return default
return data[last]
def set(key, value = None, savefile = False):
'''
Sets the key in configuration to `value`
'''
"""Sets the key in configuration to `value`"""
from . import observers
config_set_observers = {
'general.store_plaintext_blocks': [observers.delete_plaintext]
}
global _config
whole_key = key
key = str(key).split('.')
data = _config
@ -64,6 +65,11 @@ def set(key, value = None, savefile = False):
if (not item in data) or (not type(data[item]) == dict):
data[item] = dict()
data = data[item]
try:
for observer in config_set_observers[whole_key]:
observer(value)
except KeyError:
pass
if value is None:
del data[last]
@ -73,6 +79,7 @@ def set(key, value = None, savefile = False):
if savefile:
save()
def is_set(key):
key = str(key).split('.')
data = _config
@ -89,18 +96,16 @@ def is_set(key):
return True
def check():
'''
Checks if the configuration file exists, creates it if not
'''
"""Checks if the configuration file exists, creates it if not"""
if not os.path.exists(os.path.dirname(get_config_file())):
os.makedirs(os.path.dirname(get_config_file()))
def save():
'''
Saves the configuration data to the configuration file
'''
"""Saves the configuration data to the configuration file"""
check()
try:
@ -109,10 +114,9 @@ def save():
except json.JSONDecodeError:
logger.warn('Failed to write to configuration file.')
def reload():
'''
Reloads the configuration data in memory from the file
'''
"""Reloads the configuration data in memory from the file"""
check()
try:
with open(get_config_file(), 'r', encoding="utf8") as configfile:
@ -121,28 +125,24 @@ def reload():
pass
#logger.debug('Failed to parse configuration file.')
def get_config():
'''
Gets the entire configuration as an array
'''
"""Gets the entire configuration as an array"""
return _config
def set_config(config):
'''
Sets the configuration to the array in arguments
'''
"""Sets the configuration to the array in arguments"""
global _config
_config = config
def get_config_file():
'''
Returns the absolute path to the configuration file
'''
"""Returns the absolute path to the configuration file"""
return _configfile
def set_config_file(configfile):
'''
Sets the path to the configuration file
'''
"""Sets the path to the configuration file."""
global _configfile
_configfile = os.abs.abspath(configfile)

View file

@ -0,0 +1,2 @@
from . import plaintextdelete
delete_plaintext = plaintextdelete.delete_plaintext

View file

@ -0,0 +1,36 @@
"""Onionr - Private P2P Communication.
Delete plaintext blocks, used when plaintext is disabled in config
"""
from onionrblocks import onionrblockapi
from coredb import blockmetadb
from onionrstorage.removeblock import remove_block
import onionrstorage
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
def delete_plaintext(dont_delete: bool):
"""Delete, but do not blacklist, plaintext blocks."""
if dont_delete:
return
block_list = blockmetadb.get_block_list()
for block in block_list:
block = onionrblockapi.Block(hash=block)
if not block.isEncrypted:
remove_block(block.hash)
onionrstorage.deleteBlock(block.hash)

View file

@ -1,9 +1,14 @@
'''
"""
Onionr - Private P2P Communication
This module works 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
@ -16,19 +21,16 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import sqlite3
from etc import onionrvalues
from . import expiredblocks, updateblockinfo, add
from .. import dbfiles
"""
update_block_info = updateblockinfo.update_block_info
add_to_block_DB = add.add_to_block_DB
def get_block_list(dateRec = None, unsaved = False):
'''
"""
Get list of our blocks
'''
"""
if dateRec == None:
dateRec = 0
@ -44,10 +46,11 @@ def get_block_list(dateRec = None, unsaved = False):
conn.close()
return rows
def get_block_date(blockHash):
'''
"""
Returns the date a block was received
'''
"""
conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
c = conn.cursor()
@ -60,10 +63,11 @@ def get_block_date(blockHash):
conn.close()
return None
def get_blocks_by_type(blockType, orderDate=True):
'''
"""
Returns a list of blocks by the type
'''
"""
conn = sqlite3.connect(dbfiles.block_meta_db, timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
c = conn.cursor()
@ -80,4 +84,5 @@ def get_blocks_by_type(blockType, orderDate=True):
for i in row:
rows.append(i)
conn.close()
return rows
return rows

View file

@ -95,7 +95,7 @@ class Block:
# 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
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
@ -187,7 +187,7 @@ class Block:
self.date = datetime.datetime.fromtimestamp(self.getDate())
self.valid = True
if self.autoDecrypt:
self.decrypt()
@ -462,61 +462,6 @@ class Block:
return self
# static functions
def getBlocks(type = None, signer = None, signed = None, reverse = False, limit = None):
'''
Returns a list of Block objects based on supplied filters
Inputs:
- type (str): filters by block type
- signer (str/list): filters by signer (one in the list has to be a signer)
- signed (bool): filters out by whether or not the block is signed
- reverse (bool): reverses the list if True
Outputs:
- (list): a list of Block objects that match the input
'''
try:
relevant_blocks = list()
blocks = (blockmetadb.get_block_list() if type is None else blockmetadb.get_blocks_by_type(type))
for block in blocks:
if Block.exists(block):
block = Block(block)
relevant = True
if (not signed is None) and (block.isSigned() != bool(signed)):
relevant = False
if not signer is None:
if isinstance(signer, (str,)):
signer = [signer]
if isinstance(signer, (bytes,)):
signer = [signer.decode()]
isSigner = False
for key in signer:
if block.isSigner(key):
isSigner = True
break
if not isSigner:
relevant = False
if relevant and (limit is None or len(relevant_Blocks) <= int(limit)):
relevant_blocks.append(block)
if bool(reverse):
relevant_blocks.reverse()
return relevant_blocks
except Exception as e:
logger.debug('Failed to get blocks.', error = e)
return list()
def exists(bHash):
'''
Checks if a block is saved to file or not
@ -536,7 +481,7 @@ class Block:
if isinstance(bHash, Block):
bHash = bHash.getHash()
ret = isinstance(onionrstorage.getData(bHash), type(None))
return not ret

View file

@ -19,7 +19,6 @@
'''
import os
from . import identifyhome
from onionrsetup import dbcreator
import filepaths
home = identifyhome.identify_home()
@ -31,6 +30,8 @@ def create_dirs():
if not os.path.exists(path):
os.mkdir(path)
from onionrsetup import dbcreator
for db in dbcreator.create_funcs:
try:
db()