async def __send_user_account(**in_data):
    """

    """
    inputs = [
        addresser.user_address(
            public=in_data["txn_key"].get_public_key().as_hex(), index=0),
    ]

    outputs = [
        addresser.user_address(
            public=in_data["txn_key"].get_public_key().as_hex(), index=0),
    ]

    account = payload_pb2.CreateUserAccount(
        role=in_data["role"],
        phone_number=in_data["phone_number"],
        pancard=in_data["pancard"],
        first_name=in_data["first_name"],
        last_name=in_data["last_name"],
        user_id=in_data["user_id"],
        email=in_data["email"],
        time=in_data["time"],
        indian_time=in_data["indian_time"],
        deactivate=in_data["deactivate"],
        deactivate_on=in_data["deactivate_on"],
    )

    logging.info(account)
    logging.info(f"THe address for the user on blockchain {inputs[0]}")

    payload = payload_pb2.TransactionPayload(
        payload_type=payload_pb2.TransactionPayload.CREATE_USER_ACCOUNT,
        create_user_account=account)

    logging.info(payload)
    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'))
        raise err
        return False, False

    return transaction_ids, batch_id
    def get_user(self, public_key):
        try:
            address = addresser.user_address(public=public_key, index=0)
        except Exception as e:
            logging.error(e)
            raise InvalidTransaction("get_user error =={}".format(e))

        ##entries will be a weird list of the form
        ##[address: "318c9fa5d39e9ccd2769115795e384b8e83b3267172ae518136ac49ddc5adf71d87814"
        ##data: "\nB02dbf0f4a3defef38df754122ef7c10fee6a4bb363312367524f86d230e205d459\022$b6de5d5b-7870-49df-971e-0885986bfa96\032
        ##\006seller\"\021978-0-9956537-6-4*\0161-191-790-04532\r1-932866-82-5:\001\000"]

        entries = self._context.get_state(addresses=[address],
                                          timeout=self._timeout)

        logging.info("ENtries correspoding to user account address \
                {} are {}".format(address, entries))
        try:
            entry = entries[0]
        except Exception as e:
            logging.info(
                "No user account with address {} and publickey {} can be \
                        found".format(address, public_key))
            return False

        account = empty_user()
        account.ParseFromString(entry.data)
        logging.info("This is the account at {} stored on blockchain \
                                {}".format(address, account))
        return account
    def set_user(self, public_key, payload):
        if "" in [
                payload.first_name, payload.last_name, payload.email,
                payload.phone_number
        ]:
            raise InvalidTransaction('shouldnt be left empty')

        address = addresser.user_address(public_key, 0)

        logging.info("THis is the user address {}".format(address))
        user = empty_user()
        user.public = public_key
        user.role = payload.role
        user.phone_number = payload.phone_number
        user.pancard = payload.pancard
        user.user_id = payload.user_id
        user.email = payload.email
        user.first_name = payload.first_name
        user.last_name = payload.last_name
        user.time = payload.time
        user.indian_time = payload.indian_time
        user.deactivate = payload.deactivate
        user.deactivate_on = payload.deactivate_on

        logging.info("User before serialization %s", user)
        return self._context.set_state({address: user.SerializeToString()},
                                       self._timeout)
    async def user_details(self, public):
        user_address = addresser.user_address(public, 0)

        user_state = await deserialize_state.deserialize_user(
            self.app.config.REST_API_URL, user_address)

        user_db = await accounts_query.find_on_key(self.app, "user_id",
                                                   user_state["user_id"])
        return user_address, user_state, user_db
Exemple #5
0
async def forgot_password(request):
    """
    This api will be used when the user forgot their password
    and they have chosed the second option where they have stored their mnemonic
    with other users on the blockchain.
    """

    required_fields = ["email", "otp_email", "phone_number", "otp_mobile", "new_password"]

    validate_fields(required_fields, request.json)

    required_pattern = re.compile('(?=.{6,})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@#$%^&*()])')
    if not required_pattern.match(request.json["new_password"]) or \
                        len(request.json["new_password"]) <= 8:
            raise errors.PasswordStrengthError()



    account_db = await accounts_query.find_user(request.app, request.json["phone_number"],
                        request.json["email"])

    if not account_db:
        raise CustomError("This user doesnt exists, Please register first")

    otp_email = int(request.json["otp_email"])
    otp_mobile = int(request.json["otp_mobile"])

    await verify_otp(request.app, otp_email, request.json["email"],
                        otp_mobile, request.json["phone_number"])

    if account_db["role"] == "USER":
        address = addresser.user_address(account_db["acc_zero_pub"], 0)
        state = await deserialize_state.deserialize_user(
                        request.app.config.REST_API_URL,
                        address)

        logging.info(state)

        await activate_secret_batch_submit(request.app, account_db, request.json["new_password"])
    elif account_db["role"] == "ORGANIZATION":
        address = addresser.organization_address(account_db["acc_zero_pub"], 0)

    elif account_db["role"] == "CHILD":
        ##TODO
        pass
    else:
        raise CustomError("Undefined role for this user")


    logging.info(state)

    return response.json(
               {
                'error': False,
                'success': True,
                'message': "Success",
                })
async def share_secret_batch_submit(app, requester, receive_secrets,
                                    nth_keys_data):
    """
    Args:
        requester(dict): db entry of the user who is sharing the Menmonic
        receive_secrets(list of dictionaies): The recieve_secret transactions present
                        on the the blockchain with whom the user wants to share
                        the mnemonic, this has three addtional keys
                        salt (hex encoded): THe salt used, while encrypting mnemonic
                            share with scrypt ket generated from user email
                        address(string): address of the receive secret on blockchain
                        secret(hex encoded): hex encoded encrypted secret

        nth_keys_data(dict with keys as random indexes): The Pub/Priv key pairs
                    generated from the random indexes generated from the user mnemonic
                    who wants to share his/her mnemonic, the pub/priv keys are ecc keys
                    fetched from go_api
    All the trasactions will be packaged into a batch and then will be submitted to the ledger,
    If one transaction fails, All transaction will fail as per the property
    of hyperledger sawtooth
    Output:
        True if all the trasactions in a batch will be submitted
        False if there is any error
    """

    if requester["role"] == "USER":
        requester_address = addresser.user_address(requester["acc_zero_pub"],
                                                   0)
    else:
        logging.error("NOt implemented yet")

    async with aiohttp.ClientSession() as session:
        transactions = await asyncio.gather(*[
            submit_share_secret(
                app, requester, requester_address, receive_secret, int(
                    index), nth_keys_data[index]["private_key"])
            for (receive_secret,
                 index) in zip(receive_secrets, list(nth_keys_data.keys()))
        ])

    batch_id, batch_bytes = multi_transactions_batch(
        [e["transaction"] for e in transactions], app.config.SIGNER)
    """
    for e in [e["transaction"] for e in transactions]:
        logging.info(e)
    """

    instance = await SendTransactions(app.config.REST_API_URL,
                                      app.config.TIMEOUT)
    await instance.push_n_wait(batch_bytes, batch_id)

    return batch_id, transactions
Exemple #7
0
async def all_share_secrets(request, requester):
    """

    Result will have two keys,
    floated and received,
    floated will have all the shared_secret addresses that this user have floated
    and have his encryptes mnemonic distribution

    the received is all the shared_Secret_addresses that have shared with him,
    This information can only be pulled from database right now but
    sawtooth events will be used later
    """

    if requester["role"] == "USER":
        address = addresser.user_address(requester["acc_zero_pub"], 0)
        account = await deserialize_state.deserialize_user(request.app.config.REST_API_URL, address)

    else:
        logging.error("Not implemented yet")
        raise errors.ApiInternalError("This functionality is not implemented yet")



    logging.info(account)
    floated = account.get("share_secret_addresses")
    floated_result = []
    if floated:
        #implies that user has already have created shared_secrets contracts and
        ##this array have the addresses of the shared_secrets
        async with aiohttp.ClientSession() as session:
            floated_result= await asyncio.gather(*[
                deserialize_state.deserialize_share_secret(
                        request.app.config.REST_API_URL, address)
                    for address in floated
            ])

    received_result =await get_addresses_on_ownership(request.app, address)



    return response.json(
            {
            'error': False,
            'success': True,
            "data": {"floated": floated_result, "received": [received_result]},
            })
    async def _address_account(self):
        """
        Find address and account of the requester based on their role,
        the address and their blockchain state will be different for the
        user and organization role.

        """
        if self.requester["role"] == "USER":
            account_address = addresser.user_address(
                                        self.requester["acc_zero_pub"], 0)
            account_state = await deserialize_state.deserialize_user(
                                    self.app.config.REST_API_URL,
                                    account_address)

        else:
            logger.error("Not implemented yet")
            raise errors.ApiInternalError("This functionality is not implemented yet")

        return account_address, account_state
Exemple #9
0
async def receive_secret(request, requester):
    """
    Wheneve a user shares their secret with other users, the user must
    have a receive_secret address, which must be generated from his mnemonic
    at some random index, this index will then be appended to users receive_secret_idxs
    array
    """


    if requester["role"] == "USER":
        requester_address = addresser.user_address(requester["acc_zero_pub"], 0)
    else:
        ##handle case for organization
        pass

    ##resolving account for the requester to get his decrypted menmonic
    user = await ResolveAccount(requester, request.app)
    logging.info(user.decrypted_mnemonic)


    if user.org_state.get("receive_secret_idxs"):
        if len(user.org_state.get("receive_secret_idxs"))  >= \
                                        request.app.config.MAX_RECEIVE_SECRET:
            raise errors.ApiInternalError("Maximum amount of rceive_secret \
                                addresses limit reached")

    data = await submit_receive_secret(request.app, requester["user_id"],
                    user.org_state,
                    requester_address, user.decrypted_mnemonic)

    return response.json(
        {
        'error': False,
        'success': True,
        "data": data
        })
async def activate_secret_batch_submit(app, requester, password):

    ##the share_secret transaction were floated, depending upon the
    ##number of other users, our user has chosen who will have the secret shares
    ##of our users mnemonic

    #every share_secret transaction have ownership, address of other user account
    ## secret hash, hash of the secret_share
    ##key, particular key that was originally created to encrypt a particular share
    ##    of particuar user, this key will be different for every user with whom
    ##     secret share of menmonic was shared

    ##Now, the user has forgotten their password , Now based on their email address,
    ## the user will generate different AES keys, depending upon the number of users
    ##with whom he has shared their menmonic
    """
    Steps:
            Retrive number of users account addresses in the shared_secret array
            of the user,

            Generate that numbers of Scrypt keys from the password wth different salts
            these salts will then be stored in the user accounts, just using these
            salts admin cant decrypt the mnemonic

    """
    ##must be intialized
    db_instance = await DBSecrets(
        app,
        table_name="share_secret",
        array_name="share_secret_addresses",
    )

    requester_address = addresser.user_address(requester["acc_zero_pub"], 0)

    ##get user account from the blokchain, its shared_secret will have all share_secret
    ##addresses
    requester_state = await deserialize_state.deserialize_user(
        app.config.REST_API_URL, requester_address)

    ##allt he shared_secret_addresses for the user
    share_secret_addresses = requester_state["share_secret_addresses"]

    ##Deserializing all the shared_secret transaction present on the blockchain
    ## i.e all the data corresponding to the share_secret_addresses list of addresses
    async with aiohttp.ClientSession() as session:
        share_secret_transactions = await asyncio.gather(*[
            deserialize_state.deserialize_share_secret(app.config.REST_API_URL,
                                                       address)
            for address in share_secret_addresses
        ])

    ##now every share_Secret transaction as a key called as ownership which is
    ##actually an addresss of the receive_Secret transaction, Now appending
    ##public key of that receive_Secret transaction to the transaction data
    for transaction in share_secret_transactions:
        receive_secret = await deserialize_state.deserialize_receive_secret(
            app.config.REST_API_URL, transaction["ownership"])
        transaction.update({"owner_public": receive_secret["public"]})

    async with aiohttp.ClientSession() as session:
        transactions = await asyncio.gather(*[
            submit_activate_secret(app, transaction, password)
            for transaction in share_secret_transactions
        ])

    instance = await SendActivateSecret(app.config.REST_API_URL,
                                        app.config.TIMEOUT)
    batch_id, batch_list_bytes = await instance.push_batch(
        [e["transaction"] for e in transactions], app.config.SIGNER)

    try:
        for transaction in transactions:
            transaction.update({
                "batch_id": batch_id,
                "user_id": requester["user_id"]
            })
            await db_instance.update_reset_key(app, transaction)

    except Exception as e:
        logging.error(e)
        raise CustomError(e)
    return True
Exemple #11
0
async def conclude_secret_batch_submit(app, requester, mnemonic):

    ##the share_secret transaction were floated, depending upon the
    ##number of other users, our user has chosen who will have the secret shares
    ##of our users mnemonic

    #every share_secret transaction have ownership, address of other user account
    ## secret hash, hash of the secret_share
    ##key, particular key that was originally created to encrypt a particular share
    ##    of particuar user, this key will be different for every user with whom
    ##     secret share of menmonic was shared

    ##Now, the user has forgotten their password , Now based on their email address,
    ## the user will generate different AES keys, depending upon the number of users
    ##with whom he has shared their menmonic
    """
    Steps:
            Retrive number of users account addresses in the shared_secret array
            of the user,

            Generate that numbers of Scrypt keys from the password wth different salts
            these salts will then be stored in the user accounts, just using these
            salts admin cant decrypt the mnemonic

    """
    ##must be intialized

    requester_address = addresser.user_address(requester["acc_zero_pub"], 0)

    ##get user account from the blokchain, its shared_secret will have all share_secret
    ##addresses
    requester_state = await deserialize_state.deserialize_user(
        app.config.REST_API_URL, requester_address)

    ##allt he shared_secret_addresses for the user
    share_secret_addresses = requester_state["share_secret_addresses"]

    ##Deserializing all the shared_secret transaction present on the blockchain
    ## i.e all the data corresponding to the share_secret_addresses list of addresses
    async with aiohttp.ClientSession() as session:
        share_secret_transactions = await asyncio.gather(*[
            deserialize_state.deserialize_share_secret(app.config.REST_API_URL,
                                                       address)
            for address in share_secret_addresses
        ])

    indexes = [e["idx"] for e in share_secret_transactions]
    indexes.append(0)
    nth_keys = await remote_calls.key_index_keys(app, mnemonic, indexes)

    zeroth_priv, zeroth_pub = nth_keys[str(0)]["private_key"], nth_keys[str(
        0)]["public_key"]

    for share_secret_state in share_secret_transactions:
        logger.info(nth_keys[str(share_secret_state["idx"])]["private_key"])

    async with aiohttp.ClientSession() as session:
        transactions = await asyncio.gather(*[
            submit_conclude_secret(
                app, requester_address, share_secret_state, zeroth_priv,
                nth_keys[str(share_secret_state["idx"])]["private_key"])
            for share_secret_state in share_secret_transactions
        ])

    logger.info(nth_keys)

    instance = await SendConcludeSecret(app.config.REST_API_URL,
                                        app.config.TIMEOUT)
    batch_id, batch_list_bytes = await instance.push_batch(
        [e["transaction"] for e in transactions], app.config.SIGNER)
    return batch_id