Cic meta builds
This commit is contained in:
98
apps/cic-meta/example/client.py
Normal file
98
apps/cic-meta/example/client.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
import gnupg
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logg = logging.getLogger()
|
||||
|
||||
host = os.environ.get('CIC_META_URL', 'http://localhost:63380')
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
sys.stderr.write('Usage: {} <path-to-gpg-private-key>\n'.format(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# Import PGP key used to sign the data submission
|
||||
gpg = gnupg.GPG(gnupghome='/tmp/.gpg')
|
||||
f = open(sys.argv[1], 'r')
|
||||
key_data = f.read()
|
||||
f.close()
|
||||
|
||||
gpg.import_keys(key_data)
|
||||
gpgk = gpg.list_keys()
|
||||
algo = gpgk[0]['algo']
|
||||
logg.info('using signing key {} algo {}'.format(gpgk[0]['keyid'], algo))
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
# Random key to associate with value
|
||||
# (typically this is some deterministic identifier like sha256(<ethaddress>:cic-person)
|
||||
k = os.urandom(32).hex()
|
||||
url = os.path.join(host, k)
|
||||
|
||||
# Headers required for server-assisted merge operations
|
||||
headers = {
|
||||
'X-CIC-AUTOMERGE': 'server',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
# Data to merge
|
||||
data_dict = {
|
||||
'foo': 'bar',
|
||||
'xyzzy': 42,
|
||||
}
|
||||
|
||||
# Send request to server to get initial automerge object and signing material
|
||||
# Server will reply with current state of object merged with ours, but (obviously)
|
||||
# still without a signature.
|
||||
data = json.dumps(data_dict).encode('utf-8')
|
||||
req = Request(url, headers=headers, data=data, method='POST')
|
||||
rs = urlopen(req)
|
||||
logg.info('get sign material response status: {}'.format(rs.status))
|
||||
if rs.status != 200:
|
||||
raise RuntimeError('request failed: {}'.format(rs.reason))
|
||||
|
||||
|
||||
# Sign the provided digest
|
||||
data = rs.read()
|
||||
e = json.loads(data)
|
||||
sig = gpg.sign(e['digest'], passphrase='ge', keyid=gpgk[0]['keyid'])
|
||||
|
||||
# Format data for the content storage request
|
||||
data = {
|
||||
'm': data.decode('utf-8'),
|
||||
's': {
|
||||
'engine': 'pgp',
|
||||
'algo': algo,
|
||||
'data': str(sig),
|
||||
'digest': e['digest'],
|
||||
},
|
||||
}
|
||||
|
||||
# Send storage request to server
|
||||
data = json.dumps(data).encode('utf-8')
|
||||
req = Request(url, headers=headers, data=data, method='PUT')
|
||||
rs = urlopen(req)
|
||||
|
||||
logg.info('signed content submissionstatus: {}'.format(rs.status))
|
||||
if rs.status != 200:
|
||||
raise RuntimeError('request failed: {}'.format(rs.reason))
|
||||
|
||||
|
||||
# Get the latest stored version of the data (without the merge graph)
|
||||
req = Request(url, method='GET')
|
||||
rs = urlopen(req)
|
||||
logg.info('get latest data status: {}'.format(rs.status))
|
||||
if rs.status != 200:
|
||||
raise RuntimeError('request failed: {}'.format(rs.reason))
|
||||
|
||||
print(rs.read().decode('utf-8'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user