def test_crud_update_admin_other_user(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'emailconfirmationtoken', 'uid': token.get_uid(), 'data': { 'token': 'whatever' } } } ) assert response.status_code == 200 assert response.json['success'] assert response.json['results'][0]['token'] == 'whatever' with DbSessionContext(config.get('mongo_database_name')) as session: assert session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.token == 'whatever').one()
def test_crud_delete_all_notification_for_specific_user_by_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User)\ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'notification', 'filters': { 'user_uid': user.get_uid() } } }) assert response.status_code == 200 assert response.json['success'] assert response.json['total'] == 4 with DbSessionContext(config.get('mongo_database_name')) as session: assert not session.query(Notification)\ .filter(Notification.user_uid == user.get_uid()).count()
def test_crud_update_sanitize_data_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() # CHANGING ROLE IS ALLOWED FOR ADMIN response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'user', 'uid': user.get_uid(), 'data': { 'role': 'admin' } } } ) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() assert user.role == 'admin'
def test_crud_update_admin_other_user(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'user', 'uid': user.get_uid(), 'data': { 'name': 'new_name' } } } ) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() assert user.name == 'new_name'
def test_crud_delete_all_user_disabled_admin_success(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: assert session.query(User) \ .filter(User.enable == False).count() == 1 # noqa response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'user', 'filters': { 'enable': False } } } ) assert response.status_code == 200 assert response.json['success'] assert response.json['total'] == 1 with DbSessionContext(config.get('mongo_database_name')) as session: assert not session.query(User) \ .filter(User.enable == False).count() # noqa
def test_crud_delete_admin_success(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() token_uid = token.get_uid() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'emailconfirmationtoken', 'uid': token_uid } } ) assert response.status_code == 200 assert response.json['success'] assert response.json['total'] == 1 with DbSessionContext(config.get('mongo_database_name')) as session: assert not session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.mongo_id == token_uid).count()
def test_crud_delete_all_user_disabled_admin_success(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: assert session.query(User) \ .filter(User.enable == False).count() == 1 # noqa response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'user', 'filters': { 'enable': False } } }) assert response.status_code == 200 assert response.json['success'] assert response.json['total'] == 1 with DbSessionContext(config.get('mongo_database_name')) as session: assert not session.query(User) \ .filter(User.enable == False).count() # noqa
def test_crud_update_admin_other_user(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'emailconfirmationtoken', 'uid': token.get_uid(), 'data': { 'token': 'whatever' } } }) assert response.status_code == 200 assert response.json['success'] assert response.json['results'][0]['token'] == 'whatever' with DbSessionContext(config.get('mongo_database_name')) as session: assert session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.token == 'whatever').one()
def test_crud_update_sanitize_data_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() # CHANGING ROLE IS ALLOWED FOR ADMIN response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'user', 'uid': user.get_uid(), 'data': { 'role': 'admin' } } }) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() assert user.role == 'admin'
def test_crud_update_admin_other_user(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'user', 'uid': user.get_uid(), 'data': { 'name': 'new_name' } } }) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() assert user.name == 'new_name'
def test_crud_delete_admin_success(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() token_uid = token.get_uid() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'emailconfirmationtoken', 'uid': token_uid } }) assert response.status_code == 200 assert response.json['success'] assert response.json['total'] == 1 with DbSessionContext(config.get('mongo_database_name')) as session: assert not session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.mongo_id == token_uid).count()
def test_crud_delete_all_notification_for_specific_user_by_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User)\ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'notification', 'filters': { 'user_uid': user.get_uid() } } } ) assert response.status_code == 200 assert response.json['success'] assert response.json['total'] == 4 with DbSessionContext(config.get('mongo_database_name')) as session: assert not session.query(Notification)\ .filter(Notification.user_uid == user.get_uid()).count()
def test_crud_update_notification_by_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User)\ .filter(User.email == '*****@*****.**').one() notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid()).first() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'notification', 'uid': notification.get_uid(), 'data': { 'seen': True, 'message': 'Updated test' } } } ) assert response.status_code == 200 assert response.json['success'] assert response.json['results'][0]['seen'] assert response.json['results'][0]['message'] == 'Updated test' assert response.json['results'][0]['seen_timestamp']
def test_crud_read_specific_notification(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid()).first() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'notification', 'uid': notification.get_uid() } } ) assert response.status_code == 200 assert response.json['success'] assert type(response.json['results']) == list assert response.json['results'][0]['message'] == 'Test 1' assert response.json['results'][0]['uid'] == notification.get_uid() assert not response.json['results'][0]['seen'] assert response.json['total'] == 1 assert len(response.json['results']) == 1
def test_crud_update_notification_by_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User)\ .filter(User.email == '*****@*****.**').one() notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid()).first() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'notification', 'uid': notification.get_uid(), 'data': { 'seen': True, 'message': 'Updated test' } } }) assert response.status_code == 200 assert response.json['success'] assert response.json['results'][0]['seen'] assert response.json['results'][0]['message'] == 'Updated test' assert response.json['results'][0]['seen_timestamp']
def test_crud_update_normal_user_not_authorized(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: admin = session.query(User) \ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == admin.get_uid()).one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'emailconfirmationtoken', 'uid': token.get_uid(), 'data': { 'name': 'new_name' } } }) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'NotAuthorizedException'
def test_crud_read_for_normal_user(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: admin = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'user', 'uid': user.get_uid() } }) assert response.status_code == 200 assert response.json['success'] assert response.json['results'][0]['name'] == 'test' assert response.json['total'] == 1 response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'user', 'uid': admin.get_uid() } }) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'NotAuthorizedException'
def test_crud_update_normal_user_not_authorized(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: admin = session.query(User) \ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == admin.get_uid()).one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'emailconfirmationtoken', 'uid': token.get_uid(), 'data': { 'name': 'new_name' } } } ) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'NotAuthorizedException'
def test_validate_reset_password_token_expired(client): loop = asyncio.get_event_loop() asyncio.set_event_loop(loop) with DbSessionContext(config.get('mongo_database_name')) as session: old_datetime = dateutil_parser.parse('2012 12 22 00:00:00') user = session.query(User).filter(User.email == '*****@*****.**').one() reset_password_token = Resetpasswordtoken() context = { 'db_session': session, 'author': user, 'data': { 'user_uid': user.get_uid() }, 'mock_expiration_date': old_datetime } loop.run_until_complete( reset_password_token.validate_and_save(context)) old_token = reset_password_token.token response = client.post_json('/api/validate_reset_password_token', { 'token': client.__token__, 'reset_password_token': old_token }) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'TokenExpiredException'
async def middleware(request): if request.path.startswith('/api/'): request.db_session = Session.connect( config.get("mongo_database_name")) response = await handler(request) return response
def send_email_confirmation_email(self, queue, email_confirmation_token): # FORMAT EMAIL TEMPLATE email = config.get('email_confirmation_email') email = email.copy() email['text'] = email['text'].format( email_validation_token=self.email_validation_token.token) email['html'] = email['html'].format( email_validation_token=self.email_validation_token.token) email['to'][0]['email'] = email['to'][0]['email'].format( user_email=self.email) email['to'][0]['name'] = email['to'][0]['name'].format( user_name=self.name) # ADD THE SEND EMAIL TO THE QUEUE queue.enqueue(send_email, config.get('rest_api_id'), config.get('rest_api_secret'), email)
def run_migration_script(migration_script): name = migration_script.split(os.sep)[-1] spec = importlib.util.spec_from_file_location( "db_migration_scripts", migration_script ) migration_cls = importlib.util.module_from_spec(spec) spec.loader.exec_module(migration_cls) migration = migration_cls.Migration( name, config.get('mongo_database_name') ) ret = migration.run() if ret: click.echo( click.style( '{migration_script} succeeded!' .format(migration_script=migration_script), bg='green' ) ) else: click.echo( click.style( '{migration_script} failed!' .format(migration_script=migration_script), bg='red' ) ) return ret
def test_validate_reset_password_token_expired(client): loop = asyncio.get_event_loop() asyncio.set_event_loop(loop) with DbSessionContext(config.get('mongo_database_name')) as session: old_datetime = dateutil_parser.parse('2012 12 22 00:00:00') user = session.query(User).filter(User.email == '*****@*****.**').one() reset_password_token = Resetpasswordtoken() context = { 'db_session': session, 'author': user, 'data': { 'user_uid': user.get_uid() }, 'mock_expiration_date': old_datetime } loop.run_until_complete( reset_password_token.validate_and_save(context) ) old_token = reset_password_token.token response = client.post_json( '/api/validate_reset_password_token', { 'token': client.__token__, 'reset_password_token': old_token } ) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'TokenExpiredException'
async def middleware(request): if request.path.startswith('/api/'): request.db_session = Session.connect( config.get("mongo_database_name") ) response = await handler(request) return response
class Recognize(APIView): """ 识植物模块 """ APPID = config.get('BAIDU', 'appid') APPKEY = config.get('BAIDU', 'appkey') APPSECRET = config.get('BAIDU', 'appsecret') client = AipImageClassify(APPID, APPKEY, APPSECRET) def post(self, *args, **kwargs): form = UploadRecognizeFileForm(self.request.POST, self.request.FILES) if form.is_valid(): res = self.client.plantDetect( form.cleaned_data.get('image').read()) name = res.get('result')[0].get('name') score = res.get('result')[0].get('score') return ApiResponse({'name': name, 'score': score}) else: logger.error("上传失败" + form.errors) return ApiResponse(message="上传失败")
def test_confirm_email_right_token(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: token = session.query(Emailconfirmationtoken)\ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json('/api/confirm_email', {'token': token.token}) assert response.status_code == 200 assert response.json['success'] assert response.json['user']['email'] == '*****@*****.**' with DbSessionContext(config.get('mongo_database_name')) as session: last_notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid())\ .descending(Notification.created_ts)\ .first() assert last_notification.message == \ 'notification.YourEmailHasBeenConfirmed'
def on_model_change(self, form, model, is_created): logger.info("on_model_change") with DbSessionContext(config.get('mongo_database_name')) as session: try: m = importlib.import_module( 'server.model.{model}' .format(model=self.name.lower()) ) model_class = getattr(m, self.name) if not is_created: model_obj = session.query(model_class)\ .filter(model_class.mongo_id == model['_id'])\ .one() else: model_obj = model_class() context = {} context['db_session'] = session context['author'] = login.current_user context['data'] = form.data context['save'] = True loop.run_until_complete(model_obj.validate_and_save(context)) pk = model_obj.get_uid() self.coll.update({'_id': pk}, model) except Exception as e: if isinstance(e, exceptions.ServerBaseException): flash( gettext( 'Failed to update record. %(exception)s(%(error)s)', exception=e.get_name(), error=e ), 'error' ) else: flash( gettext( 'Failed to update record. %(error)s', error=e ), 'error' ) return False else: self.after_model_change(form, model, True) return True
def test_confirm_email_right_token_wrong_user(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User)\ .filter(User.email == '*****@*****.**').one() token = session.query(Emailconfirmationtoken)\ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json('/api/confirm_email', {'token': token.token}) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'TokenViolationException'
def send_email_confirmation_email(self, queue, email_confirmation_token): # FORMAT EMAIL TEMPLATE email = config.get('email_confirmation_email') email = email.copy() email['text'] = email['text'].format( email_validation_token=self.email_validation_token.token ) email['html'] = email['html'].format( email_validation_token=self.email_validation_token.token ) email['to'][0]['email'] = email['to'][0]['email'].format( user_email=self.email ) email['to'][0]['name'] = email['to'][0]['name'].format( user_name=self.name ) # ADD THE SEND EMAIL TO THE QUEUE queue.enqueue( send_email, config.get('rest_api_id'), config.get('rest_api_secret'), email )
async def api_send_reset_password_token(request): logger.debug('send_reset_password_token') session = await get_session(request) try: data = await request.json() email = data['email'] except: raise exceptions.InvalidRequestException('Missing json data') user_query = request.db_session.query(User)\ .filter(User.email == email) if user_query.count(): user = user_query.one() # NOTE disable user cannot reset their password if not user.enable: raise exceptions.EmailNotFound( '{email} belong to a disabled user'.format(email=email)) context = { 'user': user, 'db_session': request.db_session, 'ws_session': session, 'method': 'create', 'data': { 'user_uid': user.get_uid() }, 'queue': request.app.queue } reset_password_token = Resetpasswordtoken() await reset_password_token.validate_and_save(context) resp_data = {'success': True} # TEST if config.get('env', 'production') in ['development', 'test']: resp_data['reset_password_token'] = reset_password_token.token return web.json_response(resp_data) # EMAIL NOT FOUND else: raise exceptions.EmailNotFound(email)
def test_confirm_email_already_confirmed(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: token = session.query(Emailconfirmationtoken)\ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json('/api/confirm_email', {'token': token.token}) assert response.status_code == 200 assert response.json['success'] response = client.post_json('/api/confirm_email', {'token': token.token}) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'TokenAlreadyUsedException'
async def api_send_reset_password_token(request): session = await get_session(request) try: data = await request.json() email = data['email'] except: raise exceptions.InvalidRequestException('Missing json data') user_query = request.db_session.query(User)\ .filter(User.email == email) if user_query.count(): user = user_query.one() # NOTE disable user cannot reset their password if not user.enable: raise exceptions.EmailNotFound( '{email} belong to a disabled user'.format(email=email) ) context = { 'user': user, 'db_session': request.db_session, 'ws_session': session, 'method': 'create', 'data': { 'user_uid': user.get_uid() }, 'queue': request.app.queue } reset_password_token = Resetpasswordtoken() await reset_password_token.validate_and_save(context) resp_data = {'success': True} # TEST if config.get('env', 'production') in ['development', 'test']: resp_data['reset_password_token'] = reset_password_token.token return web.json_response(resp_data) # EMAIL NOT FOUND else: raise exceptions.EmailNotFound(email)
def test_crud_combination_multiple_model_multiple_action_by_user_some_allowed(client): # noqa user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: admin = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': [{ 'action': 'create', 'model': 'user', 'data': { 'email': '*****@*****.**', 'name': 'New test', 'password': '******' } }, { 'action': 'read', 'model': 'notification', 'filters': { 'user_uid': user.get_uid() } }, { 'action': 'update', 'model': 'user', 'uid': admin.get_uid(), 'data': { 'name': 'New admin' } }] } ) assert response.status_code == 200 assert not response.json['success'] assert type(response.json['error']) == list assert len(response.json['error']) == 2 assert response.json['error'][0] == 'NotAuthorizedException' assert response.json['error'][1] == 'NotAuthorizedException' assert response.json['results'][0]['error'] == 'NotAuthorizedException' assert response.json['results'][1]['total'] == 4 assert response.json['results'][2]['error'] == 'NotAuthorizedException'
def test_crud_combination_multiple_model_multiple_action_by_user_some_allowed( client): # noqa user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: admin = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': [{ 'action': 'create', 'model': 'user', 'data': { 'email': '*****@*****.**', 'name': 'New test', 'password': '******' } }, { 'action': 'read', 'model': 'notification', 'filters': { 'user_uid': user.get_uid() } }, { 'action': 'update', 'model': 'user', 'uid': admin.get_uid(), 'data': { 'name': 'New admin' } }] }) assert response.status_code == 200 assert not response.json['success'] assert type(response.json['error']) == list assert len(response.json['error']) == 2 assert response.json['error'][0] == 'NotAuthorizedException' assert response.json['error'][1] == 'NotAuthorizedException' assert response.json['results'][0]['error'] == 'NotAuthorizedException' assert response.json['results'][1]['total'] == 4 assert response.json['results'][2]['error'] == 'NotAuthorizedException'
def test_crud_delete_not_allowed_for_normal_user(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'emailconfirmationtoken', 'uid': token.get_uid() } }) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'NotAuthorizedException'
async def post(self): try: data = await self.request.json() except: raise exceptions.InvalidRequestException('No json send') context = { 'db_session': self.request.db_session, 'ws_session': {'tz': data.get('user_timezone')}, 'method': 'create', 'queue': self.request.app.queue } {%- if cookiecutter.closed_registration == 'y' %} # ClOSED REGISTRATION registration_token = data.get('registration_token') if registration_token != \ config.get('registration_token'): raise exceptions.InvalidRegistrationTokenException() {%- endif %} # INIT USER user = User() context['data'] = data sane_data = await user.sanitize_data(context) context['data'] = sane_data await user.validate_and_save(context) # SET SESSION await set_session(user, self.request) session = await get_session(self.request) session['tz'] = data.get('user_timezone') context['method'] = 'read' context['user'] = user context['ws_session'] = session resp_data = { 'success': True, 'user': await user.serialize(context), 'token': session['csrf_token'] } return web.json_response(resp_data)
def test_crud_read_specific_user_with_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'user', 'uid': user.get_uid() } }) assert response.status_code == 200 assert response.json['success'] assert len(response.json['results']) == 1 assert response.json['results'][0]['name'] == 'test'
def run_migration_script(migration_script): name = migration_script.split(os.sep)[-1] spec = importlib.util.spec_from_file_location("db_migration_scripts", migration_script) migration_cls = importlib.util.module_from_spec(spec) spec.loader.exec_module(migration_cls) migration = migration_cls.Migration(name, config.get('mongo_database_name')) ret = migration.run() if ret: click.echo( click.style('{migration_script} succeeded!'.format( migration_script=migration_script), bg='green')) else: click.echo( click.style('{migration_script} failed!'.format( migration_script=migration_script), bg='red')) return ret
def test_crud_delete_not_allowed_for_normal_user(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: token = session.query(Emailconfirmationtoken) \ .filter(Emailconfirmationtoken.user_uid == user.get_uid()).one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'emailconfirmationtoken', 'uid': token.get_uid() } } ) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'NotAuthorizedException'
def test_crud_read_specific_user_with_admin(client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'user', 'uid': user.get_uid() } } ) assert response.status_code == 200 assert response.json['success'] assert len(response.json['results']) == 1 assert response.json['results'][0]['name'] == 'test'
def test_after_delete_and_before_delete_called(adm, bdm, client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() user_uid = user.get_uid() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'user', 'uid': user_uid } }) assert response.status_code == 200 assert response.json['success'] assert adm.called assert bdm.called
def test_crud_update_email(client): user = client.login('*****@*****.**') response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'user', 'uid': user.get_uid(), 'data': { 'name': 'new_name', 'email': '*****@*****.**' } } } ) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user_query = session.query(User) \ .filter(User.email == '*****@*****.**') assert user_query.count() user = user_query.one() assert user.name == 'new_name' assert not user.email_confirmed last_notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid())\ .descending(Notification.created_ts)\ .first() assert last_notification.message == \ 'notification.PleaseConfirmYourEmail'
def test_get_session_with_logged_disabled_user(client): user = client.login('*****@*****.**') # Get session data = {'user_timezone': 'Australia/Sydney'} response = client.post_json('/api/get_session', data) assert response.status_code == 200 assert response.json['success'] assert response.json['user']['email'] == user.email assert response.json['user']['name'] == user.name assert response.status_code == 200 assert response.json['success'] # Disable user with DbSessionContext(config.get('mongo_database_name')) as session: user.enable = False session.update(user) # Get session data = {'user_timezone': 'Australia/Sydney'} response = client.post_json('/api/get_session', data) assert not response.json['user'] assert response.status_code == 200 assert not response.json['success'] # Login response = client.post_json( '/api/login', { 'email': '*****@*****.**', 'password': '******', 'token': client.__token__ } ) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'WrongEmailOrPasswordException'
def test_crud_read_for_normal_user(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: admin = session.query(User) \ .filter(User.email == '*****@*****.**').one() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'user', 'uid': user.get_uid() } } ) assert response.status_code == 200 assert response.json['success'] assert response.json['results'][0]['name'] == 'test' assert response.json['total'] == 1 response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'user', 'uid': admin.get_uid() } } ) assert response.status_code == 200 assert not response.json['success'] assert response.json['error'] == 'NotAuthorizedException'
def test_register_with_right_token(client): response = client.post_json( '/api/register', { 'email': DEFAULT_EMAIL, 'name': DEFAULT_NAME, 'password': DEFAULT_PASSWORD, 'token': client.__token__ } ) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user_query = session.query(User) \ .filter(User.email == DEFAULT_EMAIL) assert user_query.count() == 1 user = user_query.one() assert user.email == DEFAULT_EMAIL # Obviously assert user.name == DEFAULT_NAME assert user.enable assert user.role == 'user'
def test_after_delete_and_before_delete_called(adm, bdm, client): client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: user = session.query(User) \ .filter(User.email == '*****@*****.**').one() user_uid = user.get_uid() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'delete', 'model': 'user', 'uid': user_uid } } ) assert response.status_code == 200 assert response.json['success'] assert adm.called assert bdm.called
def test_crud_read_specific_notification(client): user = client.login('*****@*****.**') with DbSessionContext(config.get('mongo_database_name')) as session: notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid()).first() response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'read', 'model': 'notification', 'uid': notification.get_uid() } }) assert response.status_code == 200 assert response.json['success'] assert type(response.json['results']) == list assert response.json['results'][0]['message'] == 'Test 1' assert response.json['results'][0]['uid'] == notification.get_uid() assert not response.json['results'][0]['seen'] assert response.json['total'] == 1 assert len(response.json['results']) == 1
def test_crud_update_email(client): user = client.login('*****@*****.**') response = client.post_json( '/api/crud', { 'token': client.__token__, 'actions': { 'action': 'update', 'model': 'user', 'uid': user.get_uid(), 'data': { 'name': 'new_name', 'email': '*****@*****.**' } } }) assert response.status_code == 200 assert response.json['success'] with DbSessionContext(config.get('mongo_database_name')) as session: user_query = session.query(User) \ .filter(User.email == '*****@*****.**') assert user_query.count() user = user_query.one() assert user.name == 'new_name' assert not user.email_confirmed last_notification = session.query(Notification)\ .filter(Notification.user_uid == user.get_uid())\ .descending(Notification.created_ts)\ .first() assert last_notification.message == \ 'notification.PleaseConfirmYourEmail'
async def init(loop, config_args=None): # CONFIG config.configure(config_args) logger.info('Env: {env}'.format(env=config.get('env'))) # SESSION redis_db = config.get('redis_database', 0) redis_pool = await aioredis.create_pool(('localhost', 6379), db=redis_db) storage = redis_storage.RedisStorage( redis_pool, cookie_name="AIOHTTP_SESSION-{redis_db}".format(redis_db=redis_db)) app = web.Application( loop=loop, middlewares=[session_middleware(storage), db_handler]) app.redis_pool = redis_pool # QUEUE app.queue = Queue(connection=Redis()) # WEBSOCKET """ app['websockets'] = [] """ handler = app.make_handler() # ROUTES for route in routes: app.router.add_route(route[0], route[1], route[2], name=route[3]) if config.get('env', 'production') == 'development': static_path = os.path.join(ROOT, 'dist-dev') else: if config.get('release', 'latest') == 'latest': latest_version_path = os.path.join(ROOT, 'releases', 'latest.txt') if os.path.exists(latest_version_path): with open(latest_version_path, 'r') as fd: release_version = fd.read() else: raise Exception("The latest.txt file doesn't exists") else: release_version = config.get('release') static_path = os.path.join(ROOT, 'releases', release_version) app.router.add_static('/', static_path, name='static') logger.info( "Serving static: {static_path}".format(static_path=static_path)) aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader(static_path)) # PREPARE HOOK async def after_request(request, response): if hasattr(request, 'db_session'): request.db_session.end() request.db_session.db.client.close() app.on_response_prepare.append(after_request) # SHUTDOWN app.on_shutdown.append(on_shutdown) serv_generator = loop.create_server(handler, config.get('server_host'), config.get('server_port')) return serv_generator, handler, app
from server.settings import config # CONFIGURE config.configure() # PATHS ROOT = os.path.abspath(os.path.dirname(__file__)) migration_scripts_path = os.path.join( ROOT, 'db_migration_scripts' ) # TODO get the mongo client from server/utils:get_mongo_client mongo_client = MongoClient() db = mongo_client[config.get('mongo_database_name')] def run_migration_script(migration_script): name = migration_script.split(os.sep)[-1] spec = importlib.util.spec_from_file_location( "db_migration_scripts", migration_script ) migration_cls = importlib.util.module_from_spec(spec) spec.loader.exec_module(migration_cls) migration = migration_cls.Migration( name, config.get('mongo_database_name') ) ret = migration.run()
async def init(loop, config_args=None): # CONFIG config.configure(config_args) logger.info('Env: {env}'.format(env=config.get('env'))) # SESSION redis_db = config.get('redis_database', 0) redis_pool = await aioredis.create_pool( ('localhost', 6379), db=redis_db ) storage = redis_storage.RedisStorage( redis_pool, cookie_name="AIOHTTP_SESSION-{redis_db}" .format(redis_db=redis_db) ) app = web.Application(loop=loop, middlewares=[ session_middleware(storage), db_handler ]) app.redis_pool = redis_pool # QUEUE app.queue = Queue(connection=Redis()) # WEBSOCKET """ app['websockets'] = [] """ handler = app.make_handler() # ROUTES for route in routes: app.router.add_route(route[0], route[1], route[2], name=route[3]) if config.get('env', 'production') == 'development': static_path = os.path.join(ROOT, 'dist-dev') else: if config.get('release', 'latest') == 'latest': latest_version_path = os.path.join( ROOT, 'releases', 'latest.txt' ) if os.path.exists(latest_version_path): with open(latest_version_path, 'r') as fd: release_version = fd.read() else: raise Exception("The latest.txt file doesn't exists") else: release_version = config.get('release') static_path = os.path.join(ROOT, 'releases', release_version) app.router.add_static('/', static_path, name='static') logger.info( "Serving static: {static_path}" .format( static_path=static_path ) ) aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader(static_path)) # PREPARE HOOK async def after_request(request, response): if hasattr(request, 'db_session'): request.db_session.end() request.db_session.db.client.close() app.on_response_prepare.append(after_request) # SHUTDOWN app.on_shutdown.append(on_shutdown) serv_generator = loop.create_server( handler, config.get('server_host'), config.get('server_port') ) return serv_generator, handler, app
async def validate_and_save(self, context): NOW = datetime.now() queue = context.get('queue') data = context.get('data') user = context.get('user') db_session = context.get('db_session') save = context.get('save', True) # BaseToken validate_and_save new_context = context.copy() new_context['save'] = False await super(Resetpasswordtoken, self).validate_and_save(new_context) # FOR TEST ONLY if config.get('env', 'production') == 'test': mock_expiration_date = context.get('mock_expiration_date', NOW) NOW = mock_expiration_date # EXPIRATION DATETIME expiration_datetime = data.get('expiration_datetime') if expiration_datetime: self.expiration_datetime = dateutil.parser.parse( expiration_datetime ) else: TOMORROW = NOW + relativedelta(days=+1) self.expiration_datetime = TOMORROW # PASSWORD RESET password_reset = data.get('password_reset') if password_reset is not None: self.password_reset = password_reset # SAVE if save: db_session.save(self, safe=True) # FORMAT EMAIL TEMPLATE if config.get('env', 'production') == 'production' \ and hasattr(queue, 'enqueue'): email = config.get('reset_password_email') email['text'] = email['text'].format( reset_password_token=self.token ) email['html'] = email['html'].format( reset_password_token=self.token ) email['to'][0]['email'] = email['to'][0]['email'].format( user_email=user.email ) email['to'][0]['name'] = email['to'][0]['name'].format( user_name=user.name ) # ADD THE SEND EMAIL TO THE QUEUE queue.enqueue( send_email, config.get('rest_api_id'), config.get('rest_api_secret'), email )
HERE = os.path.abspath(os.path.dirname(__file__)) ROOT = os.path.join(HERE, '..') sys.path.append(ROOT) from server.utils import drop_database # noqa from server.model.user import User # noqa from server.settings import config # noqa from server.model.notification import Notification # noqa from server.utils import DbSessionContext # noqa config.configure() loop = asyncio.get_event_loop() asyncio.set_event_loop(loop) if config.get('env', 'production') != 'development': print('The "env" variable is not set to development') sys.exit(1) DB_NAME = config.get('mongo_database_name') drop_database(DB_NAME, config.get('redis_database')) with DbSessionContext(DB_NAME) as session: # INSERT DUMMY DATA users = [ { 'name': 'test', 'email': '*****@*****.**', 'email_validation_token': '123456', 'password': '******' }, {
async def validate_and_save(self, context): queue = context.get('queue') data = context.get('data') db_session = context.get('db_session') save = context.get('save', True) is_new = await self.is_new() # EMAIL CONFIRMED email_confirmed = data.get('email_confirmed') if email_confirmed is not None: self.email_confirmed = email_confirmed if email_confirmed: notification_data = { 'message': 'notification.YourEmailHasBeenConfirmed' } await self.add_notification( db_session, notification_data ) # NAME name = data.get('name') if name: if len(name) < NAME_MIN_LEN or len(name) > NAME_MAX_LEN: raise exceptions.InvalidNameException(name) self.name = name else: if is_new: raise exceptions.InvalidNameException('empty name') # ROLE role = data.get('role') if role: self.role = role # LOCALE locale = data.get('locale') if locale: self.locale = locale # ENABLE enable = data.get('enable') if enable is not None: self.enable = enable # PASSWORD password = data.get('password') if password: await self.set_password(password) else: if is_new: raise exceptions.InvalidPasswordException('empty password') # NEW PASSWORD new_password = data.get('new_password') if new_password: old_password = data.get('old_password') if old_password: is_password_valid = await self.check_password(old_password) if is_password_valid: await self.set_password(new_password) else: raise exceptions.WrongPasswordException() else: raise exceptions.InvalidRequestException( 'Missing old password' ) # EMAIL email = data.get('email') if email: email = email.lower() if is_new or self.email != email: is_email_valid = validate_email(email) if not is_email_valid: raise exceptions.InvalidEmailException(email) email_uniqueness_query = db_session.query(User)\ .filter(User.email == email) if not is_new: email_uniqueness_query = email_uniqueness_query\ .filter(User.mongo_id != self.get_uid()) if email_uniqueness_query.count(): raise exceptions.EmailAlreadyExistsException(email) self.email = email self.email_confirmed = False # NOTIFICATON FOR CONFIRMATION EMAIL if not is_new: notification_data = { 'message': 'notification.PleaseConfirmYourEmail', 'template_data': {'email': email} } await self.add_notification(db_session, notification_data) # GRAVATAR gravatar_url = "{base_url}{md5_hash}?{params}".format( base_url="https://www.gravatar.com/avatar/", md5_hash=hashlib.md5( email.lower().encode('utf') ).hexdigest(), params=urllib.parse.urlencode( {'d': "identicon", 's': '40'} ) ) self.gravatar_url = gravatar_url else: if is_new: raise exceptions.InvalidEmailException('empty email') if save: db_session.save(self, safe=True) if not self.email_confirmed: email_confirmation_token = Emailconfirmationtoken() context['data']['user_uid'] = self.get_uid() await email_confirmation_token.validate_and_save(context) if config.get('env', 'production') == 'production' \ and hasattr(queue, 'enqueue'): self.send_email_confirmation_email( queue, email_confirmation_token )
class Account(APIView): """ 用户账户模块 """ APPID = config.get('WECHAT', 'appid') APPSECRET = config.get('WECHAT', 'appsecret') REQUEST_BASE_URL = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + APPID + '&secret=' + APPSECRET \ + '&grant_type=authorization_code&' def __init__(self): self.http_manager = urllib3.PoolManager() super().__init__() def get(self, *args, **kwargs): js_code = self.request.GET.get('js_code') user = None message = 'OK' status = HTTP_200_OK if js_code is None: message = '临时登录凭证js_code不能为空' status = HTTP_400_BAD_REQUEST else: user = self._login(js_code) if user is None: message = '服务器内部错误' status = HTTP_400_BAD_REQUEST else: user = UserSerializer(user) return ApiResponse(user.data, message=message, status=status) def _wechat_login(self, js_code): """ 调用微信登录接口 :param js_code: 登录凭证code :return: 成功返回解析后的dict,否则返回None """ req = self.http_manager.request( 'GET', Account.REQUEST_BASE_URL + 'js_code=' + js_code) print(req.data) if req.status != 200: logger.error('请求错误,HTTP Status:' + req.status) res = None else: res = json.loads(req.data) if res.get('errcode') is not None: logger.error('调用微信登录接口错误:' + res.get('errmsg')) res = None return res def _login(self, js_code): """ 用户登录 :param js_code: 临时登录凭证code :return: 成功则返回User对象,否则返回None """ res = self._wechat_login(js_code) if res is not None: if not User.objects.filter(openid=res.get('openid')).exists(): user = User.objects.create_user(res.get('openid')) else: user = User.objects.get(openid=res.get('openid')) user.token = Digest.get( user.openid.join( RandomString.get(10, ('NUMBER', 'LOWER_CASE_CHARACTER', 'UPPER_CASE_CHARACTER')))) user.last_login_time = datetime.datetime.now() user.save() return user else: return None
from jobs.send_email import PySendPulse # noqa from server.utils import generate_token # noqa from server.settings import config # noqa from server.auth.user import User # noqa config.configure(False) user = User() user.name = '' # CHANGEME user.email = '' # CHANGEME # SEND EMAIL VALIDATION TOKEN email_validation_token = generate_token(20) user.email_validation_token = email_validation_token # FORMAT EMAIL TEMPLATE email = config.get('email_confirmation_email') email['text'] = email['text'].format( email_validation_token=email_validation_token ) email['html'] = email['html'].format( email_validation_token=email_validation_token ) email['to'][0]['email'] = email['to'][0]['email'].format( user_email=user.email ) email['to'][0]['name'] = email['to'][0]['name'].format( user_name=user.name ) SPApiProxy = PySendPulse( config.get('REST_API_ID'),