diff --git a/CompanyUser/CompanyUserImpl.py b/CompanyUser/CompanyUserImpl.py index 5a2033a..5283ec6 100644 --- a/CompanyUser/CompanyUserImpl.py +++ b/CompanyUser/CompanyUserImpl.py @@ -9,10 +9,9 @@ from werkzeug.security import check_password_hash from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from DBHelper.MongoHelper import MongoHelper -from Utils.ErrorUtil import ReturnConditionCheckFailed, LogConditionCheckFailed +from Utils.ErrorUtil import ReturnConditionCheckFailed from CompanyUser.CompanyUserObj import CompanyUser, VerifyInfo, EmailVerifyCodeRecord, VerifyMaterial, \ CompanyVerifyThreeFactors -from Utils.ValidateUtil import ValidateAttr class CompanyUserImpl(CompanyUser): diff --git a/CompanyUser/CompanyUserRoute.py b/CompanyUser/CompanyUserRoute.py index 010d5bc..83e4c3a 100644 --- a/CompanyUser/CompanyUserRoute.py +++ b/CompanyUser/CompanyUserRoute.py @@ -1,7 +1,7 @@ from flask import Blueprint, request, Response from common.rsa import decrypt_data -from CompanyUser.CompanyUserAuth import check_block, verify_token +from Utils.AuthUtil import check_block, verify_token from Utils.ErrorUtil import ReturnConditionCheckFailed from CompanyUser.CompanyUserImpl import CompanyUserImpl, EmailVerifyCodeRecordImpl, VerifyMaterialImpl, \ CompanyVerifyThreeFactorsImpl diff --git a/Implements/Others/EmailNotice.py b/Implements/Others/EmailNotice.py new file mode 100644 index 0000000..b2f9c39 --- /dev/null +++ b/Implements/Others/EmailNotice.py @@ -0,0 +1,21 @@ +from Utils.ObjUtil import SpecObject +from Utils.ValidateUtil import ValidateAttr, Validate + + +class EmailNotice(SpecObject): + """用户邮件通知""" + + email = ValidateAttr(field='email', func=Validate.email, error_info='邮箱格式异常', error_code=200) + v_period = ValidateAttr(field='v_period', type=float, error_info='验证有效期格式异常', error_code=200) + v_code = ValidateAttr(field='v_code', type=str, length=6, error_info='验证码格式异常', error_code=200) + v_type = ValidateAttr(field="v_type", type=str, in_list=["register", "resetemail", "resetpwd"], error_info="邮件验证类型错误", error_code=200) + + fields_map = { + "email": "邮箱", + "v_period": "验证有效期", + "v_code": "验证码", + "v_type": "验证类型" + } + + def send_email(self): + """发送邮件""" diff --git a/Implements/User/TFSECompanyUserImpl.py b/Implements/User/TFSECompanyUserImpl.py new file mode 100644 index 0000000..539f2f5 --- /dev/null +++ b/Implements/User/TFSECompanyUserImpl.py @@ -0,0 +1,216 @@ +import json +import time +import random +import base64 +import requests +from urllib.request import Request, urlopen + +from werkzeug.security import check_password_hash, generate_password_hash +from itsdangerous import TimedJSONWebSignatureSerializer as Serializer + +from DBHelper.MongoHelper import MongoHelper +from ObjectsInProject.User.TFSECompanyUser import TFSECompanyUser + +from Utils.ErrorUtil import ReturnConditionCheckFailed + + +class TFSECompanyUserImpl(TFSECompanyUser): + """企业用户实现类""" + + db = MongoHelper("tfse_v0.21") + + def check_email_registered(self): + """检查邮箱已被注册""" + email = self.db.find_single_column( + "应用端", + "企业用户", + {"邮箱": self.email}, + "邮箱" + ) + if email is not None: + raise ReturnConditionCheckFailed("邮箱已被注册", 200) + + def check_email_not_registered(self): + """检查邮箱未被注册""" + email = self.db.find_single_column( + "应用端", + "企业用户", + {"邮箱": self.email}, + "邮箱" + ) + if email is None: + raise ReturnConditionCheckFailed("邮箱未被注册", 200) + + def check_vcode_correct(self, code): + """检查邮箱验证码是否正确""" + verify_data = self.db.find_single_data( + "应用端", + "邮箱验证码记录", + {"邮箱": self.email}, + ["验证码", "验证有效期"] + ) + + if not verify_data: + raise ReturnConditionCheckFailed("验证码错误", 200) + + if verify_data['验证码'] != code: + raise ReturnConditionCheckFailed("验证码错误", 200) + + if time.time() - verify_data['验证有效期'] > 300: + raise ReturnConditionCheckFailed('验证码过期', 200) + + def login(self): + """登录""" + + company_user = self.db.find_single_data( + "应用端", + "企业用户", + {"邮箱": self.email}, + ["企业ID", "企业名称", "邮箱", "密码", "已认证"] + ) + + def check_user_existed(): + """检查用户是否存在""" + if company_user is None: + raise ReturnConditionCheckFailed("不存在该用户", 200) + + def check_password_correct(): + """检查密码是否正确""" + if not check_password_hash(company_user['密码'], self.pwd): + raise ReturnConditionCheckFailed("登录密码错误", 200) + + def create_token(param): + """ + 创建token + param: 传入参数,用于创建token,一般为 {"cid": cid} + return: 用户token + """ + secret_key = '0FTuOi^#Afx1@2@F' + token_expire = 14400 + s = Serializer(secret_key, expires_in=token_expire) + token = '' + s.dumps(param).decode('ascii') + return token + + check_user_existed() + check_password_correct() + + self.cid = company_user['企业ID'] + self.name = self.get_attr(company_user, '企业名称', default='未认证企业用户') + self.verify_status = company_user['已认证'] + self.token = create_token({"cid": self.cid}) + + def register(self, code): + """注册""" + + def make_new_cid(): + """生成新的企业ID,如果该ID存在,则重新生成""" + + def random_cid(num): + """随机企业ID""" + choices = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + salt = '' + for i in range(num): + salt += random.choice(choices) + return salt + + new_cid = random_cid(8) + + case = self.db.find_single_column( + "应用端", + "企业用户", + {"企业ID": new_cid}, + "企业ID" + ) is not None + while case: + new_cid = random_cid(8) + return new_cid + + self.check_email_registered() + self.check_vcode_correct(code) + + self.cid = make_new_cid() + self.avatar_id = "623152edf36000004f00124e" + self.verify_status = "否" + + self.db.insert_single_data( + "应用端", + "企业用户", + self.dict_to_return() + ) + + self.db.delete_single_data( + "应用端", + "邮箱验证码记录", + {"邮箱": self.email} + ) + + def get_company_user_info(self): + """获取企业用户信息""" + company_user_data = self.db.find_single_data( + "应用端", + "企业用户", + {"企业ID": self.cid}, + ["企业ID", "企业名称", "邮箱", "已认证"] + ) + + self.name = self.get_attr(company_user_data, '企业名称', default='未认证企业用户') + self.email = company_user_data['邮箱'] + self.verify_status = company_user_data['已认证'] + + def get_avatar(self): + """获取用户头像""" + + self.avatar_id = self.db.find_single_column( + "应用端", + "企业用户", + {"企业ID": self.cid}, + "头像fid" + ) + + avatar = self.db.find_file( + "文件", + "企业用户头像", + self.avatar_id + ) + + return avatar + + def change_avatar(self, avatar_option): + """修改企业用户头像""" + avatars = { + "avatar_01": "623152edf36000004f00124e", + "avatar_02": "623152edf36000004f001250", + "avatar_03": "623152edf36000004f00124f", + "avatar_04": "623152edf36000004f001251", + "avatar_05": "623152edf36000004f001252", + "avatar_06": "623152edf36000004f001253" + } + self.avatar_id = avatars[avatar_option] + self.db.update_single_data( + "应用端", + "企业用户", + {"企业ID": self.cid}, + {"头像fid": self.avatar_id} + ) + + def change_password(self, code): + """修改登录密码""" + self.check_email_not_registered() + self.check_vcode_correct(code) + self.db.update_single_data( + "应用端", + "企业用户", + {"邮箱": self.email}, + self.dict_to_save(columns=["密码"]) + ) + + def change_email(self, code): + """更换邮箱""" + self.check_vcode_correct(code) + self.check_email_registered() + self.db.update_single_data( + "应用端", + "企业用户", + {"企业ID": self.cid}, + self.dict_to_save(columns=["邮箱"]) + ) \ No newline at end of file diff --git a/ObjectsCommon/User/ToBUser.py b/ObjectsCommon/User/ToBUser.py new file mode 100644 index 0000000..96e3fb2 --- /dev/null +++ b/ObjectsCommon/User/ToBUser.py @@ -0,0 +1,22 @@ +from Utils.ObjUtil import SpecObject +from Utils.ValidateUtil import ValidateAttr, Validate + + +class TobUser(SpecObject): + """企业用户类""" + + cid = ValidateAttr(field='cid', type=str) + pwd = ValidateAttr(field='pwd', func=Validate.password, error_info='密码强度不够') + name = ValidateAttr(field='name', type=str) + email = ValidateAttr(field='email', func=Validate.email, error_info='邮箱格式错误') + telephone = ValidateAttr(field='telephone', func=Validate.telephone, error_info='手机号格式错误') + register_time = ValidateAttr(field='register_time', func=Validate.time_format) + + fields_map = { + "cid": "企业ID", + "pwd": "密码", + "name": "企业名称", + "email": "邮箱", + "telephone": "手机号", + "register_time": "注册时间" + } diff --git a/ObjectsCommon/User/ToCUser.py b/ObjectsCommon/User/ToCUser.py new file mode 100644 index 0000000..dd3ae2f --- /dev/null +++ b/ObjectsCommon/User/ToCUser.py @@ -0,0 +1,20 @@ +from Utils.ObjUtil import SpecObject +from Utils.ValidateUtil import ValidateAttr + + +class User(SpecObject): + """普通用户""" + + uid = ValidateAttr(field='uid', type=str) + name = ValidateAttr(field='name', type=str) + pwd = ValidateAttr(field='pwd', type=str) + email = ValidateAttr(field='email', type=str) + telephone = ValidateAttr(field='telephone', type=str) + + fields_map = { + "uid": "用户ID", + "name": "姓名", + "pwd": "密码", + "email": "邮箱", + "telephone": "手机号" + } diff --git a/ObjectsInProject/User/TFSECompanyUser.py b/ObjectsInProject/User/TFSECompanyUser.py new file mode 100644 index 0000000..64841f9 --- /dev/null +++ b/ObjectsInProject/User/TFSECompanyUser.py @@ -0,0 +1,79 @@ +from werkzeug.security import generate_password_hash + +from Utils.ObjUtil import SpecObject +from Utils.ValidateUtil import ValidateAttr, Validate + + +class TFSECompanyUser(SpecObject): + """天府股交项企业用户""" + + class VerifyInfo(SpecObject): + """认证信息""" + name = ValidateAttr(field='name', type=str) + code = ValidateAttr(field='code', type=str) + legal_person = ValidateAttr(field='legal_person', type=str) + legal_person_id = ValidateAttr(field='legal_person_id', type=str) + + fields_map = { + "name": "企业名称", + "code": "统一社会信用代码", + "legal_person": "法人姓名", + "legal_person_id": "法人身份证号" + } + + cid = ValidateAttr(field='cid', type=str) + pwd = ValidateAttr(field='pwd', func=Validate.password, error_info='密码强度不够') + name = ValidateAttr(field='name', type=str) + email = ValidateAttr(field='email', func=Validate.email, error_info='邮箱格式错误') + telephone = ValidateAttr(field='telephone', func=Validate.telephone, error_info='手机号格式错误') + register_time = ValidateAttr(field='register_time', func=Validate.time_format) + avatar_id = ValidateAttr(field='avatar_id', type=str, length=24) + verify_status = ValidateAttr(field='verify_status', in_list=["是", "否"]) + verify_info = ValidateAttr(field='verify_info', type=VerifyInfo) + token = ValidateAttr(field='token', type=str) + + fields_map = { + "cid": "企业ID", + "pwd": "密码", + "name": "企业名称", + "email": "邮箱", + "telephone": "手机号", + "register_time": "注册时间", + "avatar_id": "头像fid", + "verify_status": "已认证", + "verify_info": "认证信息", + "token": "token" + } + + def dict_to_return(self, **kwargs): + _dict_ = self.dict_keys_toggle(columns=kwargs['columns']) if kwargs.__contains__('columns') else self.dict_keys_toggle() + + if kwargs.__contains__('verify_status'): + if kwargs['verify_status'] is True: + _dict_['认证状态'] = '已认证' if _dict_.pop('已认证') == '是' else '未认证' + + if _dict_.__contains__('密码'): + _dict_['密码'] = generate_password_hash(_dict_['密码']) + + return _dict_ + + def login(self, **kwargs): + """登录""" + + def register(self, **kwargs): + """注册""" + + def get_company_user_info(self): + """获取企业用户信息""" + + def get_avatar(self): + """获取用户头像""" + + def change_avatar(self, **kwargs): + """修改用户头像""" + + def change_password(self, **kwargs): + """修改登录密码""" + + def change_email(self, **kwargs): + """修改登录邮箱""" diff --git a/ObjectsInProject/User/__init__.py b/ObjectsInProject/User/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Rating/Credit/CreditRoutes.py b/Rating/Credit/CreditRoutes.py index 102ca99..5263ae1 100644 --- a/Rating/Credit/CreditRoutes.py +++ b/Rating/Credit/CreditRoutes.py @@ -1,5 +1,5 @@ from flask import Blueprint, request -from CompanyUser.CompanyUserAuth import verify_token, verify_real_company +from Utils.AuthUtil import verify_token, verify_real_company from Rating.Credit.CreditImpl import CreditRating from Utils.ErrorUtil import ReturnConditionCheckFailed diff --git a/Rating/Esg/EsgRoutes.py b/Rating/Esg/EsgRoutes.py index 04a4c6e..41d4212 100644 --- a/Rating/Esg/EsgRoutes.py +++ b/Rating/Esg/EsgRoutes.py @@ -1,5 +1,5 @@ from flask import Blueprint, request -from CompanyUser.CompanyUserAuth import verify_token, verify_real_company +from Utils.AuthUtil import verify_token from Rating.Esg.EsgImpl import EsgRating from Utils.ErrorUtil import ReturnConditionCheckFailed diff --git a/Routes/Company/Index.py b/Routes/Company/Index.py index c3b0f23..1aebc79 100644 --- a/Routes/Company/Index.py +++ b/Routes/Company/Index.py @@ -1,7 +1,7 @@ from flask import Blueprint -from CompanyUser.CompanyUserAuth import verify_token +from Utils.AuthUtil import verify_token from Utils.ErrorUtil import ReturnConditionCheckFailed from Implements.Company.Index import CompanyIndexImpl diff --git a/Routes/User/TFSECompanyUserRoute.py b/Routes/User/TFSECompanyUserRoute.py new file mode 100644 index 0000000..f4e06b7 --- /dev/null +++ b/Routes/User/TFSECompanyUserRoute.py @@ -0,0 +1,207 @@ +from flask import Blueprint, request, Response + +from Implements.User.TFSECompanyUserImpl import TFSECompanyUserImpl +from common.rsa import decrypt_data +from Utils.AuthUtil import check_block, verify_token +from Utils.ErrorUtil import ReturnConditionCheckFailed +from CompanyUser.CompanyUserImpl import EmailVerifyCodeRecordImpl, VerifyMaterialImpl, \ + CompanyVerifyThreeFactorsImpl + +company_user_route = Blueprint('user', __name__) + + +@company_user_route.route('/login', methods=['POST']) +@check_block +def login(): + """企业用户登录""" + try: + impl = TFSECompanyUserImpl() + impl.email = request.json['email'] + try: + impl.pwd = decrypt_data(encrypt_msg=request.json['pwd']) + except Exception: + return {"info": "登录密码错误"}, 200 + impl.login() + result = impl.dict_to_return(columns=["企业名称", "已认证", "token"], verify_status=True) + return {"info": "登陆成功", "result": result}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/register', methods=['POST']) +@check_block +def register(): + """企业用户注册""" + try: + req = request.json + company_user = TFSECompanyUserImpl() + company_user.email = req['email'] + try: + company_user.pwd = decrypt_data(encrypt_msg=req['pwd']) + except Exception: + return {"info": "密码格式错误"}, 200 + company_user.register(req['code']) + response = {"info": "注册成功"}, 200 + return response + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/user_info', methods=['GET']) +@verify_token +def user_info(**kwargs): + """获取企业用户信息""" + try: + impl = TFSECompanyUserImpl() + impl.cid = kwargs['cid'] + impl.get_company_user_info() + result= impl.dict_to_return(columns=["企业ID", "企业名称", "邮箱", "已认证"], verify_status=True) + return {"info": "查询结果", "result": result}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/get_avatar', methods=['GET']) +@verify_token +def get_avatar(**kwargs): + """获取头像""" + try: + impl = TFSECompanyUserImpl() + impl.cid = kwargs['cid'] + response = Response(impl.get_avatar(), content_type='image/jpeg') + return response + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/change_avatar', methods=['POST']) +@verify_token +def change_avatar(**kwargs): + """修改头像""" + try: + impl = TFSECompanyUserImpl() + impl.cid = kwargs['cid'] + impl.change_avatar(request.json['avatar_id']) + return {"info": "修改成功"}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/change_pwd', methods=['POST']) +@check_block +def change_pwd(): + """修改密码""" + try: + req = request.json + impl = TFSECompanyUserImpl() + impl.email = req['email'] + impl.pwd = decrypt_data(encrypt_msg=req['pwd']) + impl.change_password(req['code']) + return {"info": "修改成功"}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/change_email', methods=['POST']) +@check_block +@verify_token +def change_email(**kwargs): + """更换账号邮箱""" + try: + req = request.json + impl = TFSECompanyUserImpl() + impl.cid = kwargs['cid'] + impl.email = req['email'] + impl.change_email(req['code']) + return {"info": "修改成功"}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/verify_email', methods=['POST']) +@check_block +def verify_email(): + """发送邮箱验证码""" + try: + req = request.json + email_verify = EmailVerifyCodeRecordImpl() + email_verify.email = req['email'] + email_verify.v_type = req['v_type'] + email_verify.send_email() + return {"info": "邮件已发送"}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/upload_id_card', methods=['POST']) +@verify_token +def upload_id_card(**kwargs): + """上传身份证""" + try: + material = VerifyMaterialImpl() + material.cid = kwargs['cid'] + material.image = request.files['image'] + result = material.upload_id_card() + return {"info": "识别结果", "result": result}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/upload_business_license', methods=['POST']) +@verify_token +def upload_business_license(**kwargs): + """上传营业执照""" + try: + material = VerifyMaterialImpl() + material.cid = kwargs['cid'] + material.image = request.files['image'] + result = material.upload_business_license() + return {"info": "识别结果", "result": result}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 + + +@company_user_route.route('/company_verify', methods=['GET']) +@verify_token +def company_verify_route(**kwargs): + """企业认证""" + try: + company_verify = CompanyVerifyThreeFactorsImpl() + company_verify.cid = kwargs['cid'] + company_verify.company_verify() + return {"info": "认证成功"}, 200 + except ReturnConditionCheckFailed as e: + e.log_error() + return {"info": e.failed_info}, e.status_code + except KeyError: + return {"info": "参数异常"}, 400 diff --git a/Routes/User/__init__.py b/Routes/User/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/CompanyUser/CompanyUserAuth.py b/Utils/AuthUtil.py similarity index 100% rename from CompanyUser/CompanyUserAuth.py rename to Utils/AuthUtil.py diff --git a/Utils/ObjUtil.py b/Utils/ObjUtil.py index 236b283..00b8367 100644 --- a/Utils/ObjUtil.py +++ b/Utils/ObjUtil.py @@ -8,21 +8,21 @@ class SpecObject(object): def dict_keys_toggle(self, **kwargs): """字典键值切换""" _dict_ = dict() - + default_types = ['str', 'int', 'float', 'dict', 'bool', 'tuple'] for key in self.__dict__.keys(): - if type(self.__dict__[key]).__name__ in ['str', 'int', 'float', 'dict', 'bool', 'tuple']: + if type(self.__dict__[key]).__name__ in default_types: _dict_[self.fields_map[key]] = self.__dict__[key] elif type(self.__dict__[key]).__name__ == 'list': if len(self.__dict__[key]) == 0: _dict_[self.fields_map[key]] = self.__dict__[key] - elif type(self.__dict__[key][0]).__name__ in ['str', 'int', 'float', 'dict', 'bool', 'tuple']: + elif type(self.__dict__[key][0]).__name__ in default_types: _dict_[self.fields_map[key]] = self.__dict__[key] else: - _dict_[self.fields_map[key]] = [item.dict_to_save() for item in self.__dict__[key]] + _dict_[self.fields_map[key]] = [item.dict_keys_toggle() for item in self.__dict__[key]] elif self.__dict__[key] is None: _dict_[self.fields_map[key]] = self.__dict__[key] else: - _dict_[self.fields_map[key]] = self.__dict__[key].dict_to_show() + _dict_[self.fields_map[key]] = self.__dict__[key].dict_keys_toggle() if 'columns' in kwargs: _dict_ = {key: _dict_[key] for key in kwargs['columns']} @@ -61,3 +61,13 @@ class SpecObject(object): list_.append(instance) return list_ + + @staticmethod + def get_attr(_dict_, _key_, **kwargs): + """获取字典属性值""" + value = kwargs['default'] if kwargs.__contains__('default') else None + try: + value = _dict_[_key_] + except KeyError: + pass + return value diff --git a/Utils/ValidateUtil.py b/Utils/ValidateUtil.py index 6a1749e..2cab8e9 100644 --- a/Utils/ValidateUtil.py +++ b/Utils/ValidateUtil.py @@ -21,6 +21,13 @@ class Validate(object): case = (len(param) >= 8) and (re.match(regex, param) is not None) return True if case else False + @staticmethod + def telephone(param): + """手机号格式""" + regex = "(^(13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])d{8}$)" + case = re.match(regex, param) is not None + return True if case else False + @staticmethod def date_format(param): """yyyy-mm-dd""" diff --git a/app.py b/app.py index 67a9d21..281c928 100644 --- a/app.py +++ b/app.py @@ -3,8 +3,8 @@ from flask_cors import * from Routes.Company.Index import company_route +from Routes.User.TFSECompanyUserRoute import company_user_route -from CompanyUser.CompanyUserRoute import company_user_route from file.file_routes import file_route from Rating.Credit.CreditRoutes import credit_route from Rating.Esg.EsgRoutes import esg_route diff --git a/file/file_routes.py b/file/file_routes.py index 6468ad4..bde090f 100644 --- a/file/file_routes.py +++ b/file/file_routes.py @@ -1,6 +1,6 @@ from flask import Blueprint, request, Response -from CompanyUser.CompanyUserAuth import verify_token, verify_report_view_auth +from Utils.AuthUtil import verify_token, verify_report_view_auth from file.file_obj import TfseFile file_route = Blueprint('file', __name__)