diff --git a/fir_client/src/components/FirBase.vue b/fir_client/src/components/FirBase.vue
index dcc987b..e1a8952 100644
--- a/fir_client/src/components/FirBase.vue
+++ b/fir_client/src/components/FirBase.vue
@@ -20,7 +20,7 @@
应用分发请绑定您自己的域名,平台分发域名可能因不可违因素更换,将导致您的应用无法访问
- 立即绑定
+ 立即绑定
diff --git a/fir_client/src/components/base/BindDomain.vue b/fir_client/src/components/base/BindDomain.vue
index 60f1534..48e7dd1 100644
--- a/fir_client/src/components/base/BindDomain.vue
+++ b/fir_client/src/components/base/BindDomain.vue
@@ -36,12 +36,26 @@
align="center"
label="主机记录"
>
+
+
+ {{ scope.row.host }}
+
+
+
+
+
+ {{ scope.row.dns }}
+
+
+
上一步
- 下一步
+ 强制绑定
+ 下一步
+
@@ -156,6 +172,7 @@
bind_domain_sure: true,
domain_name: '',
domain_tData: [{'type': 'CNAME', 'host': 'xxx', 'dns': 'demo.xxx.cn'}],
+ force_bind:false,
}
},
mounted() {
@@ -165,13 +182,18 @@
this.bind_domain_sure = false;
},
methods: {
+ copy_success() {
+ this.$message.success('复制剪切板成功');
+ },
check_cname() {
domainFun(data => {
if (data.code === 1000) {
if (this.active++ > 2) this.active = 3;
this.bind_status = true;
if (!this.app_id) {
- this.$store.dispatch("dodomainshow", false);
+ if (this.domain_type === 1) {
+ this.$store.dispatch("dodomainshow", false);
+ }
}
} else {
if (data.code === 1004) {
@@ -234,7 +256,7 @@
}
this.domain_tData[0].dns = cname_domain;
},
- next() {
+ next(force_bind) {
if (this.active === 1) {
domainFun(data => {
if (data.code === 1000) {
@@ -243,11 +265,14 @@
if (this.active++ > 2) this.active = 3;
}
} else {
- this.$message.error("绑定失败 " + data.msg)
+ this.$message.error("绑定失败 " + data.msg);
+ if(data.code === 1011){
+ this.force_bind=true
+ }
}
}, {
methods: 'POST',
- data: {domain_name: this.domain_name, app_id: this.app_id, domain_type: this.domain_type}
+ data: {domain_name: this.domain_name, app_id: this.app_id, domain_type: this.domain_type,force_bind:force_bind}
})
} else if (this.active === 2) {
this.check_cname()
diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py
index be3a0ed..31b744e 100644
--- a/fir_ser/api/utils/app/supersignutils.py
+++ b/fir_ser/api/utils/app/supersignutils.py
@@ -4,7 +4,7 @@
# author: liuyu
# date: 2020/3/6
-import uuid, xmltodict, os, re, logging, time
+import uuid, xmltodict, os, logging, time
import zipfile
from api.utils.response import BaseResponse
diff --git a/fir_ser/api/utils/baseutils.py b/fir_ser/api/utils/baseutils.py
index 7dfbf16..3d931fd 100644
--- a/fir_ser/api/utils/baseutils.py
+++ b/fir_ser/api/utils/baseutils.py
@@ -229,3 +229,16 @@ def get_filename_form_file(filename):
f_type = '.ipa'
return f"{app_obj.name}-{app_release_obj.app_version}-{app_obj.short}{f_type}"
return filename
+
+
+def check_app_domain_name_access(app_obj, access_domain_name, extra_domain=None):
+ if app_obj and access_domain_name:
+ domain_list = []
+ if extra_domain:
+ domain_list.append(extra_domain)
+ app_domain_name = get_app_domain_name(app_obj)
+ if app_domain_name: domain_list.append(app_domain_name)
+ user_domain_name = get_user_domain_name(app_obj.user_id)
+ if user_domain_name: domain_list.append(user_domain_name)
+ if access_domain_name in domain_list:
+ return True
diff --git a/fir_ser/api/utils/storage/caches.py b/fir_ser/api/utils/storage/caches.py
index a1af506..170dae4 100644
--- a/fir_ser/api/utils/storage/caches.py
+++ b/fir_ser/api/utils/storage/caches.py
@@ -13,7 +13,7 @@ from django.utils import timezone
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
from api.utils.storage.storage import Storage, LocalStorage
-from api.utils.baseutils import get_app_d_count_by_app_id, get_app_domain_name, check_app_password
+from api.utils.baseutils import get_app_d_count_by_app_id, get_app_domain_name, check_app_password, get_user_domain_name
import logging
from django.db.models import F
@@ -146,12 +146,16 @@ def del_cache_response_by_short(app_id, udid=''):
del_cache_response_by_short_util(combo_dict.get("short"), combo_dict.get("app_id"), udid)
-def del_cache_response_by_short_util(short, app_id, udid):
- logger.info(f"del_cache_response_by_short short:{short} app_id:{app_id} udid:{udid}")
+def del_short_cache(short):
key = "_".join([CACHE_KEY_TEMPLATE.get("download_short_key"), short, '*'])
for app_download_key in cache.iter_keys(key):
cache.delete(app_download_key)
+
+def del_cache_response_by_short_util(short, app_id, udid):
+ logger.info(f"del_cache_response_by_short short:{short} app_id:{app_id} udid:{udid}")
+ del_short_cache(short)
+
cache.delete("_".join([CACHE_KEY_TEMPLATE.get("app_instance_key"), app_id]))
key = 'ShortDownloadView'.lower()
@@ -274,16 +278,27 @@ def send_msg_over_limit(act, email):
return limit_cache_util(act, auth_code_key, SYNC_CACHE_TO_DATABASE.get("try_send_msg_over_limit_times"))
-def set_default_app_wx_easy(user_obj, only_clean_cache=False):
- app_obj_lists = Apps.objects.filter(user_id=user_obj)
- for app_obj in app_obj_lists:
- if only_clean_cache:
- del_cache_response_by_short(app_obj.app_id)
- else:
- if not get_app_domain_name(app_obj):
- app_obj.wxeasytype = True
- app_obj.save(update_fields=['wxeasytype'])
- del_cache_response_by_short(app_obj.app_id)
+def reset_short_response_cache(user_obj, app_obj=None):
+ if app_obj is None:
+ app_obj_short_list = [x[0] for x in Apps.objects.filter(user_id=user_obj).values_list('short').all() if x]
+ else:
+ app_obj_short_list = [app_obj.short]
+ for short in app_obj_short_list:
+ del_short_cache(short)
+
+
+def reset_app_wx_easy_type(user_obj, app_obj=None):
+ if get_user_domain_name(user_obj):
+ return reset_short_response_cache(user_obj, app_obj)
+ if app_obj is None:
+ app_obj_list = Apps.objects.filter(user_id=user_obj).all()
+ else:
+ app_obj_list = [app_obj]
+ for app_obj in app_obj_list:
+ if not get_app_domain_name(app_obj):
+ app_obj.wxeasytype = True
+ app_obj.save(update_fields=['wxeasytype'])
+ del_short_cache(app_obj.short)
def enable_user_download_times_flag(user_id):
diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py
index cd423ba..ef232ee 100644
--- a/fir_ser/api/utils/utils.py
+++ b/fir_ser/api/utils/utils.py
@@ -7,7 +7,7 @@ import os, datetime, random
import binascii
from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT, CACHE_KEY_TEMPLATE
from api.models import APPSuperSignUsedInfo, APPToDeveloper, \
- UDIDsyncDeveloper, UserInfo, AppReleaseInfo, AppScreenShot, Token, DeveloperDevicesID, Apps
+ UDIDsyncDeveloper, UserInfo, AppReleaseInfo, AppScreenShot, Token, DeveloperDevicesID
from api.utils.storage.caches import get_app_d_count_by_app_id
from api.utils.storage.localApi import LocalStorage
from api.utils.storage.storage import Storage
diff --git a/fir_ser/api/views/domain.py b/fir_ser/api/views/domain.py
index 7141096..fc875bb 100644
--- a/fir_ser/api/views/domain.py
+++ b/fir_ser/api/views/domain.py
@@ -14,7 +14,7 @@ from rest_framework.response import Response
from api.models import UserDomainInfo, Apps
import logging
-from api.utils.storage.caches import set_default_app_wx_easy, del_cache_response_by_short
+from api.utils.storage.caches import del_cache_response_by_short, reset_app_wx_easy_type, reset_short_response_cache
logger = logging.getLogger(__name__)
@@ -31,6 +31,32 @@ def get_domain_filter(request):
return filter_dict
+def remove_domain_wx_easy(app_obj, user_obj):
+ if app_obj and not get_user_domain_name(user_obj):
+ app_obj.wxeasytype = True
+ app_obj.save(update_fields=['wxeasytype'])
+ del_cache_response_by_short(app_obj.app_id)
+
+
+def add_new_domain_info(res, request, domain_name, domain_type):
+ min_domain_cname_info_obj = get_min_default_domain_cname_obj(False)
+ if min_domain_cname_info_obj:
+ res.data = {'cname_domain': min_domain_cname_info_obj.domain_record}
+ data_dict = {
+ 'user_id': request.user,
+ 'cname_id': min_domain_cname_info_obj,
+ 'domain_name': domain_name,
+ 'app_id': None,
+ 'domain_type': domain_type
+ }
+ app_id = request.data.get("app_id", None)
+ if app_id:
+ app_obj = Apps.objects.filter(app_id=app_id).first()
+ if app_obj:
+ data_dict['app_id'] = app_obj
+ UserDomainInfo.objects.create(**data_dict)
+
+
class DomainCnameView(APIView):
authentication_classes = [ExpiringTokenAuthentication, ]
@@ -49,6 +75,7 @@ class DomainCnameView(APIView):
res = BaseResponse()
domain_name = request.data.get("domain_name", None)
domain_type = request.data.get('domain_type', 1)
+ force_bind = request.data.get('force_bind', 0)
if domain_type not in [x[0] for x in list(UserDomainInfo.domain_type_choices)]:
res.code = 1001
res.msg = "绑定失败"
@@ -56,33 +83,37 @@ class DomainCnameView(APIView):
if domain_name:
domain_name = domain_name.strip(" ")
if domain_name and len(domain_name) > 3 and is_valid_domain(domain_name):
- if UserDomainInfo.objects.filter(domain_name=domain_name, is_enable=True,
- domain_type=domain_type).count() != 0:
- res.code = 1001
- res.msg = "该域名已经被绑定,请更换其他域名"
+ filter_dict = get_domain_filter(request)
+ if not force_bind:
+ user_domain_obj = UserDomainInfo.objects.filter(domain_name=domain_name, is_enable=True).first()
+ if user_domain_obj:
+ res.code = 1011
+ if user_domain_obj.user_id.uid == request.user.uid:
+ app_obj = user_domain_obj.app_id
+ if app_obj:
+ res.msg = f"该域名已经被应用 {app_obj.name} 绑定"
+ elif user_domain_obj.domain_type == 0:
+ res.msg = f"该域名已经被 应用下载码绑定"
+ else:
+ res.msg = f"该域名已经被 预览下载页绑定"
+ else:
+ res.msg = "该域名已经被其他用户绑定"
+ res.msg += ",请更换要绑定的域名,或者进行强制绑定域名"
+ else:
+ user_domain_obj = UserDomainInfo.objects.filter(**get_domain_filter(request),
+ domain_name=domain_name).first()
+ if user_domain_obj:
+ res.data = {'cname_domain': user_domain_obj.cname_id.domain_record}
+ else:
+ UserDomainInfo.objects.filter(**filter_dict, is_enable=False).delete()
+ add_new_domain_info(res, request, domain_name, domain_type)
else:
- user_domain_obj = UserDomainInfo.objects.filter(**get_domain_filter(request),
+ user_domain_obj = UserDomainInfo.objects.filter(**filter_dict,
domain_name=domain_name).first()
if user_domain_obj:
res.data = {'cname_domain': user_domain_obj.cname_id.domain_record}
else:
- UserDomainInfo.objects.filter(**get_domain_filter(request), is_enable=False).delete()
- min_domain_cname_info_obj = get_min_default_domain_cname_obj(False)
- if min_domain_cname_info_obj:
- res.data = {'cname_domain': min_domain_cname_info_obj.domain_record}
- data_dict = {
- 'user_id': request.user,
- 'cname_id': min_domain_cname_info_obj,
- 'domain_name': domain_name,
- 'app_id': None,
- 'domain_type': domain_type
- }
- app_id = request.data.get("app_id", None)
- if app_id:
- app_obj = Apps.objects.filter(app_id=app_id).first()
- if app_obj:
- data_dict['app_id'] = app_obj
- UserDomainInfo.objects.create(**data_dict)
+ add_new_domain_info(res, request, domain_name, domain_type)
else:
res.code = 1002
res.msg = "该域名校验失败,请检查"
@@ -94,19 +125,26 @@ class DomainCnameView(APIView):
if user_domain_obj:
cname = get_cname_from_domain(user_domain_obj.domain_name)
if cname == user_domain_obj.cname_id.domain_record + '.':
- user_domain_obj.is_enable = True
- user_domain_obj.save(update_fields=["is_enable"])
- UserDomainInfo.objects.filter(domain_name=user_domain_obj.domain_name, is_enable=False,
- domain_type=user_domain_obj.domain_type).delete()
- app_id = request.data.get("app_id", None)
- if app_id:
- app_obj = Apps.objects.filter(app_id=app_id).first()
- if app_obj:
- app_obj.wxeasytype = False
- app_obj.save(update_fields=['wxeasytype'])
- del_cache_response_by_short(app_obj.app_id)
+ user_domain_obj_list = UserDomainInfo.objects.filter(domain_name=user_domain_obj.domain_name,
+ is_enable=True).all()
+ if len(user_domain_obj_list) < 2:
+ if len(user_domain_obj_list) == 1:
+ user_obj = user_domain_obj_list.first().user_id
+ app_obj = user_domain_obj_list.first().app_id
+ user_domain_obj_list.delete()
+ reset_app_wx_easy_type(user_obj, app_obj)
+
+ user_domain_obj.is_enable = True
+ user_domain_obj.save(update_fields=["is_enable"])
+
+ app_id = request.data.get("app_id", None)
+ app_obj = None
+ if app_id:
+ app_obj = Apps.objects.filter(app_id=app_id).first()
+ reset_app_wx_easy_type(request.user, app_obj)
else:
- set_default_app_wx_easy(request.user, True)
+ res.code = 1002
+ res.msg = "该域名查询校验失败,请检查"
else:
res.code = 1003
res.msg = "系统未检出到您的CNAME记录"
@@ -117,14 +155,12 @@ class DomainCnameView(APIView):
def delete(sele, request):
res = BaseResponse()
- if UserDomainInfo.objects.filter(**get_domain_filter(request)).delete()[0]:
+ user_domain_obj = UserDomainInfo.objects.filter(**get_domain_filter(request)).first()
+ if user_domain_obj:
app_id = request.query_params.get("app_id", None)
+ app_obj = None
if app_id:
app_obj = Apps.objects.filter(app_id=app_id).first()
- if app_obj and not get_user_domain_name(request.user):
- app_obj.wxeasytype = True
- app_obj.save(update_fields=['wxeasytype'])
- del_cache_response_by_short(app_obj.app_id)
- else:
- set_default_app_wx_easy(request.user)
+ reset_app_wx_easy_type(request.user, app_obj)
+ user_domain_obj.delete()
return Response(res.dict)
diff --git a/fir_ser/api/views/download.py b/fir_ser/api/views/download.py
index 3895e94..765ca3d 100644
--- a/fir_ser/api/views/download.py
+++ b/fir_ser/api/views/download.py
@@ -3,6 +3,8 @@
# project: 3月
# author: liuyu
# date: 2020/3/6
+from urllib.parse import urlsplit
+
from rest_framework.views import APIView
from api.utils.TokenManager import verify_token
@@ -21,7 +23,8 @@ from api.utils.serializer import AppsShortSerializer
from api.models import Apps, AppReleaseInfo, APPToDeveloper, APPSuperSignUsedInfo
from django.http import FileResponse
import logging
-from api.utils.baseutils import get_profile_full_path, get_app_domain_name, get_filename_form_file
+from api.utils.baseutils import get_profile_full_path, get_app_domain_name, get_filename_form_file, \
+ check_app_domain_name_access
from api.utils.throttle import VisitShortThrottle, InstallShortThrottle, InstallThrottle1, InstallThrottle2
logger = logging.getLogger(__name__)
@@ -146,19 +149,24 @@ class ShortDownloadView(APIView):
res = check_app_permission(app_obj, res)
if res.code != 1000:
return Response(res.dict)
+ origin_domain_name = request.META.get('HTTP_ORIGIN', 'xx').split('//')[-1]
+ domain_name = get_redirect_server_domain(request, app_obj.user_id, get_app_domain_name(app_obj))
+ if not check_app_domain_name_access(app_obj, origin_domain_name, domain_name.split('//')[-1]):
+ res.code = 1004
+ res.msg = "访问域名不合法"
+ else:
+ if udid:
+ if not app_obj.issupersign:
+ res.code = 1002
+ res.msg = "参数有误"
+ return Response(res.dict)
+ del_cache_response_by_short(app_obj.app_id, udid=udid)
- if udid:
- if not app_obj.issupersign:
- res.code = 1002
- res.msg = "参数有误"
- return Response(res.dict)
- del_cache_response_by_short(app_obj.app_id, udid=udid)
-
- app_serializer = AppsShortSerializer(app_obj, context={"key": "ShortDownloadView", "release_id": release_id,
- "storage": Storage(app_obj.user_id)})
- res.data = app_serializer.data
- res.udid = udid
- res.domain_name = get_redirect_server_domain(request, app_obj.user_id, get_app_domain_name(app_obj))
+ app_serializer = AppsShortSerializer(app_obj, context={"key": "ShortDownloadView", "release_id": release_id,
+ "storage": Storage(app_obj.user_id)})
+ res.data = app_serializer.data
+ res.udid = udid
+ res.domain_name = domain_name
return Response(res.dict)
# key的设置
@@ -167,13 +175,18 @@ class ShortDownloadView(APIView):
release_id = request.query_params.get("release_id", '')
udid = request.query_params.get("udid", None)
time = request.query_params.get("time", None)
+ origin_domain_name = request.META.get('HTTP_ORIGIN', 'xx').split('//')[-1]
+ if not origin_domain_name:
+ origin_domain_name = 'default.site'
if udid and time:
udid = time
if not udid:
udid = ""
- logging.info(f"get or make cache_response short:{kwargs.get('short', '')} release_id:{release_id} udid:{udid}")
+ logging.info(
+ f"get or make cache_response short:{kwargs.get('short', '')} origin_domain_name:{origin_domain_name} release_id:{release_id} udid:{udid}")
return "_".join(
- [settings.CACHE_KEY_TEMPLATE.get("download_short_key"), kwargs.get("short", ''), release_id, udid])
+ [settings.CACHE_KEY_TEMPLATE.get("download_short_key"), kwargs.get("short", ''), origin_domain_name,
+ release_id, udid])
class InstallView(APIView):