async def get_by_login(login): """ Показать пользователей """ from helpers import db from helpers.models.users import User click.echo(click.style(str(User.get_by_login(login)), fg='green')) click.echo(await db.many(await db.autoconfig(), User.get_by_login(login)))
async def get_client_users(client_id): from helpers import db from helpers.models.users import User click.echo( click.style(str(User.get_count(where_=[User.client_id == client_id])), fg='green')) click.echo(await db.scalar(await db.autoconfig(), User.get_count(where_=[User.client_id == client_id])))
async def check_user(user_login): """ Показать пользователя с настройками """ from helpers import db from helpers.models.users import User click.echo(click.style(str(User.check_identity(user_login)), fg='green')) click.echo(await db.many(await db.autoconfig(), User.check_identity(user_login)))
async def change_user_param(user_id, param, to_value): """ Поменять настройки у юзера """ from helpers import db from helpers.models.users import User from helpers.models.params import Param click.echo( click.style(str( User.update({str(param): str(to_value)}, [User.id == user_id])), fg='green')) click.echo(await db.update( await db.autoconfig(), User.update({str(param): str(to_value)}, [User.id == user_id])))
async def list_users(): """ Показать пользователей """ from helpers import db from helpers.config import Config from helpers.models.users import User c = Config.get_config() click.echo(click.style(str(User.get(100, 0, 'id', 'DESC')), fg='green')) if 'postgres' not in c: click.echo(click.style('Config error. Cant load DB postgres', fg='red')) # получаем драйвер БД по конфигу pg = await db.get_pg_engine(c.get('postgres')) click.echo(await db.many(pg, User.get(100, 0, 'id', 'DESC')))
async def delete(self, request): """ Удаление пользователя :param request: :return: """ db = request.app['db'] auth = request.auth if request.auth.get('group') != 1: return web.HTTPUnauthorized() if not auth.get('client'): return web.HTTPUnauthorized() id = request.match_info.get('id', 0) user = await one( db, User.get_by([User.id == id, User.client_id == auth.get('client')])) del_user_result = bool(await delete( db, User.remove([User.id == id, User.client_id == auth.get('client')]))) del_params_result = bool(await delete( db, Param.remove([Param.user_id == user.get('id')]))) if not del_user_result: raise web.HTTPNotAcceptable( reason='Can`t delete user. Try again later ', body='Can`t delete user. Try again later') # статистика stat = { 'user_id': auth.get('id'), 'code': '17', 'msg': 'User deleted [' + str(id) + ']' } await insert(db, Statistic.add(stat)) # разлогиневаем удаленного cache = request.app.get('cache') await cache.kill_cache('uid_token_' + str(id)) return web.json_response(user, dumps=self.__encode_helper, headers={'X-Total-Count': '1'})
async def get_one(self, request): """ Получить один конкретный пользователь :param request: :return: """ if request.auth.get('group') != 1: return web.HTTPUnauthorized( ) # только админ может видеть пользователей своих db = request.app['db'] # обновить список тегов клиента администратора client = await one(db, Client.get_by_id(request.auth.get('client'))) client_token = client.get('token') dp = DataProvider(client_token) all_ava_tags = await dp.get_tags() # список тегов клиента import json as _json for uid, _ws_list in request.app['websockets'].items(): if int(request.auth.get('id')) == int(uid): # просим всех клиентов пользователя обновить у себя настройки профиля # если у них там что-то не обновится, потребуется перезайти for _ws in _ws_list: try: if all_ava_tags: await _ws.send_str( _json.dumps( { 'type': 'update_client_tags', 'payload': all_ava_tags }, cls=DateTimeAwareEncoder)) except Exception as e: request.app['_log'].error(str(e)) user_id = request.match_info.get('id') or request.get('id') or 0 if int(user_id) > 0: await self._fix_deleted_tags(user_id, request.app) user = await one( db, User.get_full_by_id(user_id, request.auth.get('client'))) user = group_from_labels(user) # статистика stat = { 'user_id': str(request.auth.get('id')), 'code': '15', 'msg': 'Users fetched [' + str(user_id) + ']' } await insert(db, Statistic.add(stat)) return web.json_response( user, dumps=self.__encode_helper, headers={'X-Total-Count': str(0) if len(user) == 0 else str(1)})
async def check_user_login(user_login, user_password): from helpers import db from helpers.models.users import User from helpers.models.groups import Group click.echo( click.style(str( User.get(1, 0, where_=[ User.login == user_login, User.password == user_password ])), fg='green')) click.echo(await db.many( await db.autoconfig(), User.get( 1, 0, where_=[User.login == user_login, User.password == user_password])))
async def show_user_full(user_id): """ Показать пользователя с настройками """ from helpers import db from helpers.models.users import User from helpers.models.params import Param click.echo( click.style(str( User.join(Param, 1, 0, where_=[User.id == user_id], on=User.id == Param.user_id)), fg='green')) click.echo(await db.many( await db.autoconfig(), User.join(Param, 1, 0, where_=[User.id == user_id], on=User.id == Param.user_id)))
async def get_profile(self, id, app): """ Выгрузить профиль пользователя :param id: :param app: :return: """ db = app.get('db') user = (await one( db, User.join(Param, 1, 0, on=User.id == Param.user_id, where_=[User.id == id]))) user['group'] = await one(db, Group.get_by_id(user.get('users_group_id'))) user = users_join_cleaner(user) user['client'] = await one(db, Client.get_by_id(user.get('client_id'))) client_token = user['client'].pop('token') dp = DataProvider(client_token) all_ava_tags = await dp.get_tags() # фикс удаленных тегов у клиента _tg_ids = [int(x.get('id')) for x in all_ava_tags.copy()] _rem_tags = [] for u_tag in user.get('params').get('tags'): if int(u_tag) not in _tg_ids: _rem_tags.append(int(u_tag)) # удаляем тег if len(_rem_tags) > 0: user['params']['tags'] = [ x for x in user.get('params').get('tags') if x not in _rem_tags ] await update( db, Param.update(what_={'tags': user['params']['tags']}, where_=[Param.id == user['params']['id']])) user['client']['tags_available'] = all_ava_tags user['client']['fields_available'] = fields_preparator( config.get('app').get('fields_avaliable')) del user['password'] return user
async def show_user(id): """ Показать пользователя """ from helpers import db from helpers.config import Config from sqlalchemy.sql import text, select, func, and_ from helpers.models.users import User from helpers.models.params import Param c = Config.get_config() if 'postgres' not in c: click.echo(click.style('Config error. Cant load DB postgres', fg='red')) # получаем драйвер БД по конфигу db_pg = await db.get_pg_engine(c.get('postgres')) async with db_pg.acquire() as conn: result = await conn.execute(User.get_by_id(id)) rowcount = result.rowcount users = await result.fetchone() click.echo(dict(users))
async def __check_credentials(db_engine, username, password): if username == SUPERADMIN_LOGIN and password == SUPERADMIN_PASS: return True # суперадмин ОКай! try: # у нас пока не будет хешей, ибо народ забывает пароли user = (await one( db_engine, User.get( 1, 0, where_=[User.login == username, User.password == password]))) print(user) except Exception as e: print(e) return False if user: return True return False
async def xls(self, request): """ Подгружаем XLS и отдаем клиету :param request: :return: """ from helpers.xls_maker import make_report auth = request.auth if request.auth.get('group') not in [1, 2]: return web.HTTPUnauthorized() date_from = str( request.query.get('_date_from', (datetime.now() - relativedelta(days=7)).replace( hour=0, minute=0, second=0, tzinfo=None))) date_till = str( request.query.get( '_date_till', datetime.now().replace(hour=23, minute=59, second=59, tzinfo=None))) filters = None if 'filter' in request.query: import json try: filters = json.loads(request.query.get('filter')) except Exception as e: pass if filters: if '_date_from' in filters: date_from = str( filters.get('_date_from', (datetime.now() - relativedelta(days=7)).replace(hour=0, minute=0, second=0, tzinfo=None))) if '_date_till' in filters: date_till = str( filters.get( '_date_till', datetime.now().replace(hour=23, minute=59, second=59, tzinfo=None))) sort = request.query.get('_sort', 'start_time') order = request.query.get('_order', 'DESC') db = request.app['db'] user = await one( db, User.get_full_by_id(auth.get('id'), auth.get('client'))) token = user['clients_token'] # TODO: добавить фильтры из настроек юзера # у нас нельзя сортировать по id результат отчета, говорит prohibited dt = DataProvider(token) if sort == 'id': sort = 'start_time' dt.set_period(date_from, date_till) # различная мета инфа для отчета в XLS _meta = { 'from': date_from, 'till': date_till, 'client': user['clients_name'], 'user': user['users_name'], } dt.set_fields(user['params_fields']) if user['params_filters'] is not None and user[ 'params_filters'] != 'null' and len( user['params_filters']) > 0: _flt = user['params_filters'][0].get('filters') for f in _flt: if str(f.get('value')).isdigit(): f['value'] = int(f['value']) print(user['params_filters'][0]) dt.filters = user['params_filters'][0] dt.set_sort([{'field': sort, 'order': str(order).lower()}]) report = await dt.get() # статистика прослушанности static = await many( db, """ SELECT msg FROM statistics WHERE code=30 and statistics.user_id = %s order by id ASC """ % auth.get('id')) static = [int(x.get('msg')) for x in static.get('data')] for call in report.get('result').get('data'): if int(call.get('id')) in static: call['listened'] = 'Да' else: call['listened'] = 'Нет' if call.get('tags'): for x in call['tags']: x['comm_id'] = call.get('id') if request.auth.get('group') == 2: # если пользователь, то он может видеть только теги из своего списка user_tags = user['params_tags'] for call in report.get('result').get('data'): if call.get('tags'): call['tags'][:] = [ x for x in call['tags'] if x.get('tag_id') in user_tags ] xls_filec = make_report( report, fields_preparator(config.get('app').get('fields_avaliable')), user['params_fields'], _meta, { 'hide_sys_id': user['params_hide_sys_id'], 'hide_sys_aon': user['params_hide_sys_aon'], 'hide_sys_player': user['params_hide_sys_player'], 'hide_sys_static': user['params_hide_sys_static'], }) return web.Response( body=xls_filec, headers={ "Сontent-disposition": "attachment; filename=report.xls", "Content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; base64", # "Content-Length" : str(len(xls_filec)), "Content-Transfer-Encoding": "binary", "Cache-Control": "must-revalidate", "Pragma": "public" })
async def _fix_deleted_tags(self, user_id, app): """ Если в КМ удалили теги, то у нас они обновятся не сразу Этот метод чистит удаленные теги из настроек юзера :param user_id: :param app: :return: """ try: db = app.get('db') user = (await one( db, User.join(Param, 1, 0, on=User.id == Param.user_id, where_=[User.id == user_id]))) user['group'] = await one( db, Group.get_by_id(user.get('users_group_id'))) user = users_join_cleaner(user) user['client'] = await one(db, Client.get_by_id(user.get('client_id'))) client_token = user['client'].pop('token') dp = DataProvider(client_token) all_ava_tags = await dp.get_tags() # список тегов клиента # фикс удаленных тегов у клиента _tg_ids = [int(x.get('id')) for x in all_ava_tags.copy()] _rem_tags = [] for u_tag in user.get('params').get('tags'): if int(u_tag) not in _tg_ids: _rem_tags.append(int(u_tag)) # удаляем тег if len(_rem_tags) > 0: user['params']['tags'] = [ x for x in user.get('params').get('tags') if x not in _rem_tags ] await update( db, Param.update(what_={'tags': user['params']['tags']}, where_=[Param.id == user['params']['id']])) # просим клиента обновить профиль # обновляем профиль пользователя в браузере прям через сокет import json as _json for uid, _ws_list in app['websockets'].items(): if int(user_id) == int(uid): # просим всех клиентов пользователя обновить у себя теги for _ws in _ws_list: try: await _ws.send_str( _json.dumps({ 'type': 'update_user_tag', 'payload': { 'user_tags': user['params']['tags'], 'client_tags': all_ava_tags } })) except Exception as e: app['_log'].error(str(e)) except Exception as ee: app['_log'].error('Tags sync error: ' + str(ee)) return False return True
async def update(self, request): """ Обновить данные по пользователю :param requset: :return: """ if request.auth.get('group') != 1: return web.HTTPUnauthorized( ) # только админ может добавлять и менять try: id = int(request.match_info.get('id', 0)) except Exception as e: return web.HTTPNotAcceptable( reason='Can`t update user. Data error: ' + str(e), body='Can`t update user. Data error: ' + str(e)) print('Update request started for user: '******'Can`t update user. Data error: ' + str(e), body='Can`t update user. Data error: ' + str(e)) # if int(id) != int(data.get('id')): # return web.HTTPNotAcceptable(reason='Can`t update user. Data error: id in request not match id in body', # body='Can`t update user. Data error: id in request not match id in body ') db = request.app['db'] not_n_fields = ['client_id', 'id', 'group', 'client'] for el in not_n_fields: if el in data: data.pop(el) if 'params' in data: params = data.pop('params') if params.get('filters') is None or params.get( 'filters') == 'null' or params.get('filters') == '': params['filters'] = [] else: for num, filter in enumerate(params.get('filters')): if 'filters' not in filter: del params['filters'][num] if len(filter.get('filters')) <= 0: del params['filters'][num] if params.get('fields') is None or params.get( 'fields') == 'null' or params.get('fields') == '': params['fields'] = [] if params.get('tags') is None or params.get( 'tags') == 'null' or params.get('tags') == '': params['tags'] = [] if 'user_id' in params: params.pop('user_id') if 'id' in params: params.pop('id') params_id = await scalar( db, """ -- получить ID настроек для пользователя SELECT id FROM params WHERE user_id = %d """ % id) res_params = await update( db, Param.update(what_=params, where_=[Param.id == params_id])) stat = { 'user_id': request.auth.get('id'), 'code': '94', 'msg': 'Params for user [' + str(id) + '] updated ' + str(res_params) } await insert(db, Statistic.add(stat)) try: res_user = await update( db, User.update(what_=data, where_=[User.id == id])) except Exception as ee: request.app['_log'].error('Error while user update: ' + str(ee)) raise web.HTTPNotAcceptable( reason='Can`t update. User already exists with login', body='Can`t update. User already exists with login') if int(res_user) > 0: request['id'] = id # статистика stat = { 'user_id': request.auth.get('id'), 'code': '4', 'msg': 'User updated ' + str(id) } await insert(db, Statistic.add(stat)) ## DEPRECATED! Больше не выходим юзера. Просто обновляем ему профиль через сокет ## надо заставить юзера перевойти, ибо мы поменяли ему профиль. ## разлогиневаем юзера, пусть перезайдет. #cache = request.app.get('cache') #await cache.kill_cache('uid_token_' + str(id)) import json as _json m = Main() profile = await m.get_profile(id, app=request.app) for uid, _ws_list in request.app['websockets'].items(): if int(id) == int(uid): # просим всех клиентов пользователя обновить у себя настройки профиля # если у них там что-то не обновится, потребуется перезайти for _ws in _ws_list: try: if profile: await _ws.send_str( _json.dumps( { 'type': 'update_profile', 'payload': profile }, cls=DateTimeAwareEncoder)) except Exception as e: request.app['_log'].error(str(e)) return await self.get_one(request) else: return web.json_response( { 'success': False, 'error': 'Обновление не удалось!' }, status=500)
async def get_list(self, request): """ Получить список пользователй :param request: :return: - всегда список """ db = request.app['db'] auth = request.auth if auth.get('group') != 1: return web.HTTPUnauthorized( ) # только админ может видеть пользователей своих # замечено, что иногда при некоторых связях реактадмину надо еще один роут parameters = request.rel_url.query search = request.query.get('q', None) group_id = request.query.get('group_id', None) if 'id' in parameters: ids = parameters.getall('id') users = await many( db, User.get_full_in_ids(ids, auth.get('client'), where_=[User.id != auth.get('id')])) resp = group_from_labels_many(users) return web.json_response( resp.get('data'), dumps=self.__encode_helper, headers={'X-Total-Count': resp.get('total')}) # собираем все штуки для сортировки и пагинации limit = request.query.get('_end', LIMIT) offset = request.query.get('_start', '0') if int(limit) - int(offset) > 0: limit = int(limit) - int(offset) limit = str(limit) sort = request.query.get('_sort', 'id') order = request.query.get('_order', 'DESC') if search: query = User.get_full(request.auth.get('client'), limit, offset, sort, order, where_=[ User.id != auth.get('id'), User.name.like("%" + search + "%") ]) users_total = await scalar( db, User.get_count(where_=[ User.id != auth.get('id'), User.name.like("%" + search + "%"), User.client_id == request.auth.get('client') ])) elif group_id: query = User.get_full(request.auth.get('client'), limit, offset, sort, order, where_=[ User.id != auth.get('id'), User.group_id == group_id, ]) users_total = await scalar( db, User.get_count(where_=[ User.id != auth.get('id'), User.group_id == group_id, User.client_id == request.auth.get('client') ])) else: users_total = await scalar( db, User.get_count(where_=[ User.id != auth.get('id'), User.client_id == request.auth.get('client') ])) query = User.get_full(request.auth.get('client'), limit, offset, sort, order, where_=[User.id != auth.get('id')]) users = await many(db, query) resp = group_from_labels_many(users) # статистика stat = { 'user_id': str(auth.get('id')), 'code': '14', 'msg': 'Users list fetched [' + str(users_total) + ']' } await insert(db, Statistic.add(stat)) return web.json_response(resp.get('data'), dumps=self.__encode_helper, headers={'X-Total-Count': str(users_total)})
async def get_list(self, request): """ Получить список звонков :param request: :return: """ auth = request.auth if request.auth.get('group') not in [1, 2]: return web.HTTPUnauthorized() # собираем все штуки для сортировки и пагинации limit = request.query.get('_end', '15') offset = request.query.get('_start', '0') sort = request.query.get('_sort', 'start_time') order = request.query.get('_order', 'DESC') date_from = str( request.query.get('_date_from', (datetime.now() - relativedelta(days=7)).replace( hour=0, minute=0, second=0, microsecond=0, tzinfo=None))) date_till = str( request.query.get( '_date_till', datetime.now().replace(hour=23, minute=59, second=59, microsecond=0, tzinfo=None))) db = request.app['db'] user = await one( db, User.get_full_by_id(auth.get('id'), auth.get('client'))) # обновляем список тегов if int(auth.get('id')) > 0 and user.get( 'params_enable_deleted_tags_check') is True: u = Users() await u._fix_deleted_tags(auth.get('id'), request.app) # получаем данные текущего пользователя token = user['clients_token'] # TODO: добавить фильтры из настроек юзера # у нас нельзя сортировать по id результат отчета, говорит prohibited dt = DataProvider(token) if sort == 'id': sort = 'start_time' try: dt.set_period(date_from, date_till) except Exception as e: raise web.HTTPNotAcceptable( reason='Period error. Please try again', body=str(e)) dt.set_fields(user['params_fields']) if user['params_filters'] is not None and user[ 'params_filters'] != 'null' and len( user['params_filters']) > 0: _flt = user['params_filters'][0].get('filters') for f in _flt: if str(f.get('value')).isdigit(): f['value'] = int(f['value']) dt.filters = user['params_filters'][0] dt.set_sort([{'field': sort, 'order': str(order).lower()}]) if int(limit) - int(offset) > 0: limit = int(limit) - int(offset) limit = str(limit) try: calls = Report.__extract_data(await dt.get_part(limit, offset)) except TypeError as e: return web.json_response([], headers={ 'X-Total-Count': '0', 'X-Problem': str(e) }) except Exception as ee: raise web.HTTPNotAcceptable(reason=str(ee), body=str(ee)) # calls uniq # calls = list({v['id']:v for v in calls}.values()) # для снимания тега с обращения допишем в теги обращения, ибо в реакте не понятно как это сделать # статистика прослушанности static = await many( db, """ SELECT msg FROM statistics WHERE code=30 and statistics.user_id = %s order by id ASC """ % auth.get('id')) static = [int(x.get('msg')) for x in static.get('data')] for call in calls: if int(call.get('id')) in static: call['listened'] = True else: call['listened'] = False if call.get('tags'): for x in call['tags']: x['comm_id'] = call.get('id') if request.auth.get('group') == 2: # если пользователь, то он может видеть только теги из своего списка user_tags = user['params_tags'] for call in calls: if call.get('tags'): call['tags'][:] = [ x for x in call['tags'] if x.get('tag_id') in user_tags ] rowcount = dt.get_total() # статистика stat = { 'user_id': request.auth.get('id'), 'code': '20', 'msg': 'Report fetched from:[' + str(date_from) + '] to:[' + str(date_till) + '] total:[' + str(rowcount) + ']' } await insert(db, Statistic.add(stat)) return web.json_response(calls, dumps=Report.__encode_helper, headers={'X-Total-Count': str(rowcount)})
async def create(self, request): """ Создание пользователя :param request: :return: """ db = request.app['db'] auth = request.auth # пользаков можт добавлять только админ if request.auth.get('group') != 1: return web.HTTPUnauthorized() try: data = await request.json() except Exception as e: return web.json_response({ 'success': False, 'error': str(e) }, status=500) user_neo = { 'name': data.get('name'), 'login': data.get('login'), 'email_address': data.get('email_address'), 'password': data.get('password'), 'comment': data.get('comment'), 'client_id': auth.get('client'), 'group_id': data.get('group_id') } try: new_user = await insert(db, User.add(user_neo)) except Exception as e: raise web.HTTPNotAcceptable( reason='Can`t create. User already exists with login: '******'login'), body='Can`t create. User already exists with login: '******'login')) new_user = new_user[0].get('id') if not new_user: raise web.HTTPNotAcceptable( reason='Can`t create user. Data error. ', body='Can`t create user. Data error. ') usr_params = { 'fields': data.get('params').get('fields') if data.get('params') else [], 'filters': data.get('params').get('filters') if data.get('params') else [], 'tags': data.get('params').get('tags') if data.get('params') else [], 'allow_tags_add': bool(data.get('params').get('allow_tags_add')) if data.get('params') else False, 'allow_tags_delete': bool(data.get('params').get('allow_tags_delete')) if data.get('params') else False, 'hide_sys_id': bool(data.get('params').get('hide_sys_id')) if data.get('params') else False, 'hide_sys_aon': bool(data.get('params').get('hide_sys_aon')) if data.get('params') else False, 'hide_sys_player': bool(data.get('params').get('hide_sys_player')) if data.get('params') else False, 'hide_sys_static': bool(data.get('params').get('hide_sys_static')) if data.get('params') else False, 'enable_deleted_tags_check': bool(data.get('params').get('enable_deleted_tags_check')) if data.get('params') else False, 'user_id': new_user } if usr_params.get('filters') is None or usr_params.get( 'filters') == 'null' or usr_params.get('filters') == '': usr_params['filters'] = [] if usr_params.get('fields') is None or usr_params.get( 'fields') == 'null' or usr_params.get('fields') == '': usr_params['fields'] = [] if usr_params.get('tags') is None or usr_params.get( 'tags') == 'null' or usr_params.get('tags') == '': usr_params['tags'] = [] new_params = await insert(db, Param.add(usr_params)) if not new_params: raise web.HTTPNotAcceptable( reason='Can`t create user. Default params creation failed!', body='Can`t create user. Default params creation failed!') # статистика stat = { 'user_id': request.auth.get('id'), 'code': '3', 'msg': 'User created [' + str(new_user) + '] params [' + str(new_params) + ']' } await insert(db, Statistic.add(stat)) request['id'] = new_user return await self.get_one(request)
async def refresh(self, request): """ Для обновления профиля пользователя Достается исключительно из мидлвари, в роуты добавлять не надо его :param request: :return: """ app = request.app auth = request.auth user_id = auth.get('id') db = app.get('db') user = (await one( db, User.join(Param, 1, 0, on=User.id == Param.user_id, where_=[User.id == user_id]))) # подтянем группы, потом сделаю одним запросом user['group'] = await one(db, Group.get_by_id(user.get('users_group_id'))) user = users_join_cleaner(user) user['client'] = await one(db, Client.get_by_id(user.get('client_id'))) client_token = user['client'].pop('token') dp = DataProvider(client_token) all_ava_tags = await dp.get_tags() # фикс удаленных тегов у клиента _tg_ids = [int(x.get('id')) for x in all_ava_tags.copy()] _rem_tags = [] for u_tag in user.get('params').get('tags'): if int(u_tag) not in _tg_ids: _rem_tags.append(int(u_tag)) # удаляем тег if len(_rem_tags) > 0: user['params']['tags'] = [ x for x in user.get('params').get('tags') if x not in _rem_tags ] await update( db, Param.update(what_={'tags': user['params']['tags']}, where_=[Param.id == user['params']['id']])) user['client']['tags_available'] = all_ava_tags user['client']['fields_available'] = fields_preparator( config.get('app').get('fields_avaliable')) del user['password'] payload = { 'name': user['name'], 'id': user['id'], 'client': user['client_id'], 'group': user['group_id'], 'allow_tags_add': int(user['params']['allow_tags_add']), 'allow_tags_delete': int(user['params']['allow_tags_delete']), } payload['exp'] = datetime.utcnow() + timedelta( seconds=JWT_EXP_DELTA_SECONDS) payload['iat'] = datetime.utcnow() - timedelta(seconds=1) payload['nbf'] = datetime.utcnow() - timedelta(seconds=1) jwt_token = jwt.encode(payload, JWT_SECRET, JWT_ALGORITHM, json_encoder=DateTimeAwareEncoder) token = jwt_token.decode('utf-8') # регистрируем токен юзера и вход await scalar( db, Statistic.add({ 'user_id': user.get('id'), 'code': '100', 'msg': token })) cache = app.get('cache') metrics = app.get('metrics') await metrics.inc('jwt_issued_count') _already_in_redis_tokens = await cache.get_cache('uid_token_' + str(user['id'])) if not _already_in_redis_tokens: _already_in_redis_tokens = [] _already_in_redis_tokens.append(token) await cache.set_cache('uid_token_' + str(user['id']), _already_in_redis_tokens) await cache.expire_cache('uid_token_' + str(user['id']), (JWT_EXP_DELTA_SECONDS - 2)) return web.json_response({ 'token': token, 'user': user }, dumps=self.__encode_helper, status=426) # 426 - Upgrade Required
async def login(self, request): """ Основной роут авторизации """ app = request.app try: #form = await request.json() form = str(await request.read(), encoding='utf-8') logger.debug("Login base64encoded: " + str(form)) form = json.loads(str(base64.b64decode(form), encoding='utf-8')) logger.debug("Login decoded json: " + str(json.dumps(form))) login = form.get('username') password = form.get('password') except Exception as e: # если не распарсится джсон - все ок login = '' password = '' db = app.get('db') if await self.__check_credentials(db, login, password): # доработаем суперадмина if login == SUPERADMIN_LOGIN and password == SUPERADMIN_PASS: user = User.get_superadmin() else: # ВАЖНО! Логин уникальное поле! Это надо учесть при добавлении роли user = (await one( db, User.join(Param, 1, 0, on=User.id == Param.user_id, where_=[User.login == login]))) # подтянем группы, потом сделаю одним запросом user['group'] = await one( db, Group.get_by_id(user.get('users_group_id'))) user = users_join_cleaner(user) user['client'] = await one( db, Client.get_by_id(user.get('client_id'))) client_token = user['client'].pop('token') dp = DataProvider(client_token) all_ava_tags = await dp.get_tags() # фикс удаленных тегов у клиента _tg_ids = [int(x.get('id')) for x in all_ava_tags.copy()] _rem_tags = [] for u_tag in user.get('params').get('tags'): if int(u_tag) not in _tg_ids: _rem_tags.append(int(u_tag)) # удаляем тег if len(_rem_tags) > 0: user['params']['tags'] = [ x for x in user.get('params').get('tags') if x not in _rem_tags ] await update( db, Param.update(what_={'tags': user['params']['tags']}, where_=[Param.id == user['params']['id'] ])) user['client']['tags_available'] = all_ava_tags user['client']['fields_available'] = fields_preparator( config.get('app').get('fields_avaliable')) del user['password'] # генерим юзеру токен payload = { 'name': user['name'], 'id': user['id'], 'client': user['client_id'], 'group': user['group_id'], 'allow_tags_add': int(user['params']['allow_tags_add']), 'allow_tags_delete': int(user['params']['allow_tags_delete']), } payload['exp'] = datetime.utcnow() + timedelta( seconds=JWT_EXP_DELTA_SECONDS) payload['iat'] = datetime.utcnow() - timedelta(seconds=1) payload['nbf'] = datetime.utcnow() - timedelta(seconds=1) jwt_token = jwt.encode(payload, JWT_SECRET, JWT_ALGORITHM, json_encoder=DateTimeAwareEncoder) token = jwt_token.decode('utf-8') # регистрируем токен юзера и вход await scalar( db, Statistic.add({ 'user_id': user.get('id'), 'code': '1', 'msg': token })) logger.debug("User [" + str(user.get('id')) + "] has now token: [" + str(token) + "]") metrics = app.get('metrics') await metrics.inc('jwt_issued_count') # добавляем токен в редис, в мидлвари будем проверять его наличие cache = app.get('cache') _already_in_redis_tokens = await cache.get_cache('uid_token_' + str(user['id'])) if not _already_in_redis_tokens: _already_in_redis_tokens = [] _already_in_redis_tokens.append(token) await cache.set_cache('uid_token_' + str(user['id']), _already_in_redis_tokens) await cache.expire_cache('uid_token_' + str(user['id']), (JWT_EXP_DELTA_SECONDS - 2)) logger.debug(json.dumps(user, cls=DateTimeAwareEncoder)) return web.json_response({ 'token': token, 'user': user }, dumps=self.__encode_helper) logger.debug('Login FAILED!') raise web.HTTPUnauthorized( body=b'Invalid username/password combination')