Add phone numbers to listings
This commit is contained in:
parent
d8957e89c9
commit
99156a1dba
@ -13,7 +13,10 @@ from chainlib.chain import ChainSpec
|
|||||||
import clicada.cli.user as cmd_user
|
import clicada.cli.user as cmd_user
|
||||||
import clicada.cli.tag as cmd_tag
|
import clicada.cli.tag as cmd_tag
|
||||||
from clicada.cli.auth import PGPAuthCrypt
|
from clicada.cli.auth import PGPAuthCrypt
|
||||||
from clicada.cli.http import HTTPSession
|
from clicada.cli.http import (
|
||||||
|
HTTPSession,
|
||||||
|
PGPClientSession,
|
||||||
|
)
|
||||||
|
|
||||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
data_dir = os.path.join(script_dir, '..', 'data')
|
data_dir = os.path.join(script_dir, '..', 'data')
|
||||||
@ -32,8 +35,32 @@ class CmdCtrl:
|
|||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, argv=None, description=None, logger=None, *args, **kwargs):
|
def __init__(self, argv=None, description=None, logger=None, *args, **kwargs):
|
||||||
self.argparser = chainlib.eth.cli.ArgumentParser(chainlib.eth.cli.argflag_std_read)
|
self.args(argv)
|
||||||
|
|
||||||
|
self.logging(logger)
|
||||||
|
|
||||||
|
self.module()
|
||||||
|
|
||||||
|
self.config()
|
||||||
|
|
||||||
|
self.auth()
|
||||||
|
|
||||||
|
self.blockchain()
|
||||||
|
|
||||||
|
self.remote_openers = {}
|
||||||
|
if self.get('META_URL') != None:
|
||||||
|
auth_client_session = PGPClientSession(self.__auth)
|
||||||
|
self.remote_openers['meta'] = HTTPSession(self.get('META_URL'), auth=auth_client_session)
|
||||||
|
|
||||||
|
|
||||||
|
def blockchain(self):
|
||||||
|
self.chain_spec = ChainSpec.from_chain_str(self.config.get('CHAIN_SPEC'))
|
||||||
|
self.rpc = chainlib.eth.cli.Rpc()
|
||||||
|
self.__conn = self.rpc.connect_by_config(self.config)
|
||||||
|
|
||||||
|
|
||||||
|
def args(self, argv):
|
||||||
|
self.argparser = chainlib.eth.cli.ArgumentParser(chainlib.eth.cli.argflag_std_read)
|
||||||
sub = self.argparser.add_subparsers()
|
sub = self.argparser.add_subparsers()
|
||||||
sub.dest = 'command'
|
sub.dest = 'command'
|
||||||
sub_user = sub.add_parser('user', aliases=['u'], help='retrieve transactions for a user')
|
sub_user = sub.add_parser('user', aliases=['u'], help='retrieve transactions for a user')
|
||||||
@ -43,13 +70,8 @@ class CmdCtrl:
|
|||||||
|
|
||||||
self.cmd_args = self.argparser.parse_args(argv)
|
self.cmd_args = self.argparser.parse_args(argv)
|
||||||
|
|
||||||
if logger == None:
|
|
||||||
logger = logging.getLogger()
|
def module(self):
|
||||||
if self.cmd_args.vv:
|
|
||||||
logger.setLevel(logging.DEBUG)
|
|
||||||
elif self.cmd_args.v:
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
self.cmd_string = self.cmd_args.command
|
self.cmd_string = self.cmd_args.command
|
||||||
cmd_string_translate = self.__cmd_alias.get(self.cmd_string)
|
cmd_string_translate = self.__cmd_alias.get(self.cmd_string)
|
||||||
if cmd_string_translate != None:
|
if cmd_string_translate != None:
|
||||||
@ -59,36 +81,36 @@ class CmdCtrl:
|
|||||||
raise ValueError('Subcommand missing')
|
raise ValueError('Subcommand missing')
|
||||||
|
|
||||||
modname = 'clicada.cli.{}'.format(self.cmd_string)
|
modname = 'clicada.cli.{}'.format(self.cmd_string)
|
||||||
logger.debug('using module {}'.format(modname))
|
self.logger.debug('using module {}'.format(modname))
|
||||||
self.cmd_mod = importlib.import_module(modname)
|
self.cmd_mod = importlib.import_module(modname)
|
||||||
|
|
||||||
|
|
||||||
|
def logging(self, logger):
|
||||||
|
self.logger = logger
|
||||||
|
if self.logger == None:
|
||||||
|
self.logger = logging.getLogger()
|
||||||
|
if self.cmd_args.vv:
|
||||||
|
self.logger.setLevel(logging.DEBUG)
|
||||||
|
elif self.cmd_args.v:
|
||||||
|
self.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
def config(self):
|
||||||
extra_args = self.cmd_mod.extra_args()
|
extra_args = self.cmd_mod.extra_args()
|
||||||
logger.debug('using extra args {}'.format(extra_args))
|
|
||||||
if self.cmd_args.config:
|
if self.cmd_args.config:
|
||||||
self.config = chainlib.eth.cli.Config.from_args(self.cmd_args, base_config_dir=base_config_dir, extra_args=extra_args, override_dirs=self.cmd_args.c)
|
self.config = chainlib.eth.cli.Config.from_args(self.cmd_args, base_config_dir=base_config_dir, extra_args=extra_args, override_dirs=self.cmd_args.c)
|
||||||
else:
|
else:
|
||||||
self.config = chainlib.eth.cli.Config.from_args(self.cmd_args, base_config_dir=base_config_dir, extra_args=extra_args)
|
self.config = chainlib.eth.cli.Config.from_args(self.cmd_args, base_config_dir=base_config_dir, extra_args=extra_args)
|
||||||
|
|
||||||
self.auth(self.get('AUTH_TYPE'))
|
|
||||||
|
|
||||||
self.config.add(False, '_SEQ')
|
self.config.add(False, '_SEQ')
|
||||||
|
|
||||||
self.config.censor('AUTH_PASSPHRASE')
|
self.config.censor('AUTH_PASSPHRASE')
|
||||||
|
|
||||||
logger.debug('loaded config:\n{}'.format(self.config))
|
self.logger.debug('loaded config:\n{}'.format(self.config))
|
||||||
|
|
||||||
self.chain_spec = ChainSpec.from_chain_str(self.config.get('CHAIN_SPEC'))
|
|
||||||
|
|
||||||
self.rpc = chainlib.eth.cli.Rpc()
|
|
||||||
self.__conn = self.rpc.connect_by_config(self.config)
|
|
||||||
|
|
||||||
|
|
||||||
self.remote_openers = {}
|
|
||||||
if self.get('META_URL') != None:
|
|
||||||
self.remote_openers['meta'] = HTTPSession(self.get('META_URL'), auth=self.__auth)
|
|
||||||
|
|
||||||
|
|
||||||
def auth(self, typ):
|
def auth(self):
|
||||||
|
typ = self.get('AUTH_TYPE')
|
||||||
if typ != 'gnupg':
|
if typ != 'gnupg':
|
||||||
raise NotImplementedError('Valid aut implementations are: gnupg')
|
raise NotImplementedError('Valid aut implementations are: gnupg')
|
||||||
default_auth_db_path = os.path.join(os.environ['HOME'], '.clicada/auth')
|
default_auth_db_path = os.path.join(os.environ['HOME'], '.clicada/auth')
|
||||||
|
@ -5,7 +5,6 @@ import logging
|
|||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import gnupg
|
import gnupg
|
||||||
from usumbufu.client.hoba import HobaClientSession
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from clicada.error import AuthError
|
from clicada.error import AuthError
|
||||||
@ -13,10 +12,9 @@ from clicada.error import AuthError
|
|||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PGPAuthCrypt(HobaClientSession):
|
class PGPAuthCrypt:
|
||||||
|
|
||||||
typ = 'gnupg'
|
typ = 'gnupg'
|
||||||
alg = '969'
|
|
||||||
|
|
||||||
def __init__(self, db_dir, auth_key, pgp_dir=None):
|
def __init__(self, db_dir, auth_key, pgp_dir=None):
|
||||||
self.db_dir = db_dir
|
self.db_dir = db_dir
|
||||||
@ -41,9 +39,9 @@ class PGPAuthCrypt(HobaClientSession):
|
|||||||
h.update(bytes.fromhex(self.auth_key))
|
h.update(bytes.fromhex(self.auth_key))
|
||||||
h.update(passphrase.encode('utf-8'))
|
h.update(passphrase.encode('utf-8'))
|
||||||
z = h.digest()
|
z = h.digest()
|
||||||
secret = self.gpg.encrypt(z, [self.auth_key])
|
secret = self.gpg.encrypt(z, [self.auth_key], always_trust=True)
|
||||||
if not secret.ok:
|
if not secret.ok:
|
||||||
raise AuthError('could not encrypt secret for {}'.format(auth_key))
|
raise AuthError('could not encrypt secret for {}'.format(self.auth_key))
|
||||||
|
|
||||||
d = os.path.dirname(p)
|
d = os.path.dirname(p)
|
||||||
os.makedirs(d, exist_ok=True)
|
os.makedirs(d, exist_ok=True)
|
||||||
@ -55,21 +53,23 @@ class PGPAuthCrypt(HobaClientSession):
|
|||||||
if not self.secret.ok:
|
if not self.secret.ok:
|
||||||
raise AuthError('could not decrypt encryption secret. wrong password?')
|
raise AuthError('could not decrypt encryption secret. wrong password?')
|
||||||
f.close()
|
f.close()
|
||||||
|
self.__passphrase = passphrase
|
||||||
|
|
||||||
|
|
||||||
def sign_auth_challenge(self, plaintext, hoba, encoding):
|
def get_passphrase(self):
|
||||||
r = self.gpg.sign(plaintext, passphrase=self.passphrase, detach=True)
|
return self.__passphrase
|
||||||
|
|
||||||
|
|
||||||
|
def fingerprint(self):
|
||||||
|
return self.auth_key
|
||||||
|
|
||||||
|
|
||||||
|
def sign(self, plaintext, encoding, passphrase='', detach=True):
|
||||||
|
r = self.gpg.sign(plaintext, passphrase=passphrase, detach=detach)
|
||||||
|
if len(r.data) == 0:
|
||||||
|
raise AuthError('signing failed: ' + r.status)
|
||||||
|
|
||||||
if encoding == 'base64':
|
if encoding == 'base64':
|
||||||
r = r.data
|
r = r.data
|
||||||
|
|
||||||
hoba.signature = r
|
return r
|
||||||
return str(hoba)
|
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return 'clicada hoba/pgp auth'
|
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return 'clicada hoba/pgp auth'
|
|
||||||
|
@ -10,10 +10,37 @@ from usumbufu.client.base import (
|
|||||||
BaseTokenStore,
|
BaseTokenStore,
|
||||||
)
|
)
|
||||||
from usumbufu.client.bearer import BearerClientSession
|
from usumbufu.client.bearer import BearerClientSession
|
||||||
|
from usumbufu.client.hoba import HobaClientSession
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class PGPClientSession(HobaClientSession):
|
||||||
|
|
||||||
|
alg = '969'
|
||||||
|
|
||||||
|
def __init__(self, auth):
|
||||||
|
self.auth = auth
|
||||||
|
self.origin = None
|
||||||
|
self.fingerprint = self.auth.fingerprint()
|
||||||
|
|
||||||
|
|
||||||
|
def sign_auth_challenge(self, plaintext, hoba, encoding):
|
||||||
|
passphrase = self.auth.get_passphrase()
|
||||||
|
r = self.auth.sign(plaintext, encoding, passphrase=passphrase, detach=True)
|
||||||
|
|
||||||
|
hoba.signature = r
|
||||||
|
return str(hoba)
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'clicada hoba/pgp auth'
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'clicada hoba/pgp auth'
|
||||||
|
|
||||||
|
|
||||||
class HTTPSession:
|
class HTTPSession:
|
||||||
|
|
||||||
token_dir = '/run/user/{}/clicada/usumbufu/.token'.format(os.getuid())
|
token_dir = '/run/user/{}/clicada/usumbufu/.token'.format(os.getuid())
|
||||||
@ -21,21 +48,25 @@ class HTTPSession:
|
|||||||
def __init__(self, url, auth=None):
|
def __init__(self, url, auth=None):
|
||||||
logg.debug('auth auth {}'.format(auth))
|
logg.debug('auth auth {}'.format(auth))
|
||||||
self.base_url = url
|
self.base_url = url
|
||||||
url_parts = urllib.parse.urlparse(self.base_url)
|
url_parts = urllib.parse.urlsplit(self.base_url)
|
||||||
self.origin = urllib.parse.urljoin(url_parts[0], url_parts[1])
|
url_parts_origin = (url_parts[0], url_parts[1], '', '', '',)
|
||||||
|
self.origin = urllib.parse.urlunsplit(url_parts_origin)
|
||||||
|
|
||||||
h = hashlib.sha256()
|
h = hashlib.sha256()
|
||||||
h.update(self.base_url.encode('utf-8'))
|
h.update(self.base_url.encode('utf-8'))
|
||||||
z = h.digest()
|
z = h.digest()
|
||||||
|
|
||||||
token_store_dir = os.path.join(self.token_dir, z.hex())
|
token_store_dir = os.path.join(self.token_dir, z.hex())
|
||||||
|
os.makedirs(token_store_dir, exist_ok=True)
|
||||||
self.token_store = BaseTokenStore(path=token_store_dir)
|
self.token_store = BaseTokenStore(path=token_store_dir)
|
||||||
|
|
||||||
self.session = ClientSession(self.origin, token_store=self.token_store)
|
self.session = ClientSession(self.origin, token_store=self.token_store)
|
||||||
|
|
||||||
bearer_handler = BearerClientSession(self.origin, token_store=self.token_store)
|
bearer_handler = BearerClientSession(self.origin, token_store=self.token_store)
|
||||||
self.session.add_subhandler(bearer_handler)
|
self.session.add_subhandler(bearer_handler)
|
||||||
|
|
||||||
if auth != None:
|
if auth != None:
|
||||||
|
auth.origin = self.origin
|
||||||
self.session.add_subhandler(auth)
|
self.session.add_subhandler(auth)
|
||||||
|
|
||||||
self.opener = urllib.request.build_opener(self.session)
|
self.opener = urllib.request.build_opener(self.session)
|
||||||
|
@ -9,7 +9,6 @@ import datetime
|
|||||||
# external imports
|
# external imports
|
||||||
from hexathon import strip_0x
|
from hexathon import strip_0x
|
||||||
from cic_types.condiments import MetadataPointer
|
from cic_types.condiments import MetadataPointer
|
||||||
from cic_types.ext.metadata import MetadataRequestsHandler
|
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
from cic_types.ext.requests import make_request
|
from cic_types.ext.requests import make_request
|
||||||
from cic_types.processor import generate_metadata_pointer
|
from cic_types.processor import generate_metadata_pointer
|
||||||
@ -53,6 +52,14 @@ class Account(Person):
|
|||||||
return o
|
return o
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} {} ({})'.format(
|
||||||
|
self.given_name,
|
||||||
|
self.family_name,
|
||||||
|
self.tel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FileUserStore:
|
class FileUserStore:
|
||||||
|
|
||||||
def __init__(self, metadata_opener, chain_spec, label, store_base_path, ttl):
|
def __init__(self, metadata_opener, chain_spec, label, store_base_path, ttl):
|
||||||
@ -183,14 +190,14 @@ class FileUserStore:
|
|||||||
except ExpiredRecordError as e:
|
except ExpiredRecordError as e:
|
||||||
logg.info(e)
|
logg.info(e)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
getter = self.metadata_opener
|
||||||
|
ptr = generate_metadata_pointer(phone.encode('utf-8'), MetadataPointer.PHONE)
|
||||||
r = None
|
r = None
|
||||||
user_address = None
|
user_address = None
|
||||||
try:
|
try:
|
||||||
ptr = generate_metadata_pointer(phone.encode('utf-8'), MetadataPointer.PHONE)
|
r = getter.open(ptr)
|
||||||
url = urllib.parse.urljoin(MetadataRequestsHandler.base_url, ptr)
|
user_address = json.loads(r)
|
||||||
r = make_request('GET', url)
|
|
||||||
user_address = r.json()
|
|
||||||
except requests.exceptions.HTTPError as e:
|
except requests.exceptions.HTTPError as e:
|
||||||
logg.debug('no address found for phone {}: {}'.format(phone, e))
|
logg.debug('no address found for phone {}: {}'.format(phone, e))
|
||||||
return None
|
return None
|
||||||
|
Loading…
Reference in New Issue
Block a user