Пример #1
0
def add_bh_offer_api():
    """adds a blackhawk offer to the db. the offer_id must already exist in the offers table"""
    if not config.DEBUG:
        limit_to_localhost()

    try:
        payload = request.get_json(silent=True)
        offer_id = payload.get('offer_id', None)
        merchant_code = payload.get('merchant_code', None)
        merchant_template_id = payload.get('merchant_template_id', None)
        batch_size = payload.get('batch_size', None)
        denomination = payload.get('denomination', None)
        minimum_threshold = payload.get('minimum_threshold', None)
        if None in (offer_id, merchant_code, merchant_template_id, batch_size,
                    denomination, minimum_threshold):
            raise InvalidUsage('bad-request')
    except Exception as e:
        print(e)
        raise InvalidUsage('bad-request')

    if create_bh_offer(offer_id, merchant_code, merchant_template_id,
                       batch_size, denomination, minimum_threshold):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to add blackhawk offer')
Пример #2
0
def register():
    ''' register a user to the system. 
    called once by every client until 200OK is received from the server.
    the payload may contain a optional push token.
    '''
    payload = request.get_json(silent=True)
    try:
        user_id = payload.get('user_id', None)
        os = payload.get('os', None)
        device_model = payload.get('device_model', None)
        token = payload.get('token', None)
        time_zone = payload.get('time_zone', None)
        device_id = payload.get('device_id', None)
        app_ver = payload.get('app_ver', None)
        #TODO more input check on the values
        if None in (
                user_id, os, device_model, time_zone, app_ver
        ):  # token is optional, device-id is required but may be None
            raise InvalidUsage('bad-request')
        if os not in ('iOS', 'android'):
            raise InvalidUsage('bad-request')
        user_id = UUID(user_id)  # throws exception on invalid uuid
    except Exception as e:
        raise InvalidUsage('bad-request')
    else:
        try:
            create_user(user_id, os, device_model, token, time_zone, device_id,
                        app_ver)
        except InvalidUsage as e:
            raise InvalidUsage('duplicate-userid')
        else:
            print('created user with user_id %s' % (user_id))
            return jsonify(status='ok')
Пример #3
0
def user_ids_list_blacklist_endpoint():
    """ block a list of users by there ids"""
    if not config.DEBUG:
        limit_to_localhost()
    try:
        payload = request.get_json(silent=True)
        user_ids = payload.get('user_ids', None)

        if user_ids is None:
            print('user_ids_list_blacklist_endpoint: ids: %s' % user_ids)
            raise InvalidUsage('bad-request')

        blacklisted, unable_to_blacklist, already_blacklisted, no_phone_number = [],[],[],[]
        for user_id in user_ids:
            user = get_user(user_id)
            if not user.enc_phone_number:
                no_phone_number.append(user_id)

            elif is_enc_phone_number_blacklisted(user.enc_phone_number):
                already_blacklisted.append(user_id)

            elif not blacklist_enc_phone_number(user.enc_phone_number):
                unable_to_blacklist.append(user_id)  # for later retry

            else:
                blacklisted.append(user_id)

        return jsonify(blacklisted=blacklisted,
                       already_blacklisted=already_blacklisted,
                       unable_to_blacklist=unable_to_blacklist)

    except Exception as e:
        print(e)
        raise InvalidUsage('bad-request')
Пример #4
0
def quest_answers():
    '''receive the results for a tasks and pay the user for them'''
    payload = request.get_json(silent=True)
    try:
        user_id = extract_header(request)
        task_id = payload.get('id', None)
        address = payload.get('address', None)
        results = payload.get('results', None)
        send_push = payload.get('send_push', True)
        if None in (user_id, task_id, address, results):
            raise InvalidUsage('bad-request')
        #TODO more input checks here
    except Exception as e:
        raise InvalidUsage('bad-request')

    if not store_task_results(user_id, task_id, results):
        # should never happen: the client sent the results too soon
        print('rejecting user %s task %s results' % (user_id, task_id))
        increment_metric('premature_task_results')
        return jsonify(status='error',
                       reason='cooldown_enforced'), status.HTTP_400_BAD_REQUEST
    try:
        memo = utils.KINIT_MEMO_PREFIX + str(uuid4(
        ))[:utils.
           ORDER_ID_LENGTH]  # generate a memo string and send it to the client
        reward_store_and_push(address, task_id, send_push, user_id, memo)
    except Exception as e:
        print('exception: %s' % e)
        print('failed to reward task %s at address %s' % (task_id, address))

    increment_metric('task_completed')
    return jsonify(status='ok', memo=str(memo))
Пример #5
0
def purchase_api():
    '''process the given tx_hash and return the payed-for goods'''

    #TODO: at some point we should try to listen in on incoming tx_hashes
    # for our account(s). this should hasten the process of reedeming offers.
    payload = request.get_json(silent=True)
    try:
        user_id = extract_header(request)
        tx_hash = payload.get('tx_hash', None)
        if None in (user_id, tx_hash):
            raise InvalidUsage('invalid param')
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')

    try:
        # process the tx_hash, provided its not already being processed by another server
        lock = redis_lock.Lock(app.redis, 'redeem:%s' % tx_hash)
        if lock.acquire(blocking=False):
            success, goods = process_order(user_id, tx_hash)
            if not success:
                raise InvalidUsage('cant redeem with tx_hash:%s' % tx_hash)
            increment_metric('offers_redeemed')
            return jsonify(status='ok', goods=goods)
        else:
            return jsonify(status='error', reason='already processing tx_hash')
    finally:
        lock.release()
Пример #6
0
def get_cost_and_address(offer_id):
    '''return the kin cost and address associated with this offer'''
    offer = Offer.query.filter_by(offer_id=offer_id).first()
    if not offer:
        raise InvalidUsage('no such offer_id')
    if not offer.is_active:
        raise InvalidUsage('offer is not active')
    return offer.kin_cost, offer.address
Пример #7
0
def get_offers_api():
    '''return the list of availble offers for this user'''
    try:
        user_id = extract_header(request)
        if user_id is None:
            raise InvalidUsage('no user_id')
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
        print('offers %s' % get_offers_for_user(user_id))
    return jsonify(offers=get_offers_for_user(user_id))
Пример #8
0
def add_task_api():
    #limit_to_local_host()
    payload = request.get_json(silent=True)
    try:
        task = payload.get('task', None)
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if add_task(task):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to add task')
Пример #9
0
def send_gcm_push():
    '''temp endpoint for testing gcm TODO remove'''
    payload = request.get_json(silent=True)
    try:
        push_payload = payload.get('push_payload', None)
        push_token = payload.get('push_token', None)
        if None in (push_token, push_payload):
            raise InvalidUsage('bad-request')
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    send_gcm(push_token, push_payload)
    return jsonify(status='ok')
Пример #10
0
def update_token():
    ''' update a user's token in the database '''
    payload = request.get_json(silent=True)
    try:
        user_id = extract_header(request)
        token = payload.get('token', None)
        if None in (user_id, token):
            raise InvalidUsage('bad-request')
    except Exception as e:
        raise InvalidUsage('bad-request')
    print('updating token for user %s' % user_id)
    update_user_token(user_id, token)
    return jsonify(status='ok')
Пример #11
0
def update_task_time_endpoint():
    '''temp endpoint for setting a task time TODO DELETE ME'''
    payload = request.get_json(silent=True)
    try:
        task_id = str(payload.get('task_id', None))
        time_string = str(payload.get('time_string', None))
        if None in (task_id, time_string):
            raise InvalidUsage('bad-request')
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')

    update_task_time(task_id, time_string)
    return jsonify(status='ok')
Пример #12
0
def add_offer_api():
    '''endpoint used to populate the server with offers'''
    if not config.DEBUG:
        limit_to_local_host()
    payload = request.get_json(silent=True)
    try:
        offer = payload.get('offer', None)
        set_active = payload.get('set_active', False)  # optional
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if add_offer(offer, set_active):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to add offer')
Пример #13
0
def set_active_app_discovery_api():
    """ enable/ disable discovery app"""
    if not config.DEBUG:
        limit_to_localhost()
    payload = request.get_json(silent=True)
    try:
        app_id = payload.get('app_id', None)
        set_active = payload.get('set_active', False)  # optional
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if set_discovery_app_active(app_id, set_active):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to activate discovery app')
Пример #14
0
def add_discovery_app_category_api():
    """ add a discovery app category to the db"""
    if not config.DEBUG:
        limit_to_localhost()

    payload = request.get_json(silent=True)
    try:
        discovery_app_category = payload.get('discovery_app_category', None)
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if add_discovery_app_category(discovery_app_category):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to add discovery app')
Пример #15
0
def post_task_results_endpoint():
    """an endpoint that can be used to return task results for bi"""
    limit_to_acl()
    limit_to_password()

    try:
        payload = request.get_json(silent=True)
        task_id = payload.get('task_id', None)
        if task_id is None:
            raise InvalidUsage('bad-request')
    except Exception as e:
        print(e)
        raise InvalidUsage('bad-request')

    return jsonify(status='ok', results=get_task_results(task_id))
Пример #16
0
def add_task_endpoint():
    """used to add tasks to the db"""
    if not config.DEBUG:
        limit_to_localhost()

    payload = request.get_json(silent=True)
    try:
        task = payload.get('task', None)
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if add_task(task):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to add task')
Пример #17
0
def set_active_api():
    '''enables/disables an offer'''
    if not config.DEBUG:
        limit_to_local_host()
    payload = request.get_json(silent=True)
    try:
        offer_id = payload.get('id', None)
        is_active = payload.get('is_active', None)
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if set_offer_active(offer_id, is_active):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to set offer status')
Пример #18
0
def store_task_results(user_id, task_id, results):
    '''store the results provided by the user'''

    # reject hackers trying to send task results too soon
    if reject_premature_results(get_next_task_results_ts(user_id)):
        print('rejecting premature results for user %s' % user_id)
        return False

    try:
        # store the results
        userTaskResults = UserTaskResults()
        userTaskResults.user_id = user_id
        userTaskResults.task_id = task_id
        userTaskResults.results = results
        db.session.add(userTaskResults)

        # write down the completed task-id
        from kinappserver.models import UserAppData
        user_app_data = UserAppData.query.filter_by(user_id=user_id).first()
        if user_app_data is None:
            raise('cant retrieve user app data for user:%s' % user_id)
        completed_tasks = json.loads(user_app_data.completed_tasks)
        completed_tasks.append(task_id)
        user_app_data.completed_tasks = json.dumps(completed_tasks)
        db.session.add(user_app_data)
        db.session.commit()
        return True
    except Exception as e:
        print(e)
        raise InvalidUsage('cant store_task_results')
Пример #19
0
def get_categories_for_user(user_id):
    """returns an array of categories tailored to this specific user"""
    import time
    from .user import user_exists, get_user_os_type
    if not user_exists(user_id):
        raise InvalidUsage('no such user_id %s' % user_id)

    os_type = get_user_os_type(user_id)

    s_time = int(round(time.time() * 1000))
    all_cats = list_categories(os_type)
    e_time = int(round(time.time() * 1000))
    log.info('all_cats for user %s with os_type %s: %s -- ptime: %s', user_id,
             os_type, all_cats, str(e_time - s_time))
    from .task2 import count_immediate_tasks

    s_time = int(round(time.time() * 1000))
    immediate_tasks = count_immediate_tasks(user_id)
    e_time = int(round(time.time() * 1000))
    log.info('count_immediate_tasks ptime for user_id %s is: %s', user_id,
             str(e_time - s_time))
    for cat_id in all_cats.keys():
        all_cats[cat_id]['available_tasks_count'] = immediate_tasks[cat_id]

    return [cat for cat in all_cats.values()]
Пример #20
0
def add_task(task_json):
    try:
        # sanity for task data
        for item in task_json['items']:
            if item['type'] not in ['textimage', 'text']:
                raise InvalidUsage('cant add task with invalid item-type')

        task = Task()
        task.task_id = task_json['id']
        task.task_type = task_json['type']
        task.title = task_json['title']
        task.desc = task_json['desc']
        task.price = int(task_json['price'])
        task.min_to_complete = int(task_json['min_to_complete'])
        task.provider_data = task_json['provider']
        task.tags = task_json['tags']
        task.items = task_json['items']
        print(task_json['start_date'])
        task.start_date = arrow.get(task_json['start_date'])
        print("the task: %s" % task.start_date)
        db.session.add(task)
        db.session.commit()
    except Exception as e:
        print(e)
        print('cant add task to db with id %s' % task_json['id'])
        return False
    else:
        return True
Пример #21
0
def get_user_backup_hints_by_enc_phone(enc_phone_number):
    """return the user backup hints object for the given enc_phone_number or throws exception"""
    ubh = PhoneBackupHints.query.filter_by(
        enc_phone_number=enc_phone_number).first()
    if not ubh:
        raise InvalidUsage('no such enc_phone_number')
    return ubh
Пример #22
0
def extract_header(request):
    '''extracts the user_id from the request header'''
    try:
        return request.headers.get('X-USERID')
    except Exception as e:
        print('cant extract user_id from header')
        raise InvalidUsage('bad header')
Пример #23
0
def create_user(user_id, os_type, device_model, push_token, time_zone,
                device_id, app_ver):
    '''create a new user and commit to the database. should only fail if the user_id is duplicate'''
    def parse_timezone(tz):
        '''convert -02:00 to -2 etc'''
        return int(tz[:(tz.find(':'))])

    if user_exists(user_id):
        raise InvalidUsage(
            'refusing to create user. user_id %s already exists' % user_id)
    user = User()
    user.user_id = user_id
    user.os_type = os_type
    user.device_model = device_model
    user.push_token = push_token
    user.time_zone = parse_timezone(time_zone)
    user.device_id = device_id
    db.session.add(user)
    db.session.commit()

    user_app_data = UserAppData()
    user_app_data.user_id = user_id
    user_app_data.completed_tasks = '[]'
    user_app_data.app_ver = app_ver
    user_app_data.next_task_ts = None
    db.session.add(user_app_data)
    db.session.commit()
Пример #24
0
def set_force_update_below(os_type, app_ver):
    """sets the given app_ver for the given os_type as into the db"""
    if os_type not in (OS_ANDROID, OS_IOS):
        raise InvalidUsage('invalid os type: %s' % os_type)
    if app_ver in (None, ''):
        raise InvalidUsage('invalid app_ver: %s' % app_ver)

    sysconfig = db.session.query(SystemConfig).one()
    if os_type == OS_ANDROID:
        sysconfig.block_clients_below_version_android = app_ver
    elif os_type == OS_IOS:
        sysconfig.block_clients_below_version_ios = app_ver
    db.session.add(sysconfig)
    db.session.commit()
    log.info('set force-update-below for os_type %s to %s' %
             (os_type, app_ver))
Пример #25
0
def add_discovery_app_api():
    """ internal endpoint used to populate the server with discovery apps"""
    if not config.DEBUG:
        limit_to_localhost()

    payload = request.get_json(silent=True)
    try:
        discovery_app = payload.get('discovery_app', None)
        set_active = payload.get('set_active', False)  # optional
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')
    if add_discovery_app(discovery_app, set_active):
        return jsonify(status='ok')
    else:
        raise InvalidUsage('failed to add discovery app')
def unblock_user_from_truex_tasks(user_id):
    """remove a user from the truex list"""
    tbuser = TruexBlacklistedUser.query.filter_by(user_id=user_id).first()
    if not tbuser:
        raise InvalidUsage('cant find blocked user with user_id %s' % user_id)
    db.session.delete(tbuser)
    db.session.commit()
Пример #27
0
def user_goods_report_endpoint():
    """returns a summary of the user's goods data"""
    limit_to_acl()
    limit_to_password()

    try:
        payload = request.get_json(silent=True)
        user_id = payload.get('user_id', None)
        user_phone = payload.get('phone', None)
        if (user_id is None
                and user_phone is None) or (user_id is not None
                                            and user_phone is not None):
            print('user_goods_report_endpoint: userid %s, user_phone %s' %
                  (user_id, user_phone))
            raise InvalidUsage('bad-request')
    except Exception as e:
        print(e)
        raise InvalidUsage('bad-request')

    try:  # sanitize user_id:
        if user_id:
            UUID(user_id)
    except Exception as e:
        log.error('cant generate tx report for user_id: %s ' % user_id)
        return jsonify(error='invalid_userid')

    if user_id:
        if not user_exists(user_id):
            print(
                'user_goods_report_endpoint: user_id %s does not exist. aborting'
                % user_id)
            return jsonify(erorr='no_such_user')
        else:
            return jsonify(report=[get_user_goods_report(user_id)])

    else:  # user_phone
        user_ids = get_all_user_id_by_phone(
            user_phone)  # there may be a few users with this phone
        if not user_ids:
            print(
                'user_goods_report_endpoint: user_phone %s does not exist. aborting'
                % user_phone)
            return jsonify(erorr='no_such_phone')
        else:
            return jsonify(report=[
                get_user_goods_report(user_id) for user_id in user_ids
            ])
Пример #28
0
def onboard_user():
    '''creates a wallet for the user and deposits some xlms there'''
    # input sanity
    try:
        user_id = extract_header(request)
        public_address = request.get_json(silent=True).get(
            'public_address', None)
        if None in (public_address, user_id):
            raise InvalidUsage('bad-request')
    except Exception as e:
        raise InvalidUsage('bad-request')

    # ensure the user exists but does not have an account:
    onboarded = is_onboarded(user_id)
    if onboarded is True:
        raise InvalidUsage('user already has an account')
    elif onboarded is None:
        raise InvalidUsage('no such user exists')
    else:
        # create an account, provided none is already being created
        lock = redis_lock.Lock(app.redis, 'address:%s' % public_address)
        if lock.acquire(blocking=False):
            try:
                print('creating account with address %s and amount %s' %
                      (public_address, config.STELLAR_INITIAL_ACCOUNT_BALANCE))
                tx_id = create_account(public_address,
                                       config.STELLAR_INITIAL_ACCOUNT_BALANCE)
                if (tx_id):
                    set_onboarded(user_id, True)
                else:
                    raise InternalError('failed to create account at %s' %
                                        public_address)
            except Exception as e:
                print('exception trying to create account:%s' % e)
                raise InternalError('unable to create account')
            else:
                print('created account %s with txid %s' %
                      (public_address, tx_id))
            finally:
                lock.release()
        else:
            raise InvalidUsage(
                'already creating account for user_id: %s and address: %s' %
                (user_id, public_address))

        increment_metric('user_onboarded')
        return jsonify(status='ok')
Пример #29
0
def delete_task(task_id):
    if not get_task_by_id(task_id):
        log.error('no task with id %s in the db' % task_id)
        raise InvalidUsage('task_id %s doesnt exist - cant delete' % task_id)

    task_to_delete = Task2.query.filter_by(task_id=task_id).first()
    db.session.delete(task_to_delete)
    db.session.commit()
Пример #30
0
def set_delay_days_api():
    """used to set the delay_days on all tasks - used in tests"""
    if not config.DEBUG:
        limit_to_localhost()

    payload = request.get_json(silent=True)
    try:
        delay_days = payload.get('days', None)
        if delay_days is None:
            raise InvalidUsage('missing days param')
    except Exception as e:
        print('exception: %s' % e)
        raise InvalidUsage('bad-request')

    set_delay_days(delay_days)
    print('set delay days to %s' % delay_days)
    return jsonify(status='ok')