Compare commits
8 Commits
84e16e5b82
...
8e730cef98
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8e730cef98 | ||
![]() |
738fa0c361 | ||
![]() |
b3eb0caffd | ||
![]() |
446662cc60 | ||
![]() |
180116a55d | ||
![]() |
bc3d6571bb | ||
![]() |
30d50ceacf | ||
![]() |
e84ad93de7 |
@ -1,124 +0,0 @@
|
|||||||
# Onionr HTTP API
|
|
||||||
|
|
||||||
All HTTP interfaces in the Onionr reference client use the [Flask](http://flask.pocoo.org/) web framework with the [gevent](http://www.gevent.org/) WSGI server.
|
|
||||||
|
|
||||||
## Client & Public difference
|
|
||||||
|
|
||||||
The client API server is a locked down interface intended for authenticated local communication.
|
|
||||||
|
|
||||||
The public API server is available only remotely from Tor & I2P. It is the interface in which peers use to communicate with one another.
|
|
||||||
|
|
||||||
# Client API
|
|
||||||
|
|
||||||
Please note: endpoints that simply provide static web app files are not documented here.
|
|
||||||
|
|
||||||
* /serviceactive/pubkey
|
|
||||||
- Methods: GET
|
|
||||||
- Returns true or false based on if a given public key has an active direct connection service.
|
|
||||||
* /queueResponseAdd/key (DEPRECATED)
|
|
||||||
- Methods: POST
|
|
||||||
- Accepts form key 'data' to set queue response information from a plugin
|
|
||||||
- Returns success if no error occurs
|
|
||||||
* /queueResponse/key (DEPRECATED)
|
|
||||||
- Methods: GET
|
|
||||||
- Returns the queue response for a key. Returns failure with a 404 code if a code is not set.
|
|
||||||
* /ping
|
|
||||||
- Methods: GET
|
|
||||||
- Returns "pong!"
|
|
||||||
* /getblocksbytype/type
|
|
||||||
- Methods: GET
|
|
||||||
- Returns a list of stored blocks by a given type
|
|
||||||
* /getblockbody/hash
|
|
||||||
- Methods: GET
|
|
||||||
- Returns the main data section of a block
|
|
||||||
* /getblockdata/hash
|
|
||||||
- Methods: GET
|
|
||||||
- Returns the entire data contents of a block, including metadata.
|
|
||||||
* /getblockheader/hash
|
|
||||||
- Methods: GET
|
|
||||||
- Returns the header (metadata section) of a block.
|
|
||||||
* /gethidden/
|
|
||||||
- Methods: GET
|
|
||||||
- Returns line separated list of hidden blocks
|
|
||||||
* /hitcount
|
|
||||||
- Methods: GET
|
|
||||||
- Return the amount of requests the public api server has received this session
|
|
||||||
* /lastconnect
|
|
||||||
- Methods: GET
|
|
||||||
- Returns the epoch timestamp of when the last incoming connection to the public API server was logged
|
|
||||||
* /site/hash
|
|
||||||
- Methods: GET
|
|
||||||
- Returns HTML content out of a block
|
|
||||||
* /waitforshare/hash
|
|
||||||
- Methods: POST
|
|
||||||
- Prevents the public API server from listing or sharing a block until it has been uploaded to at least 1 peer.
|
|
||||||
* /shutdown
|
|
||||||
- Methods: GET
|
|
||||||
- Shutdown Onionr. You should probably use /shutdownclean instead.
|
|
||||||
* /shutdownclean
|
|
||||||
- Methods: GET
|
|
||||||
- Tells the communicator daemon to shutdown Onionr. Slower but cleaner.
|
|
||||||
* /getstats
|
|
||||||
- Methods: GET
|
|
||||||
- Returns some JSON serialized statistics
|
|
||||||
* /getuptime
|
|
||||||
- Methods: GET
|
|
||||||
- Returns uptime in seconds
|
|
||||||
* /getActivePubkey
|
|
||||||
- Methods: GET
|
|
||||||
- Returns the current active public key in base32 format
|
|
||||||
* /getHumanReadable/pubkey
|
|
||||||
- Methods: GET
|
|
||||||
- Echos the specified public key in mnemonic format
|
|
||||||
* /insertblock
|
|
||||||
- Methods: POST
|
|
||||||
- Accepts JSON data for creating a new block. 'message' contains the block data, 'to' specifies the peer's public key to encrypt the data to, 'sign' is a boolean for signing the message.
|
|
||||||
* /torready
|
|
||||||
- Methods: POST
|
|
||||||
- Returns boolean if Tor is started or not
|
|
||||||
|
|
||||||
# Public API
|
|
||||||
|
|
||||||
v0
|
|
||||||
|
|
||||||
* /
|
|
||||||
- Methods: GET
|
|
||||||
- Returns a basic HTML informational banner describing Onionr.
|
|
||||||
* /getblocklist
|
|
||||||
- Methods: GET
|
|
||||||
- URI Parameters:
|
|
||||||
- date: unix epoch timestamp for offset
|
|
||||||
- Returns a list of block hashes stored on the node since an offset (all blocks if no timestamp is specified)
|
|
||||||
* /getdata/block-hash
|
|
||||||
- Methods: GET
|
|
||||||
- Returns data for a block based on a provided hash
|
|
||||||
* /www/file-path
|
|
||||||
- Methods: GET
|
|
||||||
- Returns file data. Intended for manually sharing file data directly from an Onionr node.
|
|
||||||
* /ping
|
|
||||||
- Methods: GET
|
|
||||||
- Returns 'pong!'
|
|
||||||
* /pex
|
|
||||||
- Methods: GET
|
|
||||||
- Returns a list of peer addresses reached within recent time
|
|
||||||
* /announce
|
|
||||||
- Methods: POST
|
|
||||||
- Accepts form data for 'node' (valid node address) and 'random' which is a nonce when hashed (blake2b_256) in the format `hash(peerAddress+serverAddress+nonce)`, begins with at least 5 zeros.
|
|
||||||
- Returns 200 with 'Success' if no error occurs. If the post is invalid, 'failure' with code 406 is returned.
|
|
||||||
* /upload
|
|
||||||
- Methods: POST
|
|
||||||
- Accepts form data for 'block' as a 'file' upload.
|
|
||||||
- Returns 200 with 'success' if no error occurs. If the block cannot be accepted, 'failure' with 400 is returned.
|
|
||||||
|
|
||||||
# Direct Connection API
|
|
||||||
|
|
||||||
These are constant endpoints available on direct connection servers. Plugin endpoints for direct connections are not documented here.
|
|
||||||
|
|
||||||
* /ping
|
|
||||||
- Methods: GET
|
|
||||||
- Returns 200 with 'pong!'
|
|
||||||
|
|
||||||
* /close
|
|
||||||
- Methods: GET
|
|
||||||
- Kills the direct connection server, destroying the onion address.
|
|
||||||
- Returns 200 with 'goodbye'
|
|
@ -2,6 +2,8 @@
|
|||||||
ORIG_ONIONR_RUN_DIR=`pwd`
|
ORIG_ONIONR_RUN_DIR=`pwd`
|
||||||
export ORIG_ONIONR_RUN_DIR
|
export ORIG_ONIONR_RUN_DIR
|
||||||
export PYTHONDONTWRITEBYTECODE=1
|
export PYTHONDONTWRITEBYTECODE=1
|
||||||
|
export PYTHONUNBUFFERED=1
|
||||||
|
export PYTHONOPTIMIZE="true"
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
cd src
|
cd src
|
||||||
./__init__.py "$@"
|
./__init__.py "$@"
|
@ -197,6 +197,10 @@ pynacl==1.5.0 \
|
|||||||
--hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
|
--hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
|
||||||
--hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
|
--hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
|
||||||
# via onionrblocks
|
# via onionrblocks
|
||||||
|
result==0.8.0 \
|
||||||
|
--hash=sha256:c48c909e92181a075ba358228a3fe161e26d205dad416ad81f27f23515a5626d \
|
||||||
|
--hash=sha256:d6a6258f32c057a4e0478999c6ce43dcadaf8ea435f58ac601ae2768f93ef243
|
||||||
|
# via -r requirements-base.in
|
||||||
ujson==5.5.0 \
|
ujson==5.5.0 \
|
||||||
--hash=sha256:0762a4fdf86e01f3f8d8b6b7158d01fdd870799ff3f402b676e358fcd879e7eb \
|
--hash=sha256:0762a4fdf86e01f3f8d8b6b7158d01fdd870799ff3f402b676e358fcd879e7eb \
|
||||||
--hash=sha256:10095160dbe6bba8059ad6677a01da251431f4c68041bf796dcac0956b34f8f7 \
|
--hash=sha256:10095160dbe6bba8059ad6677a01da251431f4c68041bf796dcac0956b34f8f7 \
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
psutil==5.9.3
|
psutil==5.9.3
|
||||||
ujson==5.5.0
|
ujson==5.5.0
|
||||||
ordered-set==4.1.0
|
ordered-set==4.1.0
|
||||||
|
result==0.8.0
|
||||||
# These two are also by Kevin
|
# These two are also by Kevin
|
||||||
filenuke==0.0.0
|
filenuke==0.0.0
|
||||||
onionrblocks==7.0.0
|
onionrblocks==7.0.0
|
@ -345,6 +345,10 @@ pytz==2022.2.1 \
|
|||||||
--hash=sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197 \
|
--hash=sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197 \
|
||||||
--hash=sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5
|
--hash=sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5
|
||||||
# via tempora
|
# via tempora
|
||||||
|
result==0.8.0 \
|
||||||
|
--hash=sha256:c48c909e92181a075ba358228a3fe161e26d205dad416ad81f27f23515a5626d \
|
||||||
|
--hash=sha256:d6a6258f32c057a4e0478999c6ce43dcadaf8ea435f58ac601ae2768f93ef243
|
||||||
|
# via -r requirements-base.in
|
||||||
secretstorage==3.3.3 \
|
secretstorage==3.3.3 \
|
||||||
--hash=sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77 \
|
--hash=sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77 \
|
||||||
--hash=sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99
|
--hash=sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99
|
||||||
|
@ -112,6 +112,7 @@ def onionr_main():
|
|||||||
|
|
||||||
Entrypoint for daemon is commands/daemonlaunch/__init__.py
|
Entrypoint for daemon is commands/daemonlaunch/__init__.py
|
||||||
"""
|
"""
|
||||||
|
events.event('beforecmdparsing', threaded=False)
|
||||||
parser.register()
|
parser.register()
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,8 +8,6 @@ if TYPE_CHECKING:
|
|||||||
from onionrplugins import onionrevents
|
from onionrplugins import onionrevents
|
||||||
from logger import log as logging
|
from logger import log as logging
|
||||||
|
|
||||||
from socks import GeneralProxyError
|
|
||||||
|
|
||||||
from ..peer import Peer
|
from ..peer import Peer
|
||||||
from ..commands import GossipCommands, command_to_byte
|
from ..commands import GossipCommands, command_to_byte
|
||||||
from ..constants import PEER_AMOUNT_TO_ASK, TRANSPORT_SIZE_BYTES
|
from ..constants import PEER_AMOUNT_TO_ASK, TRANSPORT_SIZE_BYTES
|
||||||
|
@ -30,8 +30,7 @@ def kill_daemon():
|
|||||||
os.kill(int(pid.read()), SIGTERM)
|
os.kill(int(pid.read()), SIGTERM)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logging.error("Daemon not running/pid file missing")
|
logging.error("Daemon not running/pid file missing")
|
||||||
logging.warn('Stopping the running daemon, if one exists...', timestamp=False,
|
logging.warn('Stopping the running daemon, if one exists...')
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
kill_daemon.onionr_help = "Gracefully stops the " # type: ignore
|
kill_daemon.onionr_help = "Gracefully stops the " # type: ignore
|
||||||
|
@ -17,7 +17,8 @@ GNU General Public License for more details.
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
import os, re, importlib
|
import os, re
|
||||||
|
import importlib.util
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from . import onionrevents as events
|
from . import onionrevents as events
|
||||||
|
@ -42,18 +42,22 @@ socket_file_path = identifyhome.identify_home() + 'rpc.sock'
|
|||||||
from jsonrpc import JSONRPCResponseManager, dispatcher
|
from jsonrpc import JSONRPCResponseManager, dispatcher
|
||||||
import jsonrpc
|
import jsonrpc
|
||||||
import ujson
|
import ujson
|
||||||
|
import requests_unixsocket
|
||||||
|
import requests
|
||||||
jsonrpc.manager.json = ujson
|
jsonrpc.manager.json = ujson
|
||||||
|
|
||||||
|
from onionrplugins import plugin_apis
|
||||||
|
|
||||||
# RPC modules map Onionr APIs to the RPC dispacher
|
# RPC modules map Onionr APIs to the RPC dispacher
|
||||||
from rpc import blocks, pluginrpcmethods
|
from rpc import blocks, pluginrpcmethods
|
||||||
|
|
||||||
from rpc.addmodule import add_module_to_api
|
from rpc.addmodule import add_module_to_api
|
||||||
|
|
||||||
|
|
||||||
plugin_apis['rpc.add_module_to_api'] = add_module_to_api
|
plugin_apis['rpc.add_module_to_api'] = add_module_to_api
|
||||||
|
|
||||||
class OnionrRPC(object):
|
class OnionrRPC(object):
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@cherrypy.tools.json_out()
|
|
||||||
def rpc(self):
|
def rpc(self):
|
||||||
# Dispatcher is dictionary {<method_name>: callable}
|
# Dispatcher is dictionary {<method_name>: callable}
|
||||||
data = cherrypy.request.body.read().decode('utf-8')
|
data = cherrypy.request.body.read().decode('utf-8')
|
||||||
@ -62,6 +66,20 @@ class OnionrRPC(object):
|
|||||||
return response.json
|
return response.json
|
||||||
|
|
||||||
|
|
||||||
|
def rpc_client(*args, **kwargs):
|
||||||
|
if config.get('rpc.use_sock_file', True):
|
||||||
|
session = requests_unixsocket.Session()
|
||||||
|
return session.post(
|
||||||
|
'http+unix://' + config.get('rpc.sock_file_path', socket_file_path).replace('/', '%2F') + '/rpc',
|
||||||
|
*args, **kwargs)
|
||||||
|
else:
|
||||||
|
return requests.post(
|
||||||
|
f'http://{config.get("rpc.bind_host")}:{config.get("rpc.bind_port")}/rpc',
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
|
def on_beforecmdparsing(api, data=None):
|
||||||
|
plugin_apis['rpc.rpc_client'] = rpc_client
|
||||||
|
|
||||||
def on_afterinit(api, data=None):
|
def on_afterinit(api, data=None):
|
||||||
def ping():
|
def ping():
|
||||||
return "pong"
|
return "pong"
|
||||||
|
@ -1,11 +1,52 @@
|
|||||||
import tty
|
import tty
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import ujson as json
|
||||||
|
import result
|
||||||
|
import requests
|
||||||
|
import requests_unixsocket
|
||||||
|
|
||||||
|
from logger import log as logging
|
||||||
|
import onionrplugins.pluginapis
|
||||||
|
|
||||||
def do_quit(): raise KeyboardInterrupt
|
def do_quit(): raise KeyboardInterrupt
|
||||||
|
|
||||||
|
|
||||||
|
rpc_payload = {
|
||||||
|
"method": "echo",
|
||||||
|
"params": ["example"],
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def list_idens():
|
def list_idens():
|
||||||
print('Listing identities')
|
print('Listing identities')
|
||||||
|
payload = dict(rpc_payload)
|
||||||
|
payload['method'] = 'wot.serialize_identity_set'
|
||||||
|
del payload['params']
|
||||||
|
print(onionrplugins.pluginapis.plugin_apis['rpc.rpc_client'](json=payload).text)
|
||||||
|
|
||||||
|
|
||||||
|
def ping_api() -> result.Result:
|
||||||
|
payload = dict(rpc_payload)
|
||||||
|
payload['method'] = 'ping'
|
||||||
|
del payload['params']
|
||||||
|
try:
|
||||||
|
_ping_res = onionrplugins.pluginapis.plugin_apis['rpc.rpc_client'](json=payload).text
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
logging.debug(traceback.format_exc())
|
||||||
|
return result.Err('Could not connect to Onionr RPC server. Please ensure the RPC plugin is enabled and the Onionr daemon is running')
|
||||||
|
except:
|
||||||
|
logging.error(traceback.format_exc())
|
||||||
|
return result.Err('Unknown error occurred while connecting to Onionr RPC server')
|
||||||
|
_ping_res = json.loads(_ping_res)
|
||||||
|
if _ping_res['result'] == 'pong':
|
||||||
|
return result.Ok()
|
||||||
|
else:
|
||||||
|
return result.Err('API not responding. Try restarting Onionr')
|
||||||
|
|
||||||
|
|
||||||
main_menu = {
|
main_menu = {
|
||||||
@ -14,18 +55,28 @@ main_menu = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def main_ui():
|
def main_ui():
|
||||||
tty.setraw(sys.stdin)
|
#tty.setraw(sys.stdin)
|
||||||
|
try:
|
||||||
|
onionrplugins.pluginapis.plugin_apis['rpc.rpc_client']
|
||||||
|
except KeyError:
|
||||||
|
logging.error("Web of trust CLI requires RPC plugin to be enabled")
|
||||||
|
return
|
||||||
|
|
||||||
|
ping_result: result.Result = ping_api()
|
||||||
|
if not isinstance(ping_result, result.Ok):
|
||||||
|
logging.error(ping_result)
|
||||||
|
return
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# move cursor to the beginning
|
# move cursor to the beginning
|
||||||
print('\r', end='')
|
print('\r', end='')
|
||||||
key = sys.stdin.read(1)
|
|
||||||
try:
|
try:
|
||||||
main_menu[key][1]()
|
key = sys.stdin.read(1)
|
||||||
|
main_menu[key][0]()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
subprocess.Popen(['reset'], stdout=subprocess.PIPE)
|
#subprocess.Popen(['reset'], stdout=subprocess.PIPE)
|
||||||
|
31
static-data/official-plugins/wot/cli/createiden.py
Normal file
31
static-data/official-plugins/wot/cli/createiden.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import base64
|
||||||
|
|
||||||
|
import keyring.errors
|
||||||
|
from nacl.signing import SigningKey
|
||||||
|
|
||||||
|
from logger import log as logging
|
||||||
|
import config
|
||||||
|
|
||||||
|
from wot import wotkeyring
|
||||||
|
from wot.identity import Identity
|
||||||
|
|
||||||
|
def create_new_iden():
|
||||||
|
iden = Identity(
|
||||||
|
SigningKey.generate(),
|
||||||
|
input('Enter a name for your identity: '))
|
||||||
|
try:
|
||||||
|
wotkeyring.set_identity(iden)
|
||||||
|
except keyring.errors.NoKeyringError:
|
||||||
|
logging.warn(
|
||||||
|
"Could not use secure keyring to store your WOT " +
|
||||||
|
"private key, using config.")
|
||||||
|
logging.info("Using config file to store identity private key")
|
||||||
|
config.set(
|
||||||
|
'wot.identity.{iden.name}',
|
||||||
|
base64.b85encode(
|
||||||
|
bytes(iden.private_key)).decode('utf-8'), savefile=True)
|
||||||
|
config.set(
|
||||||
|
'wot.active_identity_name', iden.name, savefile=True)
|
||||||
|
logging.info(
|
||||||
|
'Identity created and automatically set as active. ' +
|
||||||
|
'Restart Onionr to use it.')
|
1
static-data/official-plugins/wot/cli/trustidentity.py
Normal file
1
static-data/official-plugins/wot/cli/trustidentity.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
def trust_identity():
|
@ -80,9 +80,17 @@ def on_init(api, data=None):
|
|||||||
"<name>' and restart Onionr")
|
"<name>' and restart Onionr")
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
if config.get('wot.use_system_keyring', True):
|
||||||
|
try:
|
||||||
|
iden = wotkeyring.get_identity_by_name(active_identity)
|
||||||
|
except KeyError:
|
||||||
|
logging.error(
|
||||||
|
f"Could not load identity {active_identity} " +
|
||||||
|
"from keyring despite configuration choice to do so")
|
||||||
|
else:
|
||||||
|
# load from file
|
||||||
iden = load_identity_from_config(active_identity)
|
iden = load_identity_from_config(active_identity)
|
||||||
except KeyError:
|
|
||||||
try:
|
try:
|
||||||
iden = wotkeyring.get_identity_by_name(active_identity)
|
iden = wotkeyring.get_identity_by_name(active_identity)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -91,6 +99,8 @@ def on_init(api, data=None):
|
|||||||
return
|
return
|
||||||
|
|
||||||
logging.info('Loaded active identity: ' + iden.name)
|
logging.info('Loaded active identity: ' + iden.name)
|
||||||
|
identities.add(iden)
|
||||||
|
|
||||||
|
|
||||||
def on_wot_cmd(api, data=None):
|
def on_wot_cmd(api, data=None):
|
||||||
def _create_new_iden():
|
def _create_new_iden():
|
||||||
|
@ -6,3 +6,4 @@ from .identity import Identity
|
|||||||
from .getbykey import get_identity_by_key
|
from .getbykey import get_identity_by_key
|
||||||
from .identity import identities
|
from .identity import identities
|
||||||
from .identity.identityset import serialize_identity_set
|
from .identity.identityset import serialize_identity_set
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import base64
|
||||||
|
|
||||||
class IdentitySet(set):
|
class IdentitySet(set):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -32,7 +34,7 @@ identities = IdentitySet()
|
|||||||
def serialize_identity_set():
|
def serialize_identity_set():
|
||||||
serialized_idens = []
|
serialized_idens = []
|
||||||
for identity in list(identities):
|
for identity in list(identities):
|
||||||
serialized_idens.append(identity.serialize())
|
serialized_idens.append(base64.b85encode(identity.serialize()).decode('utf-8'))
|
||||||
return serialized_idens
|
return serialized_idens
|
||||||
|
|
||||||
serialize_identity_set.json_compatible = True
|
serialize_identity_set.json_compatible = True
|
@ -11,6 +11,7 @@ from wot.identity import Identity, identities
|
|||||||
from wot.exceptions import IdentitySerializationError
|
from wot.exceptions import IdentitySerializationError
|
||||||
from wot.getbykey import get_identity_by_key
|
from wot.getbykey import get_identity_by_key
|
||||||
from wot.identityprocessing import processtrustsignature
|
from wot.identityprocessing import processtrustsignature
|
||||||
|
import wot.wotcommand
|
||||||
|
|
||||||
|
|
||||||
def load_identity_from_block(block) -> Identity:
|
def load_identity_from_block(block) -> Identity:
|
||||||
@ -26,7 +27,7 @@ def load_identities_from_blocks() -> Generator[Identity, None, None]:
|
|||||||
|
|
||||||
|
|
||||||
def load_signatures_from_blocks() -> None:
|
def load_signatures_from_blocks() -> None:
|
||||||
for block in blockdb.get_blocks_by_type(b'wots'):
|
for block in blockdb.get_blocks_by_type(wot.wotcommand.block_type_map.trust):
|
||||||
try:
|
try:
|
||||||
# If good signature,
|
# If good signature,
|
||||||
# it adds the signature to the signed identity's trust set
|
# it adds the signature to the signed identity's trust set
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
from enum import IntEnum, auto
|
from enum import IntEnum, auto
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
class WotCommand(IntEnum):
|
class WotCommand(IntEnum):
|
||||||
TRUST = 1
|
TRUST = 1
|
||||||
REVOKE_TRUST = auto()
|
REVOKE_TRUST = auto()
|
||||||
ANNOUNCE = auto()
|
ANNOUNCE = auto()
|
||||||
REVOKE = auto()
|
REVOKE = auto()
|
||||||
|
|
||||||
|
|
||||||
|
_block_type_map = {
|
||||||
|
'trust': b'wots'
|
||||||
|
}
|
||||||
|
|
||||||
|
block_type_map = SimpleNamespace(**_block_type_map)
|
@ -1,16 +1,19 @@
|
|||||||
import base64
|
import base64
|
||||||
import keyring
|
|
||||||
|
|
||||||
from wot.identity import Identity
|
import keyring
|
||||||
|
import nacl.signing
|
||||||
|
|
||||||
|
import wot.identity
|
||||||
|
|
||||||
|
|
||||||
def get_identity_by_name(name: str) -> 'Identity':
|
def get_identity_by_name(name: str) -> 'Identity':
|
||||||
iden_key = keyring.get_credential('onionr.wot', name)
|
iden_key = keyring.get_credential('onionr.wot', name)
|
||||||
iden_key = base64.b85decode(iden_key)
|
|
||||||
|
|
||||||
if not iden_key:
|
if not iden_key:
|
||||||
raise KeyError('Identity not found')
|
raise KeyError('Identity not found')
|
||||||
return Identity(iden_key, name)
|
iden_key = base64.b85decode(iden_key.password)
|
||||||
|
iden_key = nacl.signing.SigningKey(iden_key)
|
||||||
|
|
||||||
|
return wot.identity.Identity(iden_key, name)
|
||||||
|
|
||||||
|
|
||||||
def set_identity(identity: 'Identity') -> None:
|
def set_identity(identity: 'Identity') -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user