cic-stack/apps/cic-ussd/cic_ussd/metadata/base.py

102 lines
3.4 KiB
Python
Raw Normal View History

2021-04-14 11:00:10 +02:00
# standard imports
import json
import logging
import os
from typing import Dict, Union
# third-part imports
from cic_types.models.person import generate_metadata_pointer, Person
# local imports
2021-08-06 18:29:01 +02:00
from cic_ussd.cache import cache_data, get_cached_data
from cic_ussd.http.requests import error_handler, make_request
2021-04-14 11:00:10 +02:00
from cic_ussd.metadata.signer import Signer
2021-08-06 18:29:01 +02:00
logg = logging.getLogger(__file__)
2021-04-14 11:00:10 +02:00
class Metadata:
"""
2021-04-14 11:00:10 +02:00
:cvar base_url: The base url or the metadata server.
:type base_url: str
"""
base_url = None
2021-04-14 11:00:10 +02:00
class MetadataRequestsHandler(Metadata):
def __init__(self, cic_type: str, identifier: bytes, engine: str = 'pgp'):
2021-08-06 18:29:01 +02:00
""""""
2021-04-14 11:00:10 +02:00
self.cic_type = cic_type
self.engine = engine
self.headers = {
'X-CIC-AUTOMERGE': 'server',
'Content-Type': 'application/json'
}
self.identifier = identifier
self.metadata_pointer = generate_metadata_pointer(
identifier=self.identifier,
cic_type=self.cic_type
)
if self.base_url:
self.url = os.path.join(self.base_url, self.metadata_pointer)
def create(self, data: Union[Dict, str]):
2021-08-06 18:29:01 +02:00
""""""
2021-08-29 11:55:47 +02:00
data = json.dumps(data).encode('utf-8')
2021-04-14 11:00:10 +02:00
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
2021-08-06 18:29:01 +02:00
error_handler(result=result)
2021-06-03 15:40:51 +02:00
metadata = result.json()
2021-08-06 18:29:01 +02:00
return self.edit(data=metadata)
2021-04-14 11:00:10 +02:00
2021-06-03 15:40:51 +02:00
def edit(self, data: Union[Dict, str]):
2021-08-06 18:29:01 +02:00
""""""
2021-04-14 11:00:10 +02:00
cic_meta_signer = Signer()
signature = cic_meta_signer.sign_digest(data=data)
algorithm = cic_meta_signer.get_operational_key().get('algo')
formatted_data = {
2021-06-03 15:40:51 +02:00
'm': json.dumps(data),
2021-04-14 11:00:10 +02:00
's': {
'engine': self.engine,
'algo': algorithm,
'data': signature,
2021-06-03 15:40:51 +02:00
'digest': data.get('digest'),
2021-04-14 11:00:10 +02:00
}
}
formatted_data = json.dumps(formatted_data)
2021-04-14 11:00:10 +02:00
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
logg.info(f'signed metadata submission status: {result.status_code}.')
2021-08-06 18:29:01 +02:00
error_handler(result=result)
2021-04-14 11:00:10 +02:00
try:
decoded_identifier = self.identifier.decode("utf-8")
except UnicodeDecodeError:
decoded_identifier = self.identifier.hex()
2021-06-03 15:40:51 +02:00
logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {data}.')
2021-08-06 18:29:01 +02:00
return result
2021-04-14 11:00:10 +02:00
def query(self):
2021-08-06 18:29:01 +02:00
""""""
2021-04-14 11:00:10 +02:00
result = make_request(method='GET', url=self.url)
2021-08-06 18:29:01 +02:00
error_handler(result=result)
2021-06-03 15:40:51 +02:00
result_data = result.json()
if not isinstance(result_data, dict):
raise ValueError(f'Invalid result data object: {result_data}.')
2021-07-20 18:18:27 +02:00
if result.status_code == 200:
if self.cic_type == ':cic.person':
person = Person()
person_data = person.deserialize(person_data=result_data)
serialized_person_data = person_data.serialize()
data = json.dumps(serialized_person_data)
else:
data = json.dumps(result_data)
2021-06-03 15:40:51 +02:00
cache_data(key=self.metadata_pointer, data=data)
2021-04-14 11:00:10 +02:00
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
2021-07-20 18:18:27 +02:00
return result_data
2021-08-06 18:29:01 +02:00
def get_cached_metadata(self):
""""""
key = generate_metadata_pointer(self.identifier, self.cic_type)
return get_cached_data(key)