def modify_user(user_id, permissions, role):
    ApiAccess.get_skynet_db().users.update_one(
        {'_id': ObjectId(user_id)},
        {'$set': {
            'permissions': permissions,
            'role': role
        }})
def change_password(user_id, new_password):
    ApiAccess.get_skynet_db().users.update_one({'_id': ObjectId(user_id)}, {
        '$set': {
            'password':
            bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt())
        }
    })
def get_new_contact_list():
    maybe_id = get_last_id()
    #Last day or from last saved
    query = {'date_added': {'$gte': int((datetime.now() - timedelta(days=1)).timestamp())}} \
        if maybe_id is None else {'_id': {'$gt': maybe_id}}
    query.update({'email': {'$exists': True, '$ne': ''}})

    contacts = []
    skip_ = 0
    while True:
        partial = list(ApiAccess.get_revenyou_db().sign_up.\
            find(query, {'email': 1, 'first_name': 1, 'last_name': 1, 'nationality': 1}).\
            sort('_id', -1).\
            skip(skip_).\
            limit(_max_limit))
        skip_ += _max_limit
        if len(partial) == 0:
            break
        contacts.extend(partial)

    if len(contacts) == 0:
        return

    ApiAccess.get_skynet_db().cached_contacts.drop()
    ApiAccess.get_skynet_db().cached_contacts.insert_many(contacts)

    for contact in contacts:
        contact['country'] = contact.pop('nationality', '').upper()
        del contact['_id']
    send_contacts(contacts)
def update_2fa_activation(data):
    if not data['2fa_active']:
        ApiAccess.get_skynet_db().users.update_one(
            {'username': data['username'].upper()},
            {'$set': {
                '2fa_active': True
            }})
def successfull_login(data):
    del data['password']
    data['status'] = LoginStates.success.value
    ApiAccess.get_skynet_db().users.update(
        {'username': data['username'].upper()},
        {'$unset': {
            'fail_count': 1,
            'timeout_until': 1
        }})
    return data
def record_action(caller, username):
    if os.environ['APP_RUN_ENV'] == Mode.development.value:
        print('{} called {}'.format(username, caller))

    ApiAccess.get_skynet_db().audit.insert({
        'time':
        int(datetime.now().timestamp()),
        'username': (username or '-'),
        'caller': (caller or '-')
    })
def suspend_user(user_id):
    permissions = ApiAccess.get_skynet_db().users.find_one(
        {'_id': ObjectId(user_id)}, {
            '_id': 0,
            'permissions': 1
        })['permissions']
    if 'SUSPENDED' in permissions:
        return

    ApiAccess.get_skynet_db().users.update_one(
        {'_id': ObjectId(user_id)}, {'$push': {
            'permissions': 'SUSPENDED'
        }})
Beispiel #8
0
def unordered_bulk_write(data):
    updates = []
    for item in data:
        updates.append(
            UpdateOne({'_id': item['_id']}, {
                '$setOnInsert': {
                    '_id': item['_id'],
                    'quantity': item['quantity'],
                    'date_added': item['date_added']
                }
            },
                      upsert=True))

    ApiAccess.get_skynet_db().first_deposit.bulk_write(updates)
Beispiel #9
0
def get_deposit_withdrawal_lookup():
    while True:
        pipeline = [{
            '$match': {
                'order_status': OrderStatus.approved.value
            }
        }, {
            '$sort': {
                '_id': 1
            }
        }, {
            '$limit': _default_partition_size
        }, {
            '$lookup': {
                'from':
                'withdrawal',
                'let': {
                    'user_id': '$user_id',
                    'status': '$order_status'
                },
                'pipeline': [{
                    '$match': {
                        '$expr': {
                            '$and': [{
                                '$eq': ['$user_id', '$$user_id']
                            }, {
                                '$eq': ['$withdrawal_status', '$$status']
                            }]
                        }
                    }
                }],
                'as':
                'withdrawals'
            }
        }]
        maybe_id = get_last_id(ApiAccess.get_skynet_db().deposit_withdrawal)
        if maybe_id:
            match_index = next((index for (index, stage) in enumerate(pipeline)
                                if '$match' in stage), None)
            if match_index is None:
                raise KeyError('No $match provided')
            pipeline[match_index]['$match'].update({'_id': {'$gt': maybe_id}})

        data = list(ApiAccess.get_revenyou_db().deposit.aggregate(pipeline))
        if len(data) == 0:
            break
        ApiAccess.get_skynet_db().deposit_withdrawal.insert_many(data)
        time.sleep(_default_cool_off_timeout)
Beispiel #10
0
def get_last_saved_date():
    maybe_date = list(ApiAccess.get_skynet_db().first_deposit.\
        find({}, {'_id': 0, 'date_added': 1}).\
        sort('date_added', -1).\
        limit(1))
    if len(maybe_date) > 0:
        return maybe_date[0]['date_added']
Beispiel #11
0
def get_top_ids():
    ids = list(ApiAccess.get_skynet_db().gold_members.\
            find({}).\
            sort('asset', -1).\
            limit(_top_max))

    return {'content': ids}
def login(username, password, token):
    login_user = ApiAccess.get_skynet_db().users.find_one(
        {'username': username.upper()})

    if login_user is None:
        return None

    result_retry_fail = check_fail_retry(login_user)
    if result_retry_fail is not None:
        return result_retry_fail

    login_user['_id'] = str(login_user['_id'])
    if bcrypt.hashpw(password.encode('utf-8'),
                     login_user['password']) != login_user['password']:
        return update_fail_retry(login_user)

    if os.environ['APP_RUN_ENV'] == Mode.development.value:  #skip 2FA on dev
        return successfull_login(login_user)

    result_2fa = check_2fa(login_user, token)
    if result_2fa is not None:
        return result_2fa

    update_2fa_activation(login_user)

    return successfull_login(login_user)
def create_user(username, password, role, permissions):
    existing_user = ApiAccess.get_skynet_db().users.find_one(
        {'username': username.upper()})

    if existing_user is None:
        ApiAccess.get_skynet_db().users.insert_one({
            'username':
            username.upper(),
            'password':
            bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()),
            'role':
            role,
            'permissions':
            permissions
        })
        return username.upper()

    return None
def get_users():
    cursor = ApiAccess.get_skynet_db().users.find({}, {
        'username': 1,
        'role': 1,
        'permissions': 1
    })
    result = {'content': []}
    for document in cursor:
        document['_id'] = str(document['_id'])
        result['content'].append(document)

    return result
Beispiel #15
0
def upsert_collection(raw_data, collection):
    any_stored = ApiAccess.get_skynet_db()[collection].count() != 0
    paid_ids = []
    if any_stored:
        diffs = list(ApiAccess.get_skynet_db()[collection].aggregate([{
            '$group': {
                '_id': '',
                'ids': {
                    '$addToSet': '$_id'
                }
            }
        }, {
            '$project': {
                'paid_ids': {
                    '$setDifference':
                    ['$ids', [user['_id'] for user in raw_data]]
                },
                '_id': 0
            }
        }]))
        paid_ids = diffs[0].get('paid_ids', []) if len(diffs) > 0 else {}
        if len(paid_ids) > 0:
            ApiAccess.get_skynet_db()[collection].remove(
                {'_id': {
                    '$in': paid_ids
                }})

    updates = [
        UpdateOne({'_id': item['_id']}, {'$set': item}, upsert=True)
        for item in raw_data
    ]
    if (len(updates) > 0):
        ApiAccess.get_skynet_db()[collection].bulk_write(updates)
def update_fail_retry(data):
    fail_count = data.get('fail_count', 0) + 1
    ApiAccess.get_skynet_db().users.update_one(
        {'username': data['username'].upper()},
        {'$set': {
            'fail_count': fail_count
        }})
    if fail_count == _fail_retry_max:
        timeout_until = int(
            (datetime.now() +
             timedelta(minutes=_fail_retry_timeout)).timestamp())
        ApiAccess.get_skynet_db().users.update_one(
            {'username': data['username'].upper()},
            {'$set': {
                'fail_count': 0,
                'timeout_until': timeout_until
            }})
        return {
            'status': LoginStates.retry_fail.value,
            'timeout': utils.utc_ts_to_local_str(timeout_until)
        }
    elif fail_count > _fail_retry_max:
        ApiAccess.get_skynet_db().users.update_one(
            {'username': data['username'].upper()},
            {'$set': {
                'fail_count': 0
            }})
        return {
            'status': LoginStates.retry_fail.value,
            'timeout': utils.utc_ts_to_local_str(data.get('timeout_until', 0))
        }

    return {'status': LoginStates.fail.value}
def check_2fa(data, token):
    if 'secret' not in data:
        secret = base64.b32encode(os.urandom(10)).decode('utf-8')
        ApiAccess.get_skynet_db().users.update_one(
            {'username': data['username'].upper()},
            {'$set': {
                'secret': secret,
                '2fa_active': False
            }})
        return {
            'status': LoginStates.active_2fa.value,
            'qr_code': 'otpauth://totp/Skynet:{}?secret={}&issuer=Skynet' \
            .format(data['username'], secret)}

    is_token_valid = onetimepass.valid_totp(token, data['secret'])
    if not is_token_valid:
        return {
            'status': LoginStates.active_2fa.value,
            'qr_code': 'otpauth://totp/Skynet:{}?secret={}&issuer=Skynet' \
            .format(data['username'], data['secret'])} if not data['2fa_active'] \
            else {'status': LoginStates.fail.value}

    return None
def get_diagnostics(begin, end):
    query = {}
    if begin and end:
        query['time'] = {'$gte': begin, '$lte': end}
    elif begin:
        query['time'] = {'$gte': begin}
    elif end:
        query['time'] = {'$lte': end}

    result = list(ApiAccess.get_skynet_db().backend_errors.\
        find(query, {'_id': 0}).\
        sort('_id', -1).\
        limit(100))

    return json.dumps(result)
def get_audits(begin, end, user, max):
    query = {} if user is None or len(user) == 0 else {'username': user}
    if begin and end:
        query['time'] = {'$gte': begin, '$lte': end}
    elif begin:
        query['time'] = {'$gte': begin}
    elif end:
        query['time'] = {'$lte': end}

    result = list(ApiAccess.get_skynet_db().audit.\
        find(query, {'_id': 0}).\
        sort('_id', -1).\
        limit(int(max)))

    return json.dumps(result)
Beispiel #20
0
def get_gold_ids(begin, end, order='desc'):
    date_filter = {}
    if begin and end: 
        date_filter = {'last_deposit': {'$gte': begin, '$lte': end}}
    elif begin:
        date_filter = {'last_deposit': {'$gte': begin}}
    elif end:
        date_filter = {'last_deposit': {'$lte': end}}

    gold_members = []
    skip_ = 0
    while True:
        partial = list(ApiAccess.get_skynet_db().gold_members.\
            find(date_filter).\
            sort('observation_date', (-1 if order == 'desc' else 1)).\
            skip(skip_).\
            limit(_max_limit))
        skip_ += _max_limit
        if len(partial) == 0:
            break
        gold_members.extend(partial)

    return {'content': gold_members}
Beispiel #21
0
def get_new_gold_accounts():
    delta = timedelta(hours=24)

    pipeline = [
        {'$sort': {'_id': 1}},
        {'$match': {'bank': TransactionType.external.value}},
        {'$group': {'_id': '$user_id',
                    'deposit_sum': {'$sum': {'$toDouble': '$quantity'}},
                    'withdrawals': {'$last': '$withdrawals'},
                    'last_deposit': {'$last': '$date_added'},
                    'traverse_id': {'$last': '$_id'}
        }},
        {'$unwind': {
            'path': '$withdrawals', 
            'preserveNullAndEmptyArrays': True
        }},
        {'$group': {'_id': '$_id',
            'deposit_sum': {'$last': '$deposit_sum'},
            'withdrawal_sum': {'$sum': {'$toDouble': '$withdrawals.withdrawal_quantity'}},
            'last_deposit': {'$last': '$last_deposit'},
            'last_withdrawal': {'$last': '$withdrawals.date_added'},
            'traverse_id': {'$last': '$traverse_id'}
        }},
        {'$addFields': {
            'asset': {'$subtract': ['$deposit_sum', '$withdrawal_sum']}
        }},
        {'$sort': {'traverse_id': 1}}
    ]

    match_index = next((index for (index, stage) in enumerate(pipeline) if '$match' in stage), None)
    if match_index is None:
        raise KeyError('No $match provided')

    docs = []
    while True:
        partial_result = list(ApiAccess.get_skynet_db().deposit_withdrawal.aggregate(pipeline))
        if len(partial_result) == 0:
            break
        pipeline[match_index]['$match'].update({'_id': {'$gt': partial_result[-1].get('traverse_id', '')}})
        docs.extend(partial_result)

    prev_gold_members = []
    skip_ = 0
    while True:
        partial = list(ApiAccess.get_skynet_db().gold_members.\
            find({}, {'_id': 1}).\
            skip(skip_).\
            limit(_max_limit))
        skip_ += _max_limit
        if len(partial) == 0:
            break
        prev_gold_members.extend(partial)


    df = pd.DataFrame(docs).\
        groupby('_id', as_index=False).\
        agg({
            'asset': 'sum',
            'last_deposit': lambda x: x.tail(1),
            'last_withdrawal': lambda x: x.tail(1)})

    df = df[(df.asset >= _gold_threshold)]
    df_records = df[['_id', 'last_deposit', 'last_withdrawal', 'asset']]
    record_data = df_records.set_index('_id').to_dict()
    df_ids = df[['_id']]
    curr_gold_members = df_ids.to_dict('records')

    new_gold_members = utils.subtract_datasets(curr_gold_members, prev_gold_members)
    lost_gold_members = utils.subtract_datasets(prev_gold_members, curr_gold_members)

    observation_date = datetime.now().strftime('%Y-%m-%d')
    if len(new_gold_members) > 0:
        ApiAccess.get_skynet_db().gold_members.insert_many([
            {'_id': _id['_id'], 
            'last_deposit': record_data['last_deposit'][_id['_id']],
            'last_withdrawal': record_data['last_withdrawal'][_id['_id']],
            'asset': record_data['asset'][_id['_id']],
            'observation_date': observation_date} for _id in new_gold_members])
        _internal_cache.set_new_gold_members(json.dumps({'content': new_gold_members}), int(delta.total_seconds()))

    if len(lost_gold_members) > 0:
        ApiAccess.get_skynet_db().gold_members.remove(
            {'_id': {'$in': [member['_id'] for member in lost_gold_members]}})
        _internal_cache.set_lost_gold_members(json.dumps({'content': lost_gold_members}), int(delta.total_seconds()))
def unsuspend_user(user_id):
    ApiAccess.get_skynet_db().users.update_one(
        {'_id': ObjectId(user_id)}, {'$pull': {
            'permissions': 'SUSPENDED'
        }})
Beispiel #23
0
def get_last_id():
    maybe_id = list(ApiAccess.get_skynet_db().cached_contacts.find({}, {'_id': 1}).\
                        sort([('_id', -1)]).\
                        limit(1))
    if len(maybe_id) > 0:
        return maybe_id[0]['_id']
def reset_2fa_secret(user_id):
    ApiAccess.get_skynet_db().users.update(
        {'_id': ObjectId(user_id)}, {'$unset': {
            'secret': 1,
            '2fa_active': 1
        }})
def find_user(username):
    user = ApiAccess.get_skynet_db().users.find_one({'username': username})
    return user
def delete_user(user_id):
    ApiAccess.get_skynet_db().users.delete_one({'_id': ObjectId(user_id)})