Beispiel #1
0
    def post(self):
        """
        Return the balance for a given wallet. The bitcoin balance
        is only available when the wallet has a server-controlled cosigner.

        Parameters required from the client:
            * id [text]    - wallet ID
        """
        wallet_id = g.payload.get('id', '').encode('ascii')
        if not wallet_id:
            return current_app.encode_error(Errors.MissingArguments)

        # Get the cosigner for this wallet for this user.
        record = current_app.session.query(db.CosignerWallet).filter(
            db.CosignerWallet.user_id == current_user.id,
            db.CosignerWallet.wallet_id == wallet_id).one_or_none()
        if record is None:
            return current_app.encode_error(Errors.CosignerNotFound)

        # Send the request to the cosigning server.
        logging.info('still here')
        resp = current_app.cosigner('/balance', wallet=record.wallet)
        logging.info('result %s', resp)
        if 'balance' in resp:
            data = {'btc': resp['balance']}
            result = current_app.encode_success(data)
        else:
            logging.error(resp)
            result = current_app.encode_error(Errors.CosignerError)

        return result
Beispiel #2
0
    def post(self):
        """
        Return the balance for a given wallet. The bitcoin balance
        is only available when the wallet has a server-controlled cosigner.

        Parameters required from the client:
            * id [text]    - wallet ID
        """
        wallet_id = g.payload.get('id', '').encode('ascii')
        if not wallet_id:
            return current_app.encode_error(Errors.MissingArguments)

        # Get the cosigner for this wallet for this user.
        record = current_app.session.query(db.CosignerWallet).filter(
            db.CosignerWallet.user_id == current_user.id,
            db.CosignerWallet.wallet_id == wallet_id).one_or_none()
        if record is None:
            return current_app.encode_error(Errors.CosignerNotFound)

        # Send the request to the cosigning server.
        logging.info('still here')
        resp = current_app.cosigner('/balance', wallet=record.wallet)
        logging.info('result %s', resp)
        if 'balance' in resp:
            data = {'btc': resp['balance']}
            result = current_app.encode_success(data)
        else:
            logging.error(resp)
            result = current_app.encode_error(Errors.CosignerError)

        return result
Beispiel #3
0
    def put(self):
        # XXX not implemented in the client yet.
        """
        Update an existing blob for this user.

        Parameters required from the client:
            * id [text]   - blob UUID
            * blob [text] - blob to replace the one previously stored

        Returns:
            the new blob
        """
        blob = g.payload.get('blob', '').encode('ascii')
        blob_id = g.payload.get('id', '').encode('ascii')
        if not blob or not blob_id:
            # No blob specified.
            return current_app.encode_error(Errors.MissingArguments)
        elif len(blob) > MAX_BLOBLEN:
            # Blob size is too big.
            return current_app.encode_error(Errors.BlobTooLong)

        # Update the blob that belongs to this user only if this new one
        # is greater (in size) than the current one.
        record = current_app.session.query(db.WalletBlob).filter(
            db.WalletBlob.user_id == current_user.id,
            db.WalletBlob.updates_left > 0,
            db.func.char_length(db.WalletBlob.blob) < len(blob)).update({
                'updates_left':
                db.WalletBlob.updates_left - 1,
                'blob':
                blob
            })
        result = format_blob(record).next()
        return current_app.encode_success(result)
Beispiel #4
0
    def get(self):
        """
        Return the salt and iteration count (for PBKDF2) for this user.

        Parameters required from the client:
            * username [text]
            * check    [text] - 6 hexadecimal digits

        Returns:
            * salt       [text]   - hexadecimal digits
            * iterations [integer]
        """
        username = request.args.get('username').encode('utf8')
        bcheck = request.args.get('check').encode('ascii')
        if not username or len(bcheck) != 6:
            return current_app.encode_error(Errors.MissingArguments)

        user = current_app.session.query(db.User).filter(
            db.User.username == username,
            db.User.user_check == bcheck).one_or_none()
        if user is None:
            return current_app.encode_error(Errors.UserNotFound)

        result = {'salt': user.salt, 'iterations': user.itercount}
        return current_app.encode_success(result)
Beispiel #5
0
    def put(self):
        # XXX not implemented in the client yet.
        """
        Update an existing blob for this user.

        Parameters required from the client:
            * id [text]   - blob UUID
            * blob [text] - blob to replace the one previously stored

        Returns:
            the new blob
        """
        blob = g.payload.get('blob', '').encode('ascii')
        blob_id = g.payload.get('id', '').encode('ascii')
        if not blob or not blob_id:
            # No blob specified.
            return current_app.encode_error(Errors.MissingArguments)
        elif len(blob) > MAX_BLOBLEN:
            # Blob size is too big.
            return current_app.encode_error(Errors.BlobTooLong)

        # Update the blob that belongs to this user only if this new one
        # is greater (in size) than the current one.
        record = current_app.session.query(db.WalletBlob).filter(
            db.WalletBlob.user_id == current_user.id,
            db.WalletBlob.updates_left > 0,
            db.func.char_length(db.WalletBlob.blob) < len(blob)).update({
                'updates_left': db.WalletBlob.updates_left - 1,
                'blob': blob})
        result = format_blob(record).next()
        return current_app.encode_success(result)
Beispiel #6
0
    def get(self):
        """
        Return the salt and iteration count (for PBKDF2) for this user.

        Parameters required from the client:
            * username [text]
            * check    [text] - 6 hexadecimal digits

        Returns:
            * salt       [text]   - hexadecimal digits
            * iterations [integer]
        """
        username = request.args.get('username').encode('utf8')
        bcheck = request.args.get('check').encode('ascii')
        if not username or len(bcheck) != 6:
            return current_app.encode_error(Errors.MissingArguments)

        user = current_app.session.query(db.User).filter(
            db.User.username == username,
            db.User.user_check == bcheck).one_or_none()
        if user is None:
            return current_app.encode_error(Errors.UserNotFound)

        result = {'salt': user.salt, 'iterations': user.itercount}
        return current_app.encode_success(result)
Beispiel #7
0
    def post(self):
        """
        Create new address(es). This only available when the wallet has
        a server-controlled cosigner.

        Parameters required from the client:
            * id [text]    - wallet ID

        Optional parameters:
            * num [number] - number of addresses to obtain
                             (max: 100, default: 1)
        """
        num = int(g.payload.get('num', 1))
        wallet_id = g.payload.get('id', '').encode('ascii')
        if not wallet_id:
            return current_app.encode_error(Errors.MissingArguments)
        if num <= 0 or num > MAX_NEWADDRESS:
            return current_app.encode_error(Errors.InvalidAddressCount)

        # Get the cosigner for this wallet for this user.
        record = current_app.session.query(db.CosignerWallet).filter(
            db.CosignerWallet.user_id == current_user.id,
            db.CosignerWallet.wallet_id == wallet_id).one_or_none()
        if record is None:
            return current_app.encode_error(Errors.CosignerNotFound)

        # Send the request to the cosigning server.
        resp = current_app.cosigner('/address/new',
                                    num=num,
                                    wallet=record.wallet)

        if 'address' in resp:
            keys = ['address', 'path', 'createdOn']
            if isinstance(resp['address'], dict):
                # Single address derived.
                keys.append('walletId')
                data = {key: resp['address'][key] for key in keys}
            else:
                # Multiple addresses.
                data = {
                    'walletId': resp['address'][0]['walletId'],
                    'result': None
                }
                data['result'] = [{key: entry[key]
                                   for key in keys}
                                  for entry in resp['address']]
            result = current_app.encode_success(data)
        else:
            logging.error(resp)
            result = current_app.encode_error(Errors.CosignerError)

        return result
Beispiel #8
0
def insert(record):
    session = current_app.session
    session.add(record)
    try:
        session.commit()
        return current_app.encode_success()
    except Exception:
        logging.exception("Failed to commit cowallet record")
        session.rollback()
        resp = current_app.encode_error(Errors.GenericError)
        return resp
    finally:
        session.close()
Beispiel #9
0
def insert(record):
    session = current_app.session
    session.add(record)
    try:
        session.commit()
        return current_app.encode_success()
    except Exception:
        logging.exception("Failed to commit cowallet record")
        session.rollback()
        resp = current_app.encode_error(Errors.GenericError)
        return resp
    finally:
        session.close()
Beispiel #10
0
    def post(self):
        """
        Create new address(es). This only available when the wallet has
        a server-controlled cosigner.

        Parameters required from the client:
            * id [text]    - wallet ID

        Optional parameters:
            * num [number] - number of addresses to obtain
                             (max: 100, default: 1)
        """
        num = int(g.payload.get('num', 1))
        wallet_id = g.payload.get('id', '').encode('ascii')
        if not wallet_id:
            return current_app.encode_error(Errors.MissingArguments)
        if num <= 0 or num > MAX_NEWADDRESS:
            return current_app.encode_error(Errors.InvalidAddressCount)

        # Get the cosigner for this wallet for this user.
        record = current_app.session.query(db.CosignerWallet).filter(
            db.CosignerWallet.user_id == current_user.id,
            db.CosignerWallet.wallet_id == wallet_id).one_or_none()
        if record is None:
            return current_app.encode_error(Errors.CosignerNotFound)

        # Send the request to the cosigning server.
        resp = current_app.cosigner(
            '/address/new', num=num, wallet=record.wallet)

        if 'address' in resp:
            keys = ['address', 'path', 'createdOn']
            if isinstance(resp['address'], dict):
                # Single address derived.
                keys.append('walletId')
                data = {key: resp['address'][key] for key in keys}
            else:
                # Multiple addresses.
                data = {
                    'walletId': resp['address'][0]['walletId'],
                    'result': None
                }
                data['result'] = [{key: entry[key] for key in keys}
                        for entry in resp['address']]
            result = current_app.encode_success(data)
        else:
            logging.error(resp)
            result = current_app.encode_error(Errors.CosignerError)

        return result
Beispiel #11
0
    def post(self):
        """Return the blobs stored for this user."""
        only_count = int(g.payload.get('count', 0))

        blobs = current_app.session.query(
            db.WalletBlob).filter(db.WalletBlob.user_id == current_user.id)

        if only_count:
            # Return the number of blobs stored.
            result = {'num': blobs.count()}
        else:
            # Return the actual blobs.
            result = list(format_blob(*blobs))

        return current_app.encode_success(result)
Beispiel #12
0
    def post(self):
        """Return the blobs stored for this user."""
        only_count = int(g.payload.get('count', 0))

        blobs = current_app.session.query(db.WalletBlob).filter(
            db.WalletBlob.user_id == current_user.id)

        if only_count:
            # Return the number of blobs stored.
            result = {'num': blobs.count()}
        else:
            # Return the actual blobs.
            result = list(format_blob(*blobs))

        return current_app.encode_success(result)
Beispiel #13
0
    def post(self):
        # XXX blob update not implemented yet.
        """
        Store or update a blob for this user.

        Parameters required from the client:
            * id [text]   - an UUID (assumed to be a wallet ID)
            * blob [text] - blob to be stored

        Optional parameters:
            * maxchanges [integer] - maximum number of changes accepted for
                                     this blob, no more than 32

        Returns:
            * id [text]            - id for the blob stored
            * blob [text]          - the blob stored
            * created_at [integer] - creation time as a unix timestamp
        """
        maxchanges = min(int(g.payload.get('maxchanges', '32')), 32)
        blob = g.payload.get('blob', '').encode('ascii')
        # Blob ID is used internally as a reference to the Wallet record
        # stored in the MongoDB by bitcore-wallet-service.
        # The default client implementation passes that UUID as this id,
        # but it is not enforced.
        blob_id = g.payload.get('id', '').encode('ascii')

        if not blob or not blob_id or len(blob_id) != 36:
            # No blob specified.
            return current_app.encode_error(Errors.MissingArguments)
        elif len(blob) > MAX_BLOBLEN:
            # Blob size is too big.
            return current_app.encode_error(Errors.BlobTooLong)

        blob_count = current_app.session.query(db.WalletBlob).filter(
            db.WalletBlob.user_id == current_user.id).count()
        if blob_count >= MAX_BLOBCOUNT:
            # This user has stored too many blobs already.
            return current_app.encode_error(Errors.TooManyBlobs)

        record = db.WalletBlob(id=blob_id,
                               user_id=current_user.id,
                               updates_left=maxchanges,
                               blob=blob)
        current_app.session.add(record)
        current_app.session.commit()

        result = format_blob(record).next()
        return current_app.encode_success(result)
Beispiel #14
0
    def post(self):
        # XXX blob update not implemented yet.
        """
        Store or update a blob for this user.

        Parameters required from the client:
            * id [text]   - an UUID (assumed to be a wallet ID)
            * blob [text] - blob to be stored

        Optional parameters:
            * maxchanges [integer] - maximum number of changes accepted for
                                     this blob, no more than 32

        Returns:
            * id [text]            - id for the blob stored
            * blob [text]          - the blob stored
            * created_at [integer] - creation time as a unix timestamp
        """
        maxchanges = min(int(g.payload.get('maxchanges', '32')), 32)
        blob = g.payload.get('blob', '').encode('ascii')
        # Blob ID is used internally as a reference to the Wallet record
        # stored in the MongoDB by bitcore-wallet-service.
        # The default client implementation passes that UUID as this id,
        # but it is not enforced.
        blob_id = g.payload.get('id', '').encode('ascii')

        if not blob or not blob_id or len(blob_id) != 36:
            # No blob specified.
            return current_app.encode_error(Errors.MissingArguments)
        elif len(blob) > MAX_BLOBLEN:
            # Blob size is too big.
            return current_app.encode_error(Errors.BlobTooLong)

        blob_count = current_app.session.query(db.WalletBlob).filter(
            db.WalletBlob.user_id == current_user.id).count()
        if blob_count >= MAX_BLOBCOUNT:
            # This user has stored too many blobs already.
            return current_app.encode_error(Errors.TooManyBlobs)

        record = db.WalletBlob(id=blob_id, user_id=current_user.id,
                               updates_left=maxchanges, blob=blob)
        current_app.session.add(record)
        current_app.session.commit()

        result = format_blob(record).next()
        return current_app.encode_success(result)
Beispiel #15
0
def signup_insert(records):
    session = current_app.session
    session.add_all(records)
    try:
        session.commit()
        return current_app.encode_success()
    except Exception as err:
        logging.exception("Failed to commit user records")
        session.rollback()

        if (isinstance(err, db.IntegrityError)
                and 'username' in err.orig.message):
            # Username already in use
            resp = current_app.encode_error(Errors.InvalidUsername)
        else:
            resp = current_app.encode_error(Errors.GenericError)

        return resp
    finally:
        session.close()
Beispiel #16
0
def signup_insert(records):
    session = current_app.session
    session.add_all(records)
    try:
        session.commit()
        return current_app.encode_success()
    except Exception as err:
        logging.exception("Failed to commit user records")
        session.rollback()

        if (isinstance(err, db.IntegrityError)
                and 'username' in err.orig.message):
            # Username already in use
            resp = current_app.encode_error(Errors.InvalidUsername)
        else:
            resp = current_app.encode_error(Errors.GenericError)

        return resp
    finally:
        session.close()