diff --git a/fir_ser/admin/views/login.py b/fir_ser/admin/views/login.py index ecc6feb..fcfd9b3 100644 --- a/fir_ser/admin/views/login.py +++ b/fir_ser/admin/views/login.py @@ -13,9 +13,9 @@ from admin.utils.utils import ApiResponse from api.utils.auth import ExpiringTokenAuthentication from api.utils.serializer import UserInfoSerializer from api.utils.storage.caches import login_auth_failed +from api.utils.sysconfig import Config from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle from api.utils.utils import get_captcha, valid_captcha, set_user_token -from fir_ser.settings import LOGIN logger = logging.getLogger(__name__) @@ -29,7 +29,7 @@ class LoginView(APIView): code = 1000 msg = 'success' data = None - if LOGIN.get("captcha"): + if Config.LOGIN.get("captcha"): is_valid = valid_captcha(receive.get("captcha_key", None), receive.get("authcode", None), username) else: is_valid = True @@ -69,7 +69,7 @@ class LoginView(APIView): def get(self, request): data = {} - if LOGIN.get("captcha"): + if Config.LOGIN.get("captcha"): data = get_captcha() return ApiResponse(data=data) diff --git a/fir_ser/admin/views/user.py b/fir_ser/admin/views/user.py index c52fbd3..5cc9890 100644 --- a/fir_ser/admin/views/user.py +++ b/fir_ser/admin/views/user.py @@ -16,8 +16,8 @@ from admin.utils.utils import AppsPageNumber, BaseModelSet, ApiResponse from api.models import UserInfo, UserCertificationInfo, ThirdWeChatUserInfo from api.utils.auth import AdminTokenAuthentication from api.utils.storage.caches import auth_user_download_times_gift +from api.utils.sysconfig import Config from common.base.baseutils import get_dict_from_filter_fields -from fir_ser.settings import AUTH_USER_GIVE_DOWNLOAD_TIMES logger = logging.getLogger(__name__) @@ -62,7 +62,7 @@ class UserInfoView(APIView): status = user_cert_obj.status UserCertificationInfo.objects.filter(user_id=user_obj).update(status=data["certification"]) if status != 1 and UserCertificationInfo.objects.filter(user_id=user_obj).first().status == 1: - auth_user_download_times_gift(user_obj, AUTH_USER_GIVE_DOWNLOAD_TIMES) + auth_user_download_times_gift(user_obj, Config.AUTH_USER_GIVE_DOWNLOAD_TIMES) data = users_serializer.data return ApiResponse(data=data) return ApiResponse(code=1004, msg='数据校验失败') @@ -97,7 +97,7 @@ class UserCertificationInfoView(APIView): if users_serializer.is_valid(): users_serializer.save() if status != 1 and users_serializer.data.get('status') == 1: - auth_user_download_times_gift(obj.user_id, AUTH_USER_GIVE_DOWNLOAD_TIMES) + auth_user_download_times_gift(obj.user_id, Config.AUTH_USER_GIVE_DOWNLOAD_TIMES) data = users_serializer.data return ApiResponse(data=data) return ApiResponse(code=1004, msg='数据校验失败') diff --git a/fir_ser/api/management/commands/expire_config_caches.py b/fir_ser/api/management/commands/expire_config_caches.py new file mode 100644 index 0000000..c24f4c3 --- /dev/null +++ b/fir_ser/api/management/commands/expire_config_caches.py @@ -0,0 +1,10 @@ +from django.core.management.base import BaseCommand + +from api.tasks import clean_config_cache + + +class Command(BaseCommand): + help = 'Expire config caches' + + def handle(self, *args, **options): + clean_config_cache() diff --git a/fir_ser/api/migrations/0032_systemconfig.py b/fir_ser/api/migrations/0032_systemconfig.py new file mode 100644 index 0000000..43b495c --- /dev/null +++ b/fir_ser/api/migrations/0032_systemconfig.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.3 on 2022-02-04 11:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0031_auto_20220204_0906'), + ] + + operations = [ + migrations.CreateModel( + name='SystemConfig', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.CharField(max_length=256, unique=True, verbose_name='配置名称')), + ('value', models.CharField(max_length=512, verbose_name='配置值')), + ('description', models.CharField(blank=True, default='', max_length=256, verbose_name='备注')), + ('updated_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ], + options={ + 'verbose_name': '系统配置项', + 'verbose_name_plural': '系统配置项', + }, + ), + ] diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index ceaa09c..cc28bc1 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -644,3 +644,17 @@ class AppleDeveloperToAppUse(models.Model): def __str__(self): return "%s-%s" % (self.app_id.name, self.developerid.issuer_id) + + +class SystemConfig(models.Model): + key = models.CharField(max_length=256, unique=True, verbose_name="配置名称") + value = models.CharField(max_length=512, verbose_name="配置值") + description = models.CharField(verbose_name="备注", max_length=256, default='', blank=True) + updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间") + + class Meta: + verbose_name = '系统配置项' + verbose_name_plural = "系统配置项" + + def __str__(self): + return "%s-%s" % (self.key, self.description) diff --git a/fir_ser/api/tasks.py b/fir_ser/api/tasks.py index 912b777..b415a60 100644 --- a/fir_ser/api/tasks.py +++ b/fir_ser/api/tasks.py @@ -17,10 +17,10 @@ from api.utils.crontab.iproxy import get_best_proxy_ips, clean_ip_proxy_infos from api.utils.geetest.geetest_utils import check_bypass_status from api.utils.mp.wechat import sync_wx_access_token from api.utils.storage.storage import get_local_storage +from api.utils.sysconfig import Config, invalid_config_cache from api.views.login import get_login_type from common.cache.state import MigrateStorageState from fir_ser.celery import app -from fir_ser.settings import LOGIN, CHANGER, REGISTER logger = logging.getLogger(__name__) @@ -83,6 +83,11 @@ def start_api_sever_do_clean(): get_local_storage(clean_cache=True) check_bypass_status() clean_ip_proxy_infos() + invalid_config_cache() + + +def clean_config_cache(): + invalid_config_cache() @app.task @@ -92,7 +97,8 @@ def sync_download_times_job(): @app.task def check_bypass_status_job(): - if LOGIN.get("geetest") or CHANGER.get('geetest') or REGISTER.get('geetest'): + if Config.LOGIN.get("geetest") or Config.CHANGER.get('geetest') or Config.REGISTER.get( + 'geetest') or Config.REPORT.get('geetest'): check_bypass_status() diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index e1d0651..62e58c4 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -26,13 +26,14 @@ from api.utils.serializer import BillAppInfoSerializer, BillDeveloperInfoSeriali from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_limit, check_app_permission, \ consume_user_download_times_by_app_obj, add_udid_cache_queue, get_and_clean_udid_cache_queue from api.utils.storage.storage import Storage +from api.utils.sysconfig import Config from api.utils.utils import delete_app_to_dev_and_file, send_ios_developer_active_status, delete_local_files, \ download_files_form_oss, get_developer_udided from common.base.baseutils import file_format_path, delete_app_profile_file, get_profile_full_path, format_apple_date, \ get_format_time, make_app_uuid, make_from_user_uuid from common.base.magic import run_function_by_locker, call_function_try_attempts from common.cache.state import CleanErrorBundleIdSignDataState -from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, MOBILE_CONFIG_SIGN_SSL, MSGTEMPLATE, DEVELOPER_USE_STATUS +from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, DEVELOPER_USE_STATUS logger = logging.getLogger(__name__) @@ -99,9 +100,9 @@ def udid_bytes_to_dict(xml_stream): def make_sign_udid_mobile_config(udid_url, short, bundle_id, app_name): - if MOBILE_CONFIG_SIGN_SSL.get("open"): - ssl_key_path = MOBILE_CONFIG_SIGN_SSL.get("ssl_key_path", None) - ssl_pem_path = MOBILE_CONFIG_SIGN_SSL.get("ssl_pem_path", None) + if Config.MOBILE_CONFIG_SIGN_SSL.get("open"): + ssl_key_path = Config.MOBILE_CONFIG_SIGN_SSL.get("ssl_key_path", None) + ssl_pem_path = Config.MOBILE_CONFIG_SIGN_SSL.get("ssl_pem_path", None) if ssl_key_path and ssl_pem_path and os.path.isfile(ssl_key_path) and os.path.isfile(ssl_pem_path): mobile_config_tmp_dir = os.path.join(SUPER_SIGN_ROOT, 'tmp', 'mobile_config') @@ -217,7 +218,7 @@ def disable_developer_and_send_email(app_obj, developer_obj): developer_obj.status = 5 developer_obj.save(update_fields=['status']) send_ios_developer_active_status(developer_obj.user_id, - MSGTEMPLATE.get('ERROR_DEVELOPER') % ( + Config.MSG_ERROR_DEVELOPER % ( developer_obj.user_id.first_name, app_obj.name, developer_obj.issuer_id)) @@ -418,7 +419,7 @@ class IosUtils(object): if self.user_obj.email: if send_msg_over_limit("get", self.user_obj.email): send_msg_over_limit("set", self.user_obj.email) - send_ios_developer_active_status(self.user_obj, MSGTEMPLATE.get('NOT_EXIST_DEVELOPER', '') + send_ios_developer_active_status(self.user_obj, Config.MSG_NOT_EXIST_DEVELOPER % ( self.user_obj.first_name, self.app_obj.name)) else: diff --git a/fir_ser/api/utils/apple/appleapiv3.py b/fir_ser/api/utils/apple/appleapiv3.py index dda1a61..959eeb5 100644 --- a/fir_ser/api/utils/apple/appleapiv3.py +++ b/fir_ser/api/utils/apple/appleapiv3.py @@ -14,9 +14,9 @@ from functools import wraps import jwt import requests -from django.conf import settings from api.utils.crontab.iproxy import get_proxy_ip_from_cache +from api.utils.sysconfig import Config logger = logging.getLogger(__name__) @@ -736,7 +736,7 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi self.p8_private_key = p8_private_key self.exp_seconds = exp_seconds self.proxies = get_proxy_ip_from_cache() - self.timeout = settings.APPLE_DEVELOPER_API_TIMEOUT if settings.APPLE_DEVELOPER_API_TIMEOUT else 120 + self.timeout = Config.APPLE_DEVELOPER_API_TIMEOUT if Config.APPLE_DEVELOPER_API_TIMEOUT else 120 self.__make_jwt_headers() DevicesAPI.__init__(self, self.BASE_URI, self.headers) BundleIDsAPI.__init__(self, self.BASE_URI, self.headers) diff --git a/fir_ser/api/utils/crontab/ctasks.py b/fir_ser/api/utils/crontab/ctasks.py index c59d6b0..11573db 100644 --- a/fir_ser/api/utils/crontab/ctasks.py +++ b/fir_ser/api/utils/crontab/ctasks.py @@ -13,9 +13,9 @@ from django.core.cache import cache from api.models import Apps, UserInfo, AppIOSDeveloperInfo from api.utils.app.supersignutils import IosUtils from api.utils.storage.storage import Storage +from api.utils.sysconfig import Config from api.utils.utils import send_ios_developer_active_status -from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE, SUPER_SIGN_ROOT, MSGTEMPLATE, \ - DEVELOPER_AUTO_CHECK_STATUS +from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE, SUPER_SIGN_ROOT, DEVELOPER_AUTO_CHECK_STATUS logger = logging.getLogger(__name__) @@ -83,5 +83,5 @@ def auto_check_ios_developer_active(): error_issuer_id[userinfo.uid] = list(set(err_issuer_id)) for uid, val in error_issuer_id.items(): userinfo = UserInfo.objects.filter(uid=uid).first() - send_ios_developer_active_status(userinfo, MSGTEMPLATE.get('AUTO_CHECK_DEVELOPER') % ( + send_ios_developer_active_status(userinfo, Config.MSG_AUTO_CHECK_DEVELOPER % ( userinfo.first_name, ",".join(val))) diff --git a/fir_ser/api/utils/crontab/iproxy.py b/fir_ser/api/utils/crontab/iproxy.py index 18d4fea..8fc9b1c 100644 --- a/fir_ser/api/utils/crontab/iproxy.py +++ b/fir_ser/api/utils/crontab/iproxy.py @@ -10,14 +10,14 @@ from concurrent.futures import ThreadPoolExecutor import requests +from api.utils.sysconfig import Config from common.cache.storage import IpProxyListCache, IpProxyActiveCache -from fir_ser.settings import APPLE_DEVELOPER_API_PROXY_LIST, APPLE_DEVELOPER_API_PROXY logger = logging.getLogger(__name__) def get_best_proxy_ips(url='https://api.appstoreconnect.apple.com/agreement'): - active_proxy_ips = [proxy_info['proxy'] for proxy_info in APPLE_DEVELOPER_API_PROXY_LIST if + active_proxy_ips = [proxy_info['proxy'] for proxy_info in Config.APPLE_DEVELOPER_API_PROXY_LIST if proxy_info.get('active')] access_ip_info = [] if not active_proxy_ips: @@ -71,7 +71,7 @@ def get_proxy_ip_from_cache(change_ip=False): 'https': proxy_ip } else: - proxy_info = APPLE_DEVELOPER_API_PROXY + proxy_info = Config.APPLE_DEVELOPER_API_PROXY logger.info(f"make ip proxy cache {proxy_info}") active_proxy_cache.set_storage_cache(proxy_info, 24 * 60 * 60) return proxy_info diff --git a/fir_ser/api/utils/geetest/geetest_utils.py b/fir_ser/api/utils/geetest/geetest_utils.py index b926897..c335be1 100644 --- a/fir_ser/api/utils/geetest/geetest_utils.py +++ b/fir_ser/api/utils/geetest/geetest_utils.py @@ -11,8 +11,7 @@ import requests from django.core.cache import cache as redis_connect from api.utils.geetest.geetest_lib import GeetestLib -from fir_ser.settings import GEETEST_ID, GEETEST_KEY, GEETEST_BYPASS_URL, \ - GEETEST_BYPASS_STATUS_KEY +from api.utils.sysconfig import Config logger = logging.getLogger(__name__) @@ -20,25 +19,25 @@ logger = logging.getLogger(__name__) # 发送bypass请求,获取bypass状态并进行缓存(如何缓存可根据自身情况合理选择,这里是使用redis进行缓存) def check_bypass_status(): response = "" - params = {"gt": GEETEST_ID} + params = {"gt": Config.GEETEST_ID} try: - response = requests.get(url=GEETEST_BYPASS_URL, params=params) + response = requests.get(url=Config.GEETEST_BYPASS_URL, params=params) except Exception as e: logger.error(f"check_bypass_status failed Exception:{e}") if response and response.status_code == 200: logger.debug(f"check_bypass_status success {response.content}") bypass_status_str = response.content.decode("utf-8") bypass_status = json.loads(bypass_status_str).get("status") - redis_connect.set(GEETEST_BYPASS_STATUS_KEY, bypass_status) + redis_connect.set(Config.GEETEST_BYPASS_STATUS_KEY, bypass_status) else: bypass_status = "fail" - redis_connect.set(GEETEST_BYPASS_STATUS_KEY, bypass_status) + redis_connect.set(Config.GEETEST_BYPASS_STATUS_KEY, bypass_status) logger.debug(f"bypass状态已经获取并存入redis,当前状态为 {bypass_status}") # 从缓存中取出当前缓存的bypass状态(success/fail) def get_bypass_cache(count=3): - bypass_status_cache = redis_connect.get(GEETEST_BYPASS_STATUS_KEY) + bypass_status_cache = redis_connect.get(Config.GEETEST_BYPASS_STATUS_KEY) if bypass_status_cache: return bypass_status_cache else: @@ -59,7 +58,7 @@ def first_register(user_id, ip_address): # client_type 客户端类型,web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生sdk植入app应用的方式;unknown:未知 # ip_address 客户端请求sdk服务器的ip地址 bypass_status = get_bypass_cache() - gt_lib = GeetestLib(GEETEST_ID, GEETEST_KEY) + gt_lib = GeetestLib(Config.GEETEST_ID, Config.GEETEST_KEY) digestmod = "md5" param_dict = {"digestmod": digestmod, "user_id": user_id, "client_type": "web", "ip_address": ip_address} if bypass_status == "success": @@ -76,7 +75,7 @@ def second_validate(rdata): validate = rdata.get(GeetestLib.GEETEST_VALIDATE, None) seccode = rdata.get(GeetestLib.GEETEST_SECCODE, None) bypass_status = get_bypass_cache() - gt_lib = GeetestLib(GEETEST_ID, GEETEST_KEY) + gt_lib = GeetestLib(Config.GEETEST_ID, Config.GEETEST_KEY) if bypass_status == "success": result = gt_lib.success_validate(challenge, validate, seccode) else: diff --git a/fir_ser/api/utils/mp/wechat.py b/fir_ser/api/utils/mp/wechat.py index c1e1971..ccdf9e1 100644 --- a/fir_ser/api/utils/mp/wechat.py +++ b/fir_ser/api/utils/mp/wechat.py @@ -10,12 +10,11 @@ from hashlib import sha1 import requests from api.utils.mp.utils import WxMsgCryptBase +from api.utils.sysconfig import Config from common.base.baseutils import get_format_time from common.cache.storage import WxTokenCache -from fir_ser.settings import THIRDLOGINCONF logger = logging.getLogger(__name__) -wx_login_info = THIRDLOGINCONF.wx_official def format_req_json(j_data, func, *args, **kwargs): @@ -151,11 +150,12 @@ class WxOfficialBase(object): @classmethod def make_wx_auth_obj(cls): - return cls(**wx_login_info.get('auth')) + return cls(**Config.THIRDLOGINCONF.get('auth')) def check_signature(params): - tmp_list = sorted([wx_login_info.get('auth', {}).get('token'), params.get("timestamp"), params.get("nonce")]) + tmp_list = sorted( + [Config.THIRDLOGINCONF.get('auth', {}).get('token'), params.get("timestamp"), params.get("nonce")]) tmp_str = "".join(tmp_list) tmp_str = sha1(tmp_str.encode("utf-8")).hexdigest() if tmp_str == params.get("signature"): @@ -165,7 +165,7 @@ def check_signature(params): class WxMsgCrypt(WxMsgCryptBase): def __init__(self): - super().__init__(**wx_login_info.get('auth')) + super().__init__(**Config.THIRDLOGINCONF.get('auth')) class WxTemplateMsg(object): diff --git a/fir_ser/api/utils/storage/caches.py b/fir_ser/api/utils/storage/caches.py index 46c2b5b..dc7a2ca 100644 --- a/fir_ser/api/utils/storage/caches.py +++ b/fir_ser/api/utils/storage/caches.py @@ -17,14 +17,14 @@ from api.models import Apps, UserInfo, AppReleaseInfo, AppUDID, APPToDeveloper, from api.utils.modelutils import get_app_d_count_by_app_id, get_app_domain_name, get_user_domain_name, \ add_remote_info_from_request from api.utils.storage.storage import Storage, LocalStorage +from api.utils.sysconfig import Config from common.base.baseutils import check_app_password, get_order_num, get_real_ip_address from common.cache.invalid import invalid_app_cache, invalid_short_cache, invalid_app_download_times_cache, \ invalid_head_img_cache from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCache, DownloadUrlCache, AppInstanceCache, \ UploadTmpFileNameCache, RedisCacheBase, UserCanDownloadCache, UserFreeDownloadTimesCache, WxTicketCache, \ SignUdidQueueCache, CloudStorageCache -from fir_ser.settings import CACHE_KEY_TEMPLATE, SERVER_DOMAIN, SYNC_CACHE_TO_DATABASE, DEFAULT_MOBILEPROVISION, \ - USER_FREE_DOWNLOAD_TIMES, AUTH_USER_FREE_DOWNLOAD_TIMES, DEVELOPER_USE_STATUS +from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE, DEVELOPER_USE_STATUS logger = logging.getLogger(__name__) @@ -39,7 +39,7 @@ def sync_download_times_by_app_id(app_ids): def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', udid=None): now = time.time() if isdownload is None: - local_storage = LocalStorage(**SERVER_DOMAIN.get("IOS_PMFILE_DOWNLOAD_DOMAIN")) + local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN) download_url_type = 'plist' if not udid: if app_obj.get('issupersign', None): @@ -68,11 +68,11 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', else: return "", "" - supersign = DEFAULT_MOBILEPROVISION.get("supersign") + supersign = Config.DEFAULT_MOBILEPROVISION.get("supersign") mobileconifg = "" if download_url_type == 'plist': - enterprise = DEFAULT_MOBILEPROVISION.get("enterprise") + enterprise = Config.DEFAULT_MOBILEPROVISION.get("enterprise") mpath = enterprise.get('path', None) murl = enterprise.get('url', None) else: @@ -314,9 +314,9 @@ def set_user_download_times_flag(user_id, act): def get_user_free_download_times(user_id, act='get', amount=1, auth_status=False): - free_download_times = USER_FREE_DOWNLOAD_TIMES + free_download_times = Config.USER_FREE_DOWNLOAD_TIMES if auth_status: - free_download_times = AUTH_USER_FREE_DOWNLOAD_TIMES + free_download_times = Config.AUTH_USER_FREE_DOWNLOAD_TIMES cache_obj = UserFreeDownloadTimesCache(user_id) user_free_download_times = cache_obj.get_storage_cache() if user_free_download_times is not None: @@ -401,7 +401,7 @@ def user_auth_success(user_id): :return: """ get_user_free_download_times(user_id, 'get') - get_user_free_download_times(user_id, 'set', USER_FREE_DOWNLOAD_TIMES - AUTH_USER_FREE_DOWNLOAD_TIMES) + get_user_free_download_times(user_id, 'set', Config.USER_FREE_DOWNLOAD_TIMES - Config.AUTH_USER_FREE_DOWNLOAD_TIMES) return enable_user_download(user_id) diff --git a/fir_ser/api/utils/sysconfig.py b/fir_ser/api/utils/sysconfig.py new file mode 100644 index 0000000..b949809 --- /dev/null +++ b/fir_ser/api/utils/sysconfig.py @@ -0,0 +1,341 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# project: 2月 +# author: liuyu +# date: 2022/2/4 + +import json +import logging + +from rest_framework import serializers + +from api.models import SystemConfig +from common.cache.storage import SystemConfigCache +from config import BASECONF, API_DOMAIN, MOBILEPROVISION, WEB_DOMAIN + +logger = logging.getLogger(__name__) + + +class SystemConfigSerializer(serializers.ModelSerializer): + class Meta: + model = SystemConfig + fields = "__all__" + + +def invalid_config_cache(): + SystemConfigCache('*').del_many() + + +# def make_json_value(value, default): +# try: +# if isinstance(value, str): +# value = json.loads(value) +# if isinstance(value, dict): +# return value +# except Exception as e: +# logger.warning(f"sysconfig make json value failed {value} Exception:{e}") +# return default + + +class ConfigCacheBase(object): + def __init__(self, px=''): + self.px = px + + def get_value_from_db(self, key): + sys_obj = SystemConfig.objects.filter(key=key).first() + return SystemConfigSerializer(sys_obj).data + + def get_value(self, key, data=None): + if data is None: + data = {} + cache = SystemConfigCache(key) + cache_data = cache.get_storage_cache() + if cache_data is not None and cache_data.get('key', '') == key: + return cache_data.get('value') + db_data = self.get_value_from_db(key) + d_key = db_data.get('key', '') + if d_key != key and data is not None: + db_data['value'] = data + db_data['key'] = key + cache.set_storage_cache(db_data, timeout=0) + return db_data.get('value') + + def set_value(self, key, value): + if not isinstance(value, str): + value = json.dumps(value) + SystemConfig.objects.update_or_create(key=key, defaults={'value': value}) + SystemConfigCache(key).del_storage_cache() + + def __getattribute__(self, name): + try: + return object.__getattribute__(self, name) + except Exception as e: + logger.error(f"__getattribute__ Error {e} {name}") + return self.get_value(name) + + @property + def MOBILEPROVISION(self): + return self.get_value('MOBILEPROVISION') if self.get_value('MOBILEPROVISION') else MOBILEPROVISION + + @property + def API_DOMAIN(self): + return self.get_value('API_DOMAIN') if self.get_value('API_DOMAIN') else API_DOMAIN + + @property + def WEB_DOMAIN(self): + return self.get_value('WEB_DOMAIN') if self.get_value('WEB_DOMAIN') else WEB_DOMAIN + + @property + def POST_UDID_DOMAIN(self): + return self.get_value('POST_UDID_DOMAIN') if self.get_value('POST_UDID_DOMAIN') else self.API_DOMAIN + + @property + def FILE_UPLOAD_DOMAIN(self): + return self.get_value('FILE_UPLOAD_DOMAIN') if self.get_value('FILE_UPLOAD_DOMAIN') else self.API_DOMAIN + + +class BaseConfCache(ConfigCacheBase): + def __init__(self): + super(BaseConfCache, self).__init__() + + @property + def IOS_PMFILE_DOWNLOAD_DOMAIN(self): + # 验证码,ios 描述文件和plist文件下载域名,该域名用于后端,一般为api访问域名 + return { + "domain_name": self.API_DOMAIN.split("://")[1], + 'is_https': True if self.API_DOMAIN.split("://")[0] == "https" else False, + } + + @property + def DEFAULT_THROTTLE_RATES(self): + """ + 暂时无用 + :return: + """ + return super().get_value('DEFAULT_THROTTLE_RATES', BASECONF.DEFAULT_THROTTLE_RATES) + + +class IpaConfCache(ConfigCacheBase): + def __init__(self): + super(IpaConfCache, self).__init__() + + @property + def MOBILE_CONFIG_SIGN_SSL(self): + return super().get_value('MOBILE_CONFIG_SIGN_SSL', { + # 描述文件是否签名,默认是关闭状态;如果开启,并且ssl_key_path 和 ssl_pem_path 正常,则使用填写的ssl进行签名,否则默认不签名 + 'open': True, + 'ssl_key_path': '/data/cert/%s.key' % self.API_DOMAIN.split("://")[1], + 'ssl_pem_path': '/data/cert/%s.pem' % self.API_DOMAIN.split("://")[1] + }) + + @property + def DEFAULT_MOBILEPROVISION(self): + return super().get_value('DEFAULT_MOBILEPROVISION', { + # 默认描述文件路径或者下载路径,用户企业签名或者超级签名 跳转 [设置 - 通用 - 描述文件|设备管理] 页面 + # 如果配置了path路径,则走路径,如果配置了url,则走URL,path 优先级大于url优先级 + 'enterprise': { + 'url': self.MOBILEPROVISION, + # 'path': os.path.join(BASE_DIR,'files', 'embedded.mobileprovision'), + }, + 'supersign': { + # 超级签名,如果self 为True,则默认用自己的描述文件,否则同企业配置顺序一致,自己的配置文件有时候有问题 + 'self': False, + 'url': self.MOBILEPROVISION, + # 'path': os.path.join(BASE_DIR,'files', 'embedded.mobileprovision'), + } + }) + + @property + def APPLE_DEVELOPER_API_PROXY(self): + return super().get_value('APPLE_DEVELOPER_API_PROXY', { + # 代理的作用,主要是为了加快苹果api的访问,在国内会出现卡死,访问超时等问题,怀疑是被苹果服务器拦截了 + # 'http': '47.243.172.202:17897', + # 'https': '47.243.172.202:17897' + }) + + @property + def APPLE_DEVELOPER_API_PROXY_LIST(self): + return super().get_value('APPLE_DEVELOPER_API_PROXY_LIST', [ + # '47.243.172.201:17897', + # '47.243.172.202:17897', + # '47.243.172.203:17897' + ]) + + @property + def APPLE_DEVELOPER_API_TIMEOUT(self): + """ + 访问苹果api超时时间,默认2分钟 + :return: + """ + value = super().get_value('APPLE_DEVELOPER_API_TIMEOUT') + return value if value is not None else 2 * 60 + + +class WechatConfCache(ConfigCacheBase): + def __init__(self): + super(WechatConfCache, self).__init__() + + @property + def THIRDLOGINCONF(self): + return super().get_value('THIRDLOGINCONF', { + 'name': 'wx_official', + 'auth': { + 'app_id': 'we6', + 'app_secret': '5bfb678', + 'token': 'f0ae1b879b8', + 'encoding_aes_key': '7b9URovp83gG', + }, + 'active': True + }) + + +class AuthConfCache(WechatConfCache): + def __init__(self): + super(AuthConfCache, self).__init__() + + @property + def REGISTER(self): + """ + 注册方式,如果启用sms或者email 需要配置 THIRD_PART_CONFIG_KEY_INFO.sender 信息 + :return: + """ + return super().get_value('REGISTER', { + "enable": True, + "captcha": False, # 是否开启注册字母验证码 + "geetest": True, # 是否开启geetest验证,如要开启请先配置geetest + "register_type": { + 'sms': True, # 短信注册 + 'email': True, # 邮件注册 + 'code': False, # 邀请码注册,邀请码必填写,需要和短信,邮件一起使用 + } + }) + + @property + def CHANGER(self): + return super().get_value('CHANGER', { + "enable": True, + "captcha": False, # 是否开启注册字母验证码 + "geetest": True, # 是否开启geetest验证,如要开启请先配置geetest + "change_type": { + 'sms': True, # 短信注册 + 'email': True, # 邮件注册 + 'code': False, # 邀请码注册,邀请码必填写,需要和短信,邮件一起使用 + } + }) + + @property + def LOGIN(self): + return super().get_value('LOGIN', { + "captcha": False, # 是否开启登录字母验证码 + "geetest": True, # 是否开启geetest验证 + "login_type": { + 'sms': True, # 短信登录 + 'email': True, # 邮件登录 + 'up': False, # 密码登录 + 'third': { + 'wxp': self.THIRDLOGINCONF.get('active') # 微信公众号登录,需要在 THIRDLOGINCONF 配置好微信公众号登录 + }, + } + }) + + @property + def REPORT(self): + return super().get_value('REPORT', { + "enable": True, + "captcha": True, # 是否开启注册字母验证码 + "geetest": False, # 是否开启geetest验证,如要开启请先配置geetest + "report_type": { + 'sms': False, # 短信举报 + 'email': True, # 邮件举报 + } + }) + + +class GeeTestConfCache(ConfigCacheBase): + def __init__(self): + super(GeeTestConfCache, self).__init__() + + @property + def GEETEST_ID(self): + value = super().get_value('GEETEST_ID') + return value if value else BASECONF.GEETEST_ID + + @property + def GEETEST_KEY(self): + value = super().get_value('GEETEST_KEY') + return value if value else BASECONF.GEETEST_KEY + + @property + def GEETEST_CYCLE_TIME(self): + """ + 定时任务初始化,该数值无效,需要在配置中定义 + :return: + """ + value = super().get_value('GEETEST_CYCLE_TIME') + return value if value else BASECONF.GEETEST_CYCLE_TIME + + @property + def GEETEST_BYPASS_STATUS_KEY(self): + value = super().get_value('GEETEST_BYPASS_STATUS_KEY') + return value if value else BASECONF.GEETEST_BYPASS_STATUS_KEY + + @property + def GEETEST_BYPASS_URL(self): + value = super().get_value('GEETEST_BYPASS_URL') + return value if value else BASECONF.GEETEST_BYPASS_URL + + +class UserDownloadTimesCache(ConfigCacheBase): + def __init__(self): + super(UserDownloadTimesCache, self).__init__() + + @property + def USER_FREE_DOWNLOAD_TIMES(self): + value = super().get_value('USER_FREE_DOWNLOAD_TIMES') + return value if value else 5 + + @property + def AUTH_USER_FREE_DOWNLOAD_TIMES(self): + value = super().get_value('AUTH_USER_FREE_DOWNLOAD_TIMES') + return value if value else 10 + + @property + def NEW_USER_GIVE_DOWNLOAD_TIMES(self): + value = super().get_value('NEW_USER_GIVE_DOWNLOAD_TIMES') + return value if value else 100 + + @property + def AUTH_USER_GIVE_DOWNLOAD_TIMES(self): + value = super().get_value('AUTH_USER_GIVE_DOWNLOAD_TIMES') + return value if value else 200 + + +class EmailMsgCache(ConfigCacheBase): + def __init__(self): + super(EmailMsgCache, self).__init__() + + @property + def MSG_NOT_EXIST_DEVELOPER(self): + value = super().get_value('MSG_NOT_EXIST_DEVELOPER') + tem = '用户 %s 你好,应用 %s 签名失败了,苹果开发者总设备量已经超限,请添加新的苹果开发者或者修改开发者设备数量。感谢有你!' + return value if value else tem + + @property + def MSG_ERROR_DEVELOPER(self): + value = super().get_value('MSG_ERROR_DEVELOPER') + tem = '用户 %s 你好,应用 %s 签名失败了,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!' + return value if value else tem + + @property + def MSG_AUTO_CHECK_DEVELOPER(self): + value = super().get_value('MSG_AUTO_CHECK_DEVELOPER') + tem = '用户 %s 你好,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!' + return value if value else tem + + +class ConfigCache(BaseConfCache, IpaConfCache, AuthConfCache, EmailMsgCache, UserDownloadTimesCache, GeeTestConfCache): + def __init__(self): + super(ConfigCache, self).__init__() + + +Config = ConfigCache() diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py index 796fc45..741e5a7 100644 --- a/fir_ser/api/utils/utils.py +++ b/fir_ser/api/utils/utils.py @@ -21,9 +21,10 @@ from api.utils.sendmsg.sendmsg import SendMessage from api.utils.storage.caches import consume_user_download_times from api.utils.storage.localApi import LocalStorage from api.utils.storage.storage import Storage +from api.utils.sysconfig import Config from common.base.baseutils import get_real_ip_address from common.cache.storage import UserTokenCache, TempCache -from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT, DEVELOPER_USE_STATUS +from fir_ser.settings import CAPTCHA_LENGTH, MEDIA_ROOT, DEVELOPER_USE_STATUS logger = logging.getLogger(__name__) @@ -88,7 +89,7 @@ def get_captcha(): captcha_key = CaptchaStore.generate_key() captcha_image = captcha_image_url(captcha_key) CaptchaStore.remove_expired() - local_storage = LocalStorage(**SERVER_DOMAIN.get("IOS_PMFILE_DOWNLOAD_DOMAIN")) + local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN) return {"captcha_image": "/".join([local_storage.get_base_url(), captcha_image.strip("/"), '']), "captcha_key": captcha_key, "length": CAPTCHA_LENGTH} diff --git a/fir_ser/api/views/download.py b/fir_ser/api/views/download.py index ac5fe0a..4fca06e 100644 --- a/fir_ser/api/views/download.py +++ b/fir_ser/api/views/download.py @@ -22,9 +22,10 @@ from api.utils.response import BaseResponse from api.utils.serializer import AppsShortSerializer, AppAdInfoSerializer from api.utils.storage.caches import check_app_permission, get_app_download_url from api.utils.storage.storage import Storage, get_local_storage +from api.utils.sysconfig import Config from api.utils.throttle import VisitShortThrottle, InstallShortThrottle, InstallThrottle1, InstallThrottle2 from common.base.baseutils import get_profile_full_path, make_random_uuid, get_origin_domain_name, \ - format_get_uri, get_post_udid_url + format_get_uri, get_server_domain_from_request from fir_ser import settings logger = logging.getLogger(__name__) @@ -41,6 +42,12 @@ def mobileprovision_file_response(file_path): "application/x-apple-aspen-config") +def get_post_udid_url(request, short): + server_domain = get_server_domain_from_request(request, Config.POST_UDID_DOMAIN) + path_info_lists = [server_domain, "udid", short] + return "/".join(path_info_lists) + + class DownloadView(APIView): """ 文件下载接口,适用于本地存储和所有plist文件下载 @@ -100,7 +107,7 @@ class DownloadView(APIView): app_super_obj = APPSuperSignUsedInfo.objects.last() if not app_super_obj: - file_path = settings.DEFAULT_MOBILEPROVISION.get("supersign").get('path') + file_path = Config.DEFAULT_MOBILEPROVISION.get("supersign").get('path') if file_path and os.path.isfile(file_path): return mobileprovision_file_response(file_path) else: @@ -109,7 +116,7 @@ class DownloadView(APIView): if os.path.isfile(file_path): return mobileprovision_file_response(file_path) else: - file_path = settings.DEFAULT_MOBILEPROVISION.get("supersign").get('path') + file_path = Config.DEFAULT_MOBILEPROVISION.get("supersign").get('path') if file_path and os.path.isfile(file_path): return mobileprovision_file_response(file_path) @@ -117,7 +124,7 @@ class DownloadView(APIView): elif f_type == 'dmobileprovision': # 企业签名安装信任跳转 release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() if release_obj: - file_path = settings.DEFAULT_MOBILEPROVISION.get("enterprise").get('path') + file_path = Config.DEFAULT_MOBILEPROVISION.get("enterprise").get('path') if file_path and os.path.isfile(file_path): return mobileprovision_file_response(file_path) res.msg = "d_mobile_provision release_id error" diff --git a/fir_ser/api/views/login.py b/fir_ser/api/views/login.py index 4f466e3..ccee80a 100644 --- a/fir_ser/api/views/login.py +++ b/fir_ser/api/views/login.py @@ -13,22 +13,22 @@ from api.utils.response import BaseResponse from api.utils.serializer import UserInfoSerializer, CertificationSerializer, UserCertificationSerializer from api.utils.storage.caches import login_auth_failed, set_wx_ticket_login_info_cache, get_wx_ticket_login_info_cache, \ new_user_download_times_gift +from api.utils.sysconfig import Config from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle, GetAuthC1Throttle, GetAuthC2Throttle from api.utils.utils import get_captcha, valid_captcha, \ get_sender_sms_token, is_valid_sender_code, get_sender_email_token, get_random_username, \ check_username_exists, set_user_token, clean_user_token_and_cache from common.base.baseutils import is_valid_phone, is_valid_email, get_real_ip_address -from fir_ser.settings import LOGIN, CHANGER, REPORT, NEW_USER_GIVE_DOWNLOAD_TIMES, REGISTER logger = logging.getLogger(__name__) def get_login_type(): - return LOGIN.get("login_type") + return Config.LOGIN.get("login_type") def get_register_type(): - return REGISTER.get("register_type") + return Config.REGISTER.get("register_type") def reset_user_pwd(user, sure_password, old_password=''): @@ -251,12 +251,12 @@ class LoginView(APIView): response = BaseResponse() receive = request.data username = receive.get("username", None) - if LOGIN.get("captcha"): + if Config.LOGIN.get("captcha"): is_valid = valid_captcha(receive.get("captcha_key", None), receive.get("authcode", None), username) else: is_valid = True if is_valid: - if LOGIN.get("geetest"): + if Config.LOGIN.get("geetest"): geetest = receive.get("geetest", None) if geetest and second_validate(geetest).get("result", "") == "success": pass @@ -359,12 +359,12 @@ class LoginView(APIView): def get(self, request): response = BaseResponse() response.data = {} - if LOGIN.get("captcha"): + if Config.LOGIN.get("captcha"): response.data = get_captcha() - if LOGIN.get("geetest"): + if Config.LOGIN.get("geetest"): response.data['geetest'] = True response.data['login_type'] = get_login_type() - allow_f = REGISTER.get("enable") + allow_f = Config.REGISTER.get("enable") response.data['register_enable'] = allow_f return Response(response.dict) @@ -404,7 +404,7 @@ class RegistView(APIView): response.msg = "不允许该类型注册" return Response(response.dict) - if REGISTER.get("geetest"): + if Config.REGISTER.get("geetest"): geetest = request.data.get("geetest", None) if geetest and second_validate(geetest).get("result", "") == "success": pass @@ -437,7 +437,7 @@ class RegistView(APIView): response.code = 1000 if user_obj: try: - new_user_download_times_gift(user_obj, NEW_USER_GIVE_DOWNLOAD_TIMES) + new_user_download_times_gift(user_obj, Config.NEW_USER_GIVE_DOWNLOAD_TIMES) except Exception as e: logger.error(f"用户{user_obj}赠送下载次数失败{e}") response.msg = "注册成功" @@ -458,11 +458,11 @@ class RegistView(APIView): def get(self, request): response = BaseResponse() response.data = {} - allow_f = REGISTER.get("enable") + allow_f = Config.REGISTER.get("enable") if allow_f: - if REGISTER.get("captcha"): + if Config.REGISTER.get("captcha"): response.data = get_captcha() - if REGISTER.get("geetest"): + if Config.REGISTER.get("geetest"): response.data['geetest'] = True response.data['register_type'] = get_register_type() response.data['enable'] = allow_f @@ -510,7 +510,7 @@ class UserInfoView(APIView): mobile = data.get("mobile", None) email = data.get("email", None) if mobile or email: - if CHANGER.get('captcha'): + if Config.CHANGER.get('captcha'): is_valid = valid_captcha(data.get("captcha_key", None), data.get("authcode", None), request) if not is_valid: res.code = 1008 @@ -620,9 +620,9 @@ class AuthorizationView(APIView): res.msg = "邀请码已失效" return Response(res.dict) if ext and ext.get('report'): - p_data = REPORT + p_data = Config.REPORT else: - p_data = REGISTER + p_data = Config.REGISTER if p_data.get("captcha"): is_valid = valid_captcha(ext.get("captcha_key", None), ext.get("authcode", None), target) @@ -666,7 +666,7 @@ class ChangeAuthorizationView(APIView): target = request.data.get("target", None) ext = request.data.get("ext", None) f_type = request.data.get("ftype", None) - if REGISTER.get("captcha"): + if Config.REGISTER.get("captcha"): if ext and valid_captcha(ext.get("captcha_key", None), ext.get("authcode", None), target): pass else: @@ -674,7 +674,7 @@ class ChangeAuthorizationView(APIView): res.msg = "图片验证码有误" return Response(res.dict) - if REGISTER.get("geetest"): + if Config.REGISTER.get("geetest"): geetest = request.data.get("geetest", None) if geetest and second_validate(geetest).get("result", "") == "success": pass @@ -754,7 +754,7 @@ class CertificationView(APIView): return Response(res.dict) try: - if CHANGER.get("captcha"): + if Config.CHANGER.get("captcha"): if data and valid_captcha(data.get("captcha_key", None), data.get("authcode", None), data.get("mobile")): del data["captcha_key"] @@ -763,7 +763,7 @@ class CertificationView(APIView): res.code = 1009 res.msg = "图片验证码有误" return Response(res.dict) - if CHANGER.get('change_type').get('sms'): + if Config.CHANGER.get('change_type').get('sms'): is_valid, target = is_valid_sender_code('sms', data.get("auth_token", None), data.get("auth_key", None)) if is_valid and str(target) == str(data.get("mobile")): if login_auth_failed("get", str(data.get("mobile"))): @@ -807,13 +807,13 @@ class ChangeInfoView(APIView): def get(self, request): response = BaseResponse() response.data = {} - allow_f = CHANGER.get("enable") + allow_f = Config.CHANGER.get("enable") if allow_f: - if CHANGER.get("captcha"): + if Config.CHANGER.get("captcha"): response.data = get_captcha() - if CHANGER.get("geetest"): + if Config.CHANGER.get("geetest"): response.data['geetest'] = True - response.data['change_type'] = CHANGER.get("change_type") + response.data['change_type'] = Config.CHANGER.get("change_type") response.data['enable'] = allow_f return Response(response.dict) diff --git a/fir_ser/api/views/receiveudids.py b/fir_ser/api/views/receiveudids.py index 12144cb..ec5b62a 100644 --- a/fir_ser/api/views/receiveudids.py +++ b/fir_ser/api/views/receiveudids.py @@ -18,8 +18,9 @@ from api.utils.modelutils import get_redirect_server_domain, add_remote_info_fro get_app_download_uri from api.utils.response import BaseResponse from api.utils.storage.caches import check_app_permission +from api.utils.sysconfig import Config from api.utils.throttle import ReceiveUdidThrottle1, ReceiveUdidThrottle2 -from common.base.baseutils import get_real_ip_address, get_http_server_domain, make_random_uuid +from common.base.baseutils import get_real_ip_address, make_random_uuid, get_server_domain_from_request from fir_ser.celery import app logger = logging.getLogger(__name__) @@ -107,7 +108,7 @@ class ShowUdidView(View): udid = request.GET.get("udid") if udid: return HttpResponse("udid: %s" % udid) - server_domain = get_http_server_domain(request) + server_domain = get_server_domain_from_request(request, Config.POST_UDID_DOMAIN) path_info_lists = [server_domain, "show_udid"] udid_url = "/".join(path_info_lists) ios_udid_mobile_config = make_sign_udid_mobile_config(udid_url, 'show_udid_info', 'flyapps.cn', '查询设备udid') @@ -120,6 +121,6 @@ class ShowUdidView(View): stream_f = str(request.body) format_udid_info = udid_bytes_to_dict(stream_f) logger.info(f"show_udid receive new udid {format_udid_info}") - server_domain = get_http_server_domain(request) + server_domain = get_server_domain_from_request(request, Config.POST_UDID_DOMAIN) return HttpResponsePermanentRedirect( "%s/show_udid?udid=%s" % (server_domain, format_udid_info.get("udid"))) diff --git a/fir_ser/api/views/report.py b/fir_ser/api/views/report.py index 512ea83..73cbd34 100644 --- a/fir_ser/api/views/report.py +++ b/fir_ser/api/views/report.py @@ -13,10 +13,10 @@ from api.utils.modelutils import add_remote_info_from_request from api.utils.response import BaseResponse from api.utils.serializer import AppReportSerializer from api.utils.storage.caches import login_auth_failed +from api.utils.sysconfig import Config from api.utils.throttle import InstallThrottle2 from api.utils.utils import is_valid_sender_code, get_captcha from common.base.baseutils import get_real_ip_address, get_choices_dict -from fir_ser.settings import REPORT logger = logging.getLogger(__name__) @@ -27,13 +27,13 @@ class ReportView(APIView): def get(self, request): response = BaseResponse() response.data = {} - allow_f = REPORT.get("enable") + allow_f = Config.REPORT.get("enable") if allow_f: - if REPORT.get("captcha"): + if Config.REPORT.get("captcha"): response.data = get_captcha() - if REPORT.get("geetest"): + if Config.REPORT.get("geetest"): response.data['geetest'] = True - response.data['report_type'] = REPORT.get("report_type") + response.data['report_type'] = Config.REPORT.get("report_type") response.data['s_list'] = get_choices_dict(AppReportInfo.report_type_choices) response.data['enable'] = allow_f return Response(response.dict) diff --git a/fir_ser/api/views/uploads.py b/fir_ser/api/views/uploads.py index 1760246..5d0dfd0 100644 --- a/fir_ser/api/views/uploads.py +++ b/fir_ser/api/views/uploads.py @@ -19,6 +19,7 @@ from api.utils.modelutils import check_super_sign_permission, get_app_download_u from api.utils.response import BaseResponse from api.utils.storage.caches import upload_file_tmp_name, del_cache_response_by_short from api.utils.storage.storage import Storage +from api.utils.sysconfig import Config from common.base.baseutils import make_app_uuid, make_from_user_uuid from common.cache.state import MigrateStorageState from fir_ser import settings @@ -92,7 +93,7 @@ class AppAnalyseView(APIView): "enable_sign": enable_sign } if storage_type not in [1, 2]: - res.data['domain_name'] = settings.SERVER_DOMAIN.get("FILE_UPLOAD_DOMAIN", None) + res.data['domain_name'] = Config.FILE_UPLOAD_DOMAIN else: res.code = 1003 @@ -202,7 +203,7 @@ class UploadView(APIView): upload_token = storage.get_upload_token(upload_key) storage_type = storage.get_storage_type() res.data = { - "domain_name": settings.SERVER_DOMAIN.get("FILE_UPLOAD_DOMAIN", None), + "domain_name": Config.FILE_UPLOAD_DOMAIN, "upload_token": upload_token, "upload_key": upload_key, "storage": storage_type, diff --git a/fir_ser/common/base/baseutils.py b/fir_ser/common/base/baseutils.py index af33d5b..8eb1a51 100644 --- a/fir_ser/common/base/baseutils.py +++ b/fir_ser/common/base/baseutils.py @@ -21,7 +21,7 @@ from django.core.validators import validate_email from django.utils import timezone from dns.resolver import Resolver -from fir_ser.settings import SUPER_SIGN_ROOT, SERVER_DOMAIN +from fir_ser.settings import SUPER_SIGN_ROOT logger = logging.getLogger(__name__) @@ -250,17 +250,6 @@ def get_server_domain_from_request(request, server_domain): return server_domain -def get_http_server_domain(request): - server_domain = SERVER_DOMAIN.get('POST_UDID_DOMAIN', None) - return get_server_domain_from_request(request, server_domain) - - -def get_post_udid_url(request, short): - server_domain = get_http_server_domain(request) - path_info_lists = [server_domain, "udid", short] - return "/".join(path_info_lists) - - def format_apple_date(s_date): try: f_date = datetime.datetime.strptime(s_date, '%Y-%m-%dT%H:%M:%S.000+0000') diff --git a/fir_ser/common/cache/storage.py b/fir_ser/common/cache/storage.py index dea27c6..89fd922 100644 --- a/fir_ser/common/cache/storage.py +++ b/fir_ser/common/cache/storage.py @@ -203,3 +203,9 @@ class SignUdidQueueCache(RedisCacheBase): def __init__(self, prefix_key): self.cache_key = f"{CACHE_KEY_TEMPLATE.get('ipa_sign_udid_queue_key')}_{prefix_key}" super().__init__(self.cache_key) + + +class SystemConfigCache(RedisCacheBase): + def __init__(self, prefix_key): + self.cache_key = f"{CACHE_KEY_TEMPLATE.get('sysconfig_key')}_{prefix_key}" + super().__init__(self.cache_key) diff --git a/fir_ser/config.py b/fir_ser/config.py index 423e439..165c26e 100644 --- a/fir_ser/config.py +++ b/fir_ser/config.py @@ -31,15 +31,6 @@ class BASECONF(object): CELERY_FLOWER_PORT = 5566 CELERY_FLOWER_HOST = '127.0.0.1' - SERVER_DOMAIN = { - 'IOS_PMFILE_DOWNLOAD_DOMAIN': { - "domain_name": API_DOMAIN.split("://")[1], - 'is_https': True if API_DOMAIN.split("://")[0] == "https" else False, - }, # 验证码,ios 描述文件和plist文件下载域名,该域名用于后端,一般为api访问域名 - 'POST_UDID_DOMAIN': API_DOMAIN, # 超级签名 安装签名时 向该域名 发送udid数据,该域名用于后端,一般为 api 访问域名 - 'FILE_UPLOAD_DOMAIN': API_DOMAIN, # 本地文件上传域名,使用本地存储必须配置 - } - # geetest 配置信息 GEETEST_ID = "d3f3cf73200a70bd3a0c32ea22e5003a" GEETEST_KEY = "6f4ab6185c230a4b1f8430f28ebe4804" @@ -77,66 +68,6 @@ class CACHECONF(object): password = '' -# 微信公众号登录配置 -class THIRDLOGINCONF(object): - wx_official = { - 'name': 'wx_official', - 'auth': { - 'app_id': 'we6', - 'app_secret': '5bfb678', - 'token': 'f0ae1b879b8', - 'encoding_aes_key': '7b9URovp83gG', - }, - 'active': True - } - - -class AUTHCONF(object): - # 注册方式,如果启用sms或者email 需要配置 THIRD_PART_CONFIG_KEY_INFO.sender 信息 - REGISTER = { - "enable": True, - "captcha": False, # 是否开启注册字母验证码 - "geetest": True, # 是否开启geetest验证,如要开启请先配置geetest - "register_type": { - 'sms': True, # 短信注册 - 'email': True, # 邮件注册 - 'code': False, # 邀请码注册,邀请码必填写,需要和短信,邮件一起使用 - } - } - # 个人资料修改修改也会使用该配置 - CHANGER = { - "enable": True, - "captcha": False, # 是否开启注册字母验证码 - "geetest": True, # 是否开启geetest验证,如要开启请先配置geetest - "change_type": { - 'sms': True, # 短信注册 - 'email': True, # 邮件注册 - 'code': False, # 邀请码注册,邀请码必填写,需要和短信,邮件一起使用 - } - } - LOGIN = { - "captcha": False, # 是否开启登录字母验证码 - "geetest": True, # 是否开启geetest验证 - "login_type": { - 'sms': True, # 短信登录 - 'email': True, # 邮件登录 - 'up': False, # 密码登录 - 'third': { - 'wxp': THIRDLOGINCONF.wx_official.get('active') # 微信公众号登录,需要在 THIRDLOGINCONF 配置好微信公众号登录 - }, - } - } - REPORT = { - "enable": True, - "captcha": True, # 是否开启注册字母验证码 - "geetest": False, # 是否开启geetest验证,如要开启请先配置geetest - "report_type": { - 'sms': False, # 短信举报 - 'email': True, # 邮件举报 - } - } - - class STORAGEKEYCONF(object): STORAGE = [ { @@ -245,34 +176,6 @@ class SENDERCONF(object): ] -class IPACONF(object): - APPLE_DEVELOPER_API_PROXY_LIST = [] - APPLE_DEVELOPER_API_PROXY = { - # 代理的作用,主要是为了加快苹果api的访问,在国内会出现卡死,访问超时等问题,怀疑是被苹果服务器拦截了 - } - APPLE_DEVELOPER_API_TIMEOUT = 120 # 访问苹果api超时时间,默认3分钟 - MOBILE_CONFIG_SIGN_SSL = { - # 描述文件是否签名,默认是关闭状态;如果开启,并且ssl_key_path 和 ssl_pem_path 正常,则使用填写的ssl进行签名,否则默认不签名 - 'open': True, - 'ssl_key_path': '/data/cert/%s.key' % API_DOMAIN.split("://")[1], - 'ssl_pem_path': '/data/cert/%s.pem' % API_DOMAIN.split("://")[1] - } - DEFAULT_MOBILEPROVISION = { - # 默认描述文件路径或者下载路径,用户企业签名或者超级签名 跳转 [设置 - 通用 - 描述文件|设备管理] 页面 - # 如果配置了path路径,则走路径,如果配置了url,则走URL,path 优先级大于url优先级 - 'enterprise': { - 'url': MOBILEPROVISION, - # 'path': os.path.join(BASE_DIR,'files', 'embedded.mobileprovision'), - }, - 'supersign': { - # 超级签名,如果self 为True,则默认用自己的描述文件,否则同企业配置顺序一致,自己的配置文件有时候有问题 - 'self': False, - 'url': MOBILEPROVISION, - # 'path': os.path.join(BASE_DIR,'files', 'embedded.mobileprovision'), - } - } - - class PAYCONF(object): PAY_SUCCESS_URL = '%s/user/orders' % WEB_DOMAIN # 前端页面,支付成功跳转页面 PAY_CONFIG_KEY_INFO = [ diff --git a/fir_ser/fir_ser/settings.py b/fir_ser/fir_ser/settings.py index 593ba9b..4d7d6c0 100644 --- a/fir_ser/fir_ser/settings.py +++ b/fir_ser/fir_ser/settings.py @@ -141,7 +141,7 @@ AUTH_PASSWORD_VALIDATORS = [ REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', - 'rest_framework.renderers.BrowsableAPIRenderer', + # 'rest_framework.renderers.BrowsableAPIRenderer', ), 'DEFAULT_THROTTLE_CLASSES': [ 'api.utils.throttle.LoginUserThrottle', @@ -236,25 +236,13 @@ CORS_ALLOW_HEADERS = ( "x-token" ) -# geetest 配置信息 -GEETEST_ID = BASECONF.GEETEST_ID -GEETEST_KEY = BASECONF.GEETEST_KEY -GEETEST_CYCLE_TIME = BASECONF.GEETEST_CYCLE_TIME -GEETEST_BYPASS_STATUS_KEY = BASECONF.GEETEST_BYPASS_STATUS_KEY -GEETEST_BYPASS_URL = BASECONF.GEETEST_BYPASS_URL - -# 注册方式,如果启用sms或者email 需要配置 THIRD_PART_CONFIG_KEY_INFO.sender 信息 -REGISTER = AUTHCONF.REGISTER -# 个人资料修改修改也会使用该配置 -CHANGER = AUTHCONF.CHANGER -LOGIN = AUTHCONF.LOGIN -REPORT = AUTHCONF.REPORT THIRD_PART_CONFIG_KEY_INFO = { # APP存储配置 'storage_key': STORAGEKEYCONF.STORAGE, 'sender_key': SENDERCONF.SENDER } CACHE_KEY_TEMPLATE = { + 'sysconfig_key': 'sysconfig', 'user_can_download_key': 'user_can_download', 'download_times_key': 'app_download_times', 'make_token_key': 'make_token', @@ -281,10 +269,6 @@ CACHE_KEY_TEMPLATE = { DATA_DOWNLOAD_KEY = "d_token" FILE_UPLOAD_TMP_KEY = ".tmp" DEVELOPER_UID_KEY = "T:" -USER_FREE_DOWNLOAD_TIMES = 5 -AUTH_USER_FREE_DOWNLOAD_TIMES = 10 -NEW_USER_GIVE_DOWNLOAD_TIMES = 100 -AUTH_USER_GIVE_DOWNLOAD_TIMES = 200 # (-1, '疑似被封'), (0, '未激活'), (1, '已激活'), (2, '协议待同意'), (3, '维护中'), (4, '证书过期'), (5, '状态异常') DEVELOPER_USE_STATUS = [1, 2, 3, 4, 5] # 开发者可用状态,详情查看 model.AppIOSDeveloperInfo @@ -304,32 +288,6 @@ SYNC_CACHE_TO_DATABASE = { 'auto_check_ios_developer_active_times': 60 * 60 * 12, # ios开发者证书检测时间 } -SERVER_DOMAIN = BASECONF.SERVER_DOMAIN - -MOBILE_CONFIG_SIGN_SSL = IPACONF.MOBILE_CONFIG_SIGN_SSL - -APPLE_DEVELOPER_API_PROXY = IPACONF.APPLE_DEVELOPER_API_PROXY - -APPLE_DEVELOPER_API_TIMEOUT = IPACONF.APPLE_DEVELOPER_API_TIMEOUT - -APPLE_DEVELOPER_API_PROXY_LIST = IPACONF.APPLE_DEVELOPER_API_PROXY_LIST - -DEFAULT_MOBILEPROVISION = IPACONF.DEFAULT_MOBILEPROVISION -# DEFAULT_MOBILEPROVISION = { -# # 默认描述文件路径或者下载路径,用户企业签名或者超级签名 跳转 [设置 - 通用 - 描述文件|设备管理] 页面 -# # 如果配置了path路径,则走路径,如果配置了url,则走URL,path 优先级大于url优先级 -# 'enterprise': { -# 'path': os.path.join(MEDIA_ROOT, 'embedded.mobileprovision'), -# 'url': 'https://ali-static.jappstore.com/embedded.mobileprovision' -# }, -# 'supersign': { -# # 超级签名,如果self 为True,则默认用自己的描述文件,否则同企业配置顺序一致,自己的配置文件有时候有问题 -# 'self': False, -# 'path': os.path.join(MEDIA_ROOT, 'embedded.mobileprovision'), -# 'url': 'https://ali-static.jappstore.com/embedded.mobileprovision' -# } -# } - SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default" @@ -473,7 +431,7 @@ CELERY_BEAT_SCHEDULE = { }, 'check_bypass_status_job': { 'task': 'api.tasks.check_bypass_status_job', - 'schedule': GEETEST_CYCLE_TIME, + 'schedule': BASECONF.GEETEST_CYCLE_TIME, 'args': () }, 'auto_clean_upload_tmp_file_job': { @@ -510,13 +468,7 @@ CELERY_BEAT_SCHEDULE = { }, } -MSGTEMPLATE = { - 'NOT_EXIST_DEVELOPER': '用户 %s 你好,应用 %s 签名失败了,苹果开发者总设备量已经超限,请添加新的苹果开发者或者修改开发者设备数量。感谢有你!', - 'ERROR_DEVELOPER': '用户 %s 你好,应用 %s 签名失败了,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!', - 'AUTO_CHECK_DEVELOPER': '用户 %s 你好,苹果开发者 %s 信息异常,请重新检查苹果开发者状态是否正常。感谢有你!', -} - -## listen port +# listen port SERVER_BIND_HOST = BASECONF.SERVER_BIND_HOST SERVER_LISTEN_PORT = BASECONF.SERVER_LISTEN_PORT