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' }})
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)
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)
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']
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
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)
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}
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' }})
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)})