def get_asset(self, asset_id, index): address = addresser.create_asset_address(asset_id=asset_id, index=index) """ self._state_entries.extend(self._context.get_state( addresses=[address], timeout=self._timeout)) return self._get_asset(address=address, name=name) """ asset = self._context.get_state(addresses=[address], timeout=self._timeout) return asset
async def assets(self): logging.info("Finding all the assets from the SOlve account") create_asset_idxs, nth_keys = await self.indexes_n_pub_priv_pairs( "create_asset_idxs") address_list = [] if create_asset_idxs: for key_index in create_asset_idxs: public_key = nth_keys[str(key_index)]["public_key"] child_address = addresser.create_asset_address( asset_id=public_key, index=key_index) address_list.append(child_address) logging.info(f"Asset address list <<{address_list}>>") return address_list
def set_asset(self, payload, public, account, account_type): """ payload will have the CreateAsset in the payload public: hex public key with whose private key transaction was signed account: could be a float account or account account_type: could be FLOAT_ACCOUNT or CREATE_ACCOUNT """ logging.info("Account in set_asset <<{}>>".format(account)) if account_type == "FLOAT_ACCOUNT": account_address = addresser.float_account_address( account_id=payload.flt_account_parent_pub, index=payload.flt_account_parent_idx) else: account_address = addresser.create_account_address( account_id=payload.zero_pub, index=0) self.update_asset_index(account_address, account, payload.idx) address = addresser.create_asset_address(asset_id=public, index=payload.idx) asset = create_empty_asset() asset.key = payload.key asset.url = payload.url asset.time = payload.time asset.indiantime = payload.indiantime asset.file_name = payload.file_name asset.file_hash = payload.file_hash asset.idx = payload.idx asset.master_key = payload.master_key asset.master_url = payload.master_url asset.role = payload.role asset.public = public if payload.scope: asset.scope.cert_type = payload.scope.cert_type asset.scope.product_type = payload.scope.product_type asset.scope.product_name = payload.scope.product_name logging.info(asset) logging.info("Account after serialization %s", asset.SerializeToString()) return self._context.set_state({address: asset.SerializeToString()}, self._timeout)
def share_asset(account, receive_asset_address, unique_code): headers = get_headers_on_email(account["email"], account["password"]) asset = get_assets(account)[0] logging.info(asset) asset_address = addresser.create_asset_address(asset_id=asset["public"], index=asset["idx"]) logging.info(f"Asset address which will be shared is {asset_address}") data = { "revoked_on": revoke_time_stamp(days=30), "asset_address": asset_address, "receive_asset_address": receive_asset_address, "unique_code": unique_code, "comments": faker.paragraph() } logging.info(f"data for shareasset is {data}") r = requests.post("http://localhost:8000/assets/share_asset", data=json.dumps(data), headers=headers) logging.info(r.json())
async def send_create_asset(**in_data): """ Args key(str), hex_encoded: encrypted AES key with user publickey present at random index url(str): s3 url encrypted with user public key time(str): when this asset was created indiantime(str): time in indian format file_name(str): file_name file_hash(str): sha3_512 hash of file content child_idx(int): random index parent_zero_pub(str): Parent zero public key of the parent master_key(str): encrypted s3 url, encrypted with aes key generated with qci_public and user private key master_url(str): encrypted s3 url, encrypted with aes key generated with private key of user and public of QCI scope(Scope(defined in asset.proto)): string expired_on=13; //the date on which this certificate is intended """ ##TODO: Processor side : Float this asset and make change to create_asset_idxs ## to either float_Account_Address or create_Account_Address depending upon ##whther the user has been claimed or not inputs = [ addresser.create_asset_address( asset_id=in_data["txn_key"].get_public_key().as_hex(), index=in_data["idx"]), ] outputs = [ addresser.create_asset_address( asset_id=in_data["txn_key"].get_public_key().as_hex(), index=in_data["idx"]) ] ##ideally if account is claimed, we should have nothing to do with float account ## but we are sending both addresses to the processor and let processor handle ## the logic i.e float_account should exists and is_claimed shall be true ##to append create_asset_idxs to the account_transaction if not in_data["is_acc_claimed"]: ##implies user havent claimed his float_account_address, so the ## create_asset_idx aill be chnaged on flt_account_addresslogging.info("Float account parent pub %s"%in_data["flt_account_parent_pub"]) logging.info("Float account parent idx %s" % str(in_data["flt_account_parent_idx"])) float_account_address = addresser.float_account_address( account_id=in_data["flt_account_parent_pub"], index=in_data["flt_account_parent_idx"]) inputs.append(float_account_address) outputs.append(float_account_address) else: account_address = addresser.create_organization_account_address( account_id=in_data["zero_pub"], index=0) inputs.append(account_address) outputs.append(account_address) if in_data["child_zero_pub"]: child_address = addresser.child_account_address( account_id=in_data["child_zero_pub"], index=0) inputs.append(child_address) outputs.append(child_address) if in_data["scope"]: scope = payload_pb2.PayloadScope( group=in_data["scope"]["group"], sub_group=in_data["scope"]["sub_group"], field=in_data["scope"]["field"], nature=in_data["scope"]["nature"], operations=in_data["scope"]["operations"], description=in_data["scope"]["description"], ) else: scope = None logging.info(f"Input Address<<{inputs}>>") logging.info(f"Output Address<<{outputs}>>") asset = payload_pb2.CreateAsset( key=in_data["key"], url=in_data["url"], time=in_data["time"], indiantime=in_data["indiantime"], file_name=in_data["file_name"], file_hash=in_data["file_hash"], idx=in_data["idx"], master_key=in_data["master_key"], master_url=in_data["master_url"], role=in_data["role"], scope=scope, zero_pub=in_data["zero_pub"], flt_account_parent_pub=in_data["flt_account_parent_pub"], flt_account_parent_idx=in_data["flt_account_parent_idx"], child_zero_pub=in_data["child_zero_pub"]) logging.info(f"Create asset transaction {asset}") payload = payload_pb2.TransactionPayload( payload_type=payload_pb2.TransactionPayload.CREATE_ASSET, create_asset=asset) transaction_ids, batches, batch_id, batch_list_bytes = make_header_and_batch( payload=payload, inputs=inputs, outputs=outputs, txn_key=in_data["txn_key"], batch_key=in_data["batch_key"]) logging.info(f"This is the batch_id {batch_id}") rest_api_response = await messaging.send(batch_list_bytes, in_data["config"]) try: result = await messaging.wait_for_status(batch_id, in_data["config"]) except (ApiBadRequest, ApiInternalError) as err: #await auth_query.remove_auth_entry(request.app.config.DB_CONN, request.json.get('email')) logging.error(f"Transaction failed with {err}") raise ApiInternalError(err) #raise err return transaction_ids, batch_id
async def submit_empty_asset(app, requester, claimed=False): """ claimed : False, Which means this account hasnt been claimed, it doesnt have a orgnization_account Implies that create_asset_idxs array of float account will be appended with key_index rather the orgnization acount create_asset_idxs float_accounts cannot create assets, but any other orgnization who have been claimed can force float_account to create empty asset, thats why for create_asset claimed will be always True. Now empty asset can be created by any account, Child, orgnization or float_account Child account for float_account can't exists """ f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic org_db_entry = f.org_db logging.info(f"THis is the decrypted mnemonic {decrypted_mnemonic}") create_asset_idxs = f.org_state.get("create_asset_idxs") child_zero_pub = f.child_zero_pub child_user_id = f.child_user_id zero_pub = f.zero_pub if not claimed: ##these are required so that create_asset_idxs of float account ##can be apended with key_index flt_account_parent_pub = requester[ "parent_pub"] #exists both in users_table flt_account_parent_idx = requester["parent_idx"] else: flt_account_parent_pub = None #exists both in users_table flt_account_parent_idx = None key_index = await ledger_utils.generate_key_index(array=create_asset_idxs) nth_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [key_index]) nth_priv, nth_pub = nth_keys[str(key_index)]["private_key"], \ nth_keys[str(key_index)]["public_key"] key = encrypted_key = s3_url = encrypted_s3_url = None master_key = master_url = None ##the transaction will be signed by users nth private key create_asset_signer = ledger_utils.create_signer(nth_priv) ##we havent included the child_nth_pub in this transaction because it ## can be calculated from txn_key on the processor side asset_address = addresser.create_asset_address(asset_id=nth_pub, index=key_index) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "key": None, "url": None, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "file_name": None, "file_hash": None, "idx": key_index, "master_key": None, "master_url": None, "scope": None, "role": requester["role"], "zero_pub": zero_pub, "is_acc_claimed": claimed, "flt_account_parent_pub": flt_account_parent_pub, "flt_account_parent_idx": flt_account_parent_idx, "child_zero_pub": child_zero_pub, } logging.info(f"THis is the transaction data {transaction_data}") transaction_ids, batch_id = await send_create_asset(**transaction_data) if batch_id: [ transaction_data.pop(field) for field in [ "config", "txn_key", "batch_key", "is_acc_claimed", "flt_account_parent_pub", "flt_account_parent_idx" ] ] transaction_data.update({ "user_id": requester["user_id"], "public": nth_pub, "transaction_id": transaction_ids[0], "batch_id": batch_id, "asset_address": asset_address, "child_zero_pub": child_zero_pub }) await assets_query.store_assets(app, transaction_data) if claimed: await accounts_query.update_create_asst_idxs( app, org_db_entry["user_id"], key_index) else: logging.error("Must be a float account") await accounts_query.update_create_asst_idxs_pending( app, org_db_entry["user_id"], key_index) if child_user_id: await accounts_query.update_create_asst_idxs( app, child_user_id, key_index) #await accounts_query.update_create_asst_idxs_pending(app, #requester["user_id"], key_index) return nth_priv, nth_pub, key_index, asset_address else: logging.error("Create asset Faied, GO to hell Dude!!!!,\ Kabhi kabhi lagta hai ki bhagwan hone ka bhi kya fayda") return
async def submit_create_asset(app, requester, file_data): """ Creates an empty asset or asset with data, Process: Get user Mnemonic If user is child, then get the mnemonic of the parent orgnization This can be done by getting by fetching org account present on the blokchchain constructing org_address from child["parent_pub"] Checks: 1.check if child is actually a valid child by checking if child parent_idx is in org_account["child_account_idxs"] 2. Check child org_name is same is orgnization org_name Fecth org entry in the dabase corresponding to the user_id of the org in orgnization entry on blokchchain NOw decrypt the org menmonic with Admin public key if org is not admin Now, get the create_asset_idxs array of the organization from the blockchain if requester is orgnization: Fecth org entry in the dabase corresponding to the user_id of the org in orgnization entry on blokchchain NOw decrypt the org menmonic with Admin public key if org is not admin Now, get the create_asset_idxs array of the organization from the blockchain A new key_index will be generated at create_asset_idxs, From the decrypted_nemonic, Public/Private key pair will be generated at this key_index, this will be a asset_address NOw, Check if file_Data is there or not, if yes, Encrypt the file data with random AES key, and post it on S3, Now encrypt both AES key and s3_url with the public key generated at random index Now there are two main conditions which needs attention, The user who still dont have an orgnization account but only a float_account In this case, is_claimed "flt_account_parent_pub": requester["parent_pub"], "flt_account_parent_idx": requester["parent_idx"], THese are required because since this is a float_account, on the processor side, the key_index will be appended to float_account which will be calculated from these two keys Th user does have an orgnization account The user whom is floating this transaction if claimed=False, user havent claimed his/her account if claimed=False, the requester["role"] cant be child, as float accounts arent allowed to create child roles, ADMIN doesnt have float accounts "flt_account_parent_pub": None, "flt_account_parent_idx": None, THese keys are required if the account is float_account, Now since this orgnization doesnt have any real account or the account has not been claimed, the create_asset_idxs will be appended to create_asset_idxs of float account Now since float account can not create new assets, only assets being transffered to them, Float account cannot run this function as credentials of float account are debarred from accessing this api or this function so, only CHILD, AQDMIN or any other orgnixzation who already have alimed their account can access this API, which means they have orgnization account, which means key_index will be appende to their orgnization account not float_account_idxs, Hence these two keys will be none for this function """ logging.info("Enterintosubmitcreateasset") f = await userapis.SolveAccount(requester, app) decrypted_mnemonic = f.decrypted_mnemonic org_state = f.org_state logging.info(f"THis is the decrypted mnemonic {decrypted_mnemonic}") create_asset_idxs = f.org_state.get("create_asset_idxs") child_zero_pub = f.child_zero_pub child_user_id = f.child_user_id zero_pub = f.zero_pub flt_account_parent_pub = None #exists both in users_table flt_account_parent_idx = None ##generate a new random index key which is not present in the ## create_asset_idxs key_index = await ledger_utils.generate_key_index(array=create_asset_idxs) logging.info(f"User key index create_asset_idxs for user {key_index}") ##retrieve pub/priv key pair corresponding to the random index just ##generated nth_keys = await remote_calls.key_index_keys(app, decrypted_mnemonic, [key_index]) nth_priv, nth_pub = nth_keys[str(key_index)]["private_key"], \ nth_keys[str(key_index)]["public_key"] ## all the data being encrypted with user nth public key key, encrypted_key, s3_url, encrypted_s3_url = \ await asset_utils.encrypt_file_data(requester["user_id"], nth_pub, app.config, file_data) master_key, master_url = await asset_utils.master_url_n_key( app.config.ADMIN_ZERO_PUB, key, s3_url) ##the transaction will be signed by users nth private key create_asset_signer = ledger_utils.create_signer(nth_priv) ##we havent included the child_nth_pub in this transaction because it ## can be calculated from txn_key on the processor side asset_address = addresser.create_asset_address(asset_id=nth_pub, index=key_index) transaction_data = { "config": app.config, "txn_key": create_asset_signer, "batch_key": app.config.SIGNER, "key": encrypted_key, "url": encrypted_s3_url, "time": int(time.time()), "indiantime": upload_utils.indian_time_stamp(), "file_name": file_data["file_name"], "file_hash": file_data["file_hash"], "idx": key_index, "master_key": master_key, "master_url": master_url, "role": requester["role"], "scope": file_data["scope"], "zero_pub": zero_pub, "is_acc_claimed": True, "flt_account_parent_pub": None, "flt_account_parent_idx": None, "child_zero_pub": child_zero_pub, } logging.info(f"THis is the transaction data {transaction_data}") transaction_ids, batch_id = await send_create_asset(**transaction_data) if batch_id: logging.info("Create Transaction has been created successfully") ##which imlies the transaction has been submitted successfully, ##now all the changes that are required to be done on the databse can ##be done ##Update users create_asset_idxs key on users entry will be updated by ## whomever will call this, because update can happend on pending_users ## table or users table depending upon user has been claimed or not. ##if transaction was submitted successfully ##Update user entry in the pending_users table of uer_table with the new ##new asset_index in creat_asset_idxs ##insert in asests with new asset created [ transaction_data.pop(field) for field in [ "config", "txn_key", "batch_key", "is_acc_claimed", "flt_account_parent_pub", "flt_account_parent_idx" ] ] transaction_data.update({ "user_id": requester["user_id"], "public": nth_pub, "transaction_id": transaction_ids[0], "batch_id": batch_id, "asset_address": asset_address, "child_zero_pub": child_zero_pub }) ##updating assets table with this new asset await assets_query.store_assets(app, transaction_data) ##updating org_state user_id in users table with new index of asset await accounts_query.update_create_asst_idxs(app, org_state["user_id"], key_index) if child_user_id: ##updating child_user_id user_id in users table with new index of asset await accounts_query.update_create_asst_idxs( app, child_user_id, key_index) #await accounts_query.update_create_asst_idxs_pending(app, #requester["user_id"], key_index) return nth_priv, nth_pub, key_index, asset_address else: logging.error("Create asset Faied, GO to hell Dude!!!!,\ Kabhi kabhi lagta hai ki bhagwan hone ka bhi kya fayda") return
def create_asset(**in_data): """ Inputs will have asset_address, account_address (The key index will be appended to the account address) float_accout (if the user only has a float_account till now, key_index will be appended to the float_account address) child_account_address (In case the asset being created by the child) """ ##TODO: Processor side : Float this asset and make change to create_asset_idxs ## to either float_Account_Address or create_Account_Address depending upon ##whther the user has been claimed or not inputs = [ addresser.create_asset_address( asset_id=in_data["txn_key"].get_public_key().as_hex(), index=in_data["idx"]), ] outputs = [ addresser.create_asset_address( asset_id=in_data["txn_key"].get_public_key().as_hex(), index=in_data["idx"]) ] ##ideally if account is claimed, we should have nothing to do with float account ## but we are sending both addresses to the processor and let processor handle ## the logic i.e float_account should exists and is_claimed shall be true ##to append create_asset_idxs to the account_transaction if not in_data["is_acc_claimed"]: ##implies user havent claimed his float_account_address, so the ## create_asset_idx aill be chnaged on flt_account_addresslogging.info("Float account parent pub %s"%in_data["flt_account_parent_pub"]) logging.info("Float account parent idx %s" % str(in_data["flt_account_parent_idx"])) float_account_address = addresser.float_account_address( account_id=in_data["flt_account_parent_pub"], index=in_data["flt_account_parent_idx"]) inputs.append(float_account_address) outputs.append(float_account_address) else: account_address = addresser.create_organization_account_address( account_id=in_data["zero_pub"], index=0) inputs.append(account_address) outputs.append(account_address) if in_data["child_zero_pub"]: child_address = addresser.child_account_address( account_id=in_data["child_zero_pub"], index=0) inputs.append(child_address) outputs.append(child_address) if in_data["scope"]: scope = payload_pb2.PayloadScope( group=in_data["scope"]["group"], sub_group=in_data["scope"]["sub_group"], field=in_data["scope"]["field"], nature=in_data["scope"]["nature"], operations=in_data["scope"]["operations"], description=in_data["scope"]["description"], ) else: scope = None logging.info(f"Input Address<<{inputs}>>") logging.info(f"Output Address<<{outputs}>>") asset = payload_pb2.CreateAsset( key=in_data["key"], url=in_data["url"], time=in_data["time"], indiantime=in_data["indiantime"], file_name=in_data["file_name"], file_hash=in_data["file_hash"], idx=in_data["idx"], master_key=in_data["master_key"], master_url=in_data["master_url"], role=in_data["role"], scope=scope, zero_pub=in_data["zero_pub"], flt_account_parent_pub=in_data["flt_account_parent_pub"], flt_account_parent_idx=in_data["flt_account_parent_idx"], child_zero_pub=in_data["child_zero_pub"]) logging.info(f"Create asset transaction {asset}") payload = payload_pb2.TransactionPayload( payload_type=payload_pb2.TransactionPayload.CREATE_ASSET, create_asset=asset) return make_header_and_batch(payload=payload, inputs=inputs, outputs=outputs, txn_key=in_data["txn_key"], batch_key=in_data["batch_key"])
def set_asset(self, public, payload): """ payload will have the CreateAsset in the payload public: hex public key with whose private key transaction was signed account: could be a float account or account account_type: could be FLOAT_ACCOUNT or CREATE_ACCOUNT """ logging.info("Payload in set_asset <<{}>>".format(payload)) if payload.flt_account_parent_pub: account_address = addresser.float_account_address( account_id=payload.flt_account_parent_pub, index=payload.flt_account_parent_idx) logging.info("Updating create_asset_idxs in float_account\ at {}".format(account_address)) float_account = self.get_flt_account( public_key=payload.flt_account_parent_pub, index=payload.flt_account_parent_idx) self.update_asset_index(account_address, float_account, payload.idx) else: account_address = addresser.create_organization_account_address( account_id=payload.zero_pub, index=0) logging.info("Updating create_asset_idxs in \ organization_account at {}".format(account_address)) organization_account = self.get_organization( public_key=payload.zero_pub) self.update_asset_index(account_address, organization_account, payload.idx) ##if this is present that means that this asset is being created by child ##of the organization, so the payload.idx needs to be appended to the ##create_asset_idxs array of the child too if payload.child_zero_pub: account_address = addresser.child_account_address( account_id=payload.child_zero_pub, index=0) child_account = self.get_child(payload.child_zero_pub, 0) self.update_asset_index(account_address, child_account, payload.idx) address = addresser.create_asset_address(asset_id=public, index=payload.idx) asset = create_empty_asset() asset.key = payload.key asset.url = payload.url asset.time = payload.time asset.indiantime = payload.indiantime asset.file_name = payload.file_name asset.file_hash = payload.file_hash asset.idx = payload.idx asset.master_key = payload.master_key asset.master_url = payload.master_url asset.expired_on = payload.expired_on asset.role = payload.role asset.public = public asset.child_zero_pub = payload.child_zero_pub if payload.scope: asset.scope.group = payload.scope.group asset.scope.sub_group = payload.scope.sub_group asset.scope.field = payload.scope.field asset.scope.nature = payload.scope.nature asset.scope.operations = payload.scope.operations asset.scope.description = payload.scope.description logging.info(asset) logging.info("Account after serialization %s", asset.SerializeToString()) return self._context.set_state({address: asset.SerializeToString()}, self._timeout)