fix some bugs

super_signature
nineven 5 years ago
parent 72d8ebcfd8
commit 9cdc609eb5
  1. 8
      fir_client/src/components/FirDownload.vue
  2. 7
      fir_client/src/restful/index.js
  3. 29
      fir_download/src/components/FirDownload.vue
  4. 10
      fir_download/src/restful/download.js
  5. 22
      fir_ser/api/migrations/0004_auto_20200504_2054.py
  6. 2
      fir_ser/api/models.py
  7. 4
      fir_ser/api/utils/app/shellcmds.py
  8. 32
      fir_ser/api/utils/app/supersignutils.py
  9. 5
      fir_ser/api/utils/serializer.py
  10. 7
      fir_ser/api/utils/storage/caches.py
  11. 16
      fir_ser/api/views/download.py
  12. 8
      fir_ser/fir_ser/settings.py

@ -149,7 +149,7 @@
<script> <script>
import QRCode from 'qrcodejs2' import QRCode from 'qrcodejs2'
import {getShortAppinfo,getdownloadurl,getplisturl} from '../restful' import {getShortAppinfo,getdownloadurl} from '../restful'
export default { export default {
name: "FirDownload", name: "FirDownload",
@ -183,12 +183,12 @@
if(this.currentappinfo.type === 1){ if(this.currentappinfo.type === 1){
if(this.currentappinfo.issupersign && this.udid !== this.$route.query.udid){ if(this.currentappinfo.issupersign && this.udid !== this.$route.query.udid){
if(this.agent !== ''){ if(this.agent !== ''){
let download_url = res.data.download_url; this.downloadurl=res.data.download_url;
this.downloadurl = download_url.replace('http://localhost/download',getplisturl()); // this.downloadurl = download_url.replace('http://localhost/download',getplisturl());
} }
}else { }else {
let download_url = res.data.download_url; let download_url = res.data.download_url;
download_url = download_url.replace('http://localhost/download',getplisturl()); // download_url = download_url.replace('http://localhost/download',getplisturl());
this.downloadurl="itms-services://?action=download-manifest&url="+encodeURIComponent(download_url); this.downloadurl="itms-services://?action=download-manifest&url="+encodeURIComponent(download_url);
} }
}else{ }else{

@ -9,10 +9,8 @@ Axios.defaults.httpsAgent = new https.Agent({
keepAlive: true keepAlive: true
}); });
// Axios.defaults.baseURL='';
const DOMAIN = 'https://fly.dvcloud.xin';
// const DOMAIN = 'http://192.168.8.236:8000'; const DOMAIN = 'https://fly.harmonygames.cn';
const APIPATH='/api/v1/fir/server'; const APIPATH='/api/v1/fir/server';
let USERSEVER = DOMAIN+APIPATH; let USERSEVER = DOMAIN+APIPATH;
@ -358,9 +356,6 @@ export function getapppicurl(app_id) {
export function getuploadurl() { export function getuploadurl() {
return USERSEVER + '/upload' return USERSEVER + '/upload'
} }
export function getplisturl() {
return DOMAIN + '/download'
}
/**分析应用并获取app上传token */ /**分析应用并获取app上传token */

@ -29,7 +29,8 @@
<span id="qrcode" class="qrcode"> <span id="qrcode" class="qrcode">
</span> </span>
</div> </div>
<p class="scan-tips wrapper icon-warp" >{{ mcurrentappinfo.release_type|getiOStype }}</p> <p v-if="currentappinfo.issupersign" class="scan-tips wrapper icon-warp" >超级签</p>
<p v-else class="scan-tips wrapper icon-warp" >{{ mcurrentappinfo.release_type|getiOStype }}</p>
<h1 class="name wrapper"> <h1 class="name wrapper">
<span class="icon-warp" style="margin-left:0px"> <span class="icon-warp" style="margin-left:0px">
<i v-if="currentappinfo.type === 0 && agent !== ''" class="iconfont icon-android2"/> <i v-if="currentappinfo.type === 0 && agent !== ''" class="iconfont icon-android2"/>
@ -150,7 +151,7 @@
<script> <script>
import QRCode from 'qrcodejs2' import QRCode from 'qrcodejs2'
import {getShortAppinfo,getdownloadurl,getplisturl} from '../restful/download' import {getShortAppinfo,getdownloadurl} from '../restful/download'
export default { export default {
name: "FirDownload", name: "FirDownload",
@ -179,17 +180,26 @@
getdownloadurl(res => { getdownloadurl(res => {
if (res.code === 1000) { if (res.code === 1000) {
if (this.currentappinfo.type === 1) { if(res.data.download_url === ""){
window.location.href=this.full_url;
return
}
if(this.currentappinfo.type === 1){
if(this.currentappinfo.issupersign && this.udid !== this.$route.query.udid){
if(this.agent !== ''){
this.download_url = res.data.download_url;
}
}else {
let download_url = res.data.download_url; let download_url = res.data.download_url;
download_url = download_url.replace('http://localhost/download', getplisturl()); this.downloadurl="itms-services://?action=download-manifest&url="+encodeURIComponent(download_url);
this.downloadurl = "itms-services://?action=download-manifest&url=" + encodeURIComponent(download_url); }
} else { }else{
if (this.agent !== '') { if(this.agent !== ''){
this.downloadurl = res.data.download_url; this.downloadurl = res.data.download_url;
} }
} }
window.location.href = this.downloadurl; window.location.href=this.downloadurl;
} else { } else {
this.isdownload = false; this.isdownload = false;
alert("密码错误,或者下载链接失效") alert("密码错误,或者下载链接失效")
@ -200,6 +210,7 @@
'short': this.currentappinfo.short, 'short': this.currentappinfo.short,
'release_id': this.mcurrentappinfo.release_id, 'release_id': this.mcurrentappinfo.release_id,
'password': this.password, 'password': this.password,
'udid':this.udid,
}, },
'app_id': this.currentappinfo.app_id 'app_id': this.currentappinfo.app_id
}) })
@ -213,7 +224,7 @@
}) })
}, },
getDownloadTokenFun() { getDownloadTokenFun() {
let params={ "short": this.$route.params.short }; let params={ "short": this.$route.params.short,"time":new Date().getTime() };
if(this.$route.query.release_id){ if(this.$route.query.release_id){
params["release_id"]=this.$route.query.release_id params["release_id"]=this.$route.query.release_id
} }

@ -6,10 +6,9 @@ Axios.defaults.httpsAgent = new https.Agent({
keepAlive: true keepAlive: true
}); });
// Axios.defaults.baseURL=''; const DOMAIN = 'https://fly.harmonygames.cn';
const USERSEVER = 'https://fly.dvcloud.xin/api/v1/fir/server'; const APIPATH='/api/v1/fir/server';
let USERSEVER = DOMAIN+APIPATH;
// const USERSEVER = 'http://192.168.1.112:8000/api/v1/fir/server';
function getData(url, params = {}, callBack) { function getData(url, params = {}, callBack) {
@ -114,6 +113,3 @@ export function getdownloadurl(callBack, params) {
}, },
); );
} }
export function getplisturl() {
return USERSEVER + '/download'
}

@ -0,0 +1,22 @@
# Generated by Django 3.0.3 on 2020-05-04 20:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0003_apptodeveloper'),
]
operations = [
migrations.AlterModelOptions(
name='apptodeveloper',
options={'verbose_name': '应用开发者绑定', 'verbose_name_plural': '应用开发者绑定'},
),
migrations.AlterField(
model_name='apptodeveloper',
name='binary_file',
field=models.CharField(blank=True, max_length=128, null=True, unique=True, verbose_name='签名包名称'),
),
]

@ -232,7 +232,7 @@ class APPSuperSignUsedInfo(models.Model):
class APPToDeveloper(models.Model): class APPToDeveloper(models.Model):
app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP") app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP")
developerid = models.ForeignKey(to="AppIOSDeveloperInfo",on_delete=models.CASCADE, verbose_name="所使用苹果开发者账户") developerid = models.ForeignKey(to="AppIOSDeveloperInfo",on_delete=models.CASCADE, verbose_name="所使用苹果开发者账户")
binary_file = models.CharField(max_length=128,blank=True,verbose_name="签名包名称",null=True) binary_file = models.CharField(max_length=128,blank=True,verbose_name="签名包名称",null=True,unique=True)
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间") updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta: class Meta:

@ -86,15 +86,13 @@ class SSHConnection(object):
self._client.close() self._client.close()
def shell_command(cmdstrs,timeout): def shell_command(cmdstrs,timeout):
# cmdresult = re.split(r'\s+', cmdstrs)
# print(cmdresult)
result = default_result() result = default_result()
result['return_info'] = '' result['return_info'] = ''
shell_start_time = time.time() shell_start_time = time.time()
child = Popen(cmdstrs, shell=True, stdout=PIPE, stderr=PIPE) child = Popen(cmdstrs, shell=True, stdout=PIPE, stderr=PIPE)
if timeout: if timeout:
while child.poll() is None: while child.poll() is None:
time.sleep(0.2) time.sleep(1)
now = time.time() now = time.time()
if int(now - shell_start_time) > timeout: if int(now - shell_start_time) > timeout:
os.kill(child.pid, signal.SIGKILL) os.kill(child.pid, signal.SIGKILL)

@ -71,12 +71,13 @@ def make_udid_mobileconfig(udid_url, PayloadOrganization, PayloadUUID=uuid.uuid1
def get_post_udid_url(request, short): def get_post_udid_url(request, short):
server_domain = get_http_server_doamin(request) server_domain = get_http_server_doamin(request)
PATH_INFO = request.META.get('PATH_INFO') # PATH_INFO = request.META.get('PATH_INFO')
PATH_INFO_lists = PATH_INFO.strip('/').split('/') # PATH_INFO_lists = PATH_INFO.strip('/').split('/')
PATH_INFO_lists[-1] = 'udid' # PATH_INFO_lists[-1] = 'udid'
PATH_INFO_lists.pop(-2) # PATH_INFO_lists.pop(-2)
PATH_INFO_lists.append(short) # PATH_INFO_lists.append(short)
PATH_INFO_lists.insert(0, server_domain) # PATH_INFO_lists.insert(0, server_domain)
PATH_INFO_lists=[server_domain,"udid",short]
udid_url = "/".join(PATH_INFO_lists) udid_url = "/".join(PATH_INFO_lists)
return udid_url return udid_url
@ -283,6 +284,7 @@ class IosUtils(object):
developer_obj.save() developer_obj.save()
udid_obj.delete() udid_obj.delete()
SuperSignUsed_obj.delete() SuperSignUsed_obj.delete()
@ -301,8 +303,8 @@ class IosUtils(object):
if developer_obj: if developer_obj:
IosUtils.clean_app_by_developer_obj(app_obj,developer_obj) IosUtils.clean_app_by_developer_obj(app_obj,developer_obj)
APPToDeveloper.objects.filter(developerid=developer_obj,app_id=app_obj).delete() APPToDeveloper.objects.filter(developerid=developer_obj,app_id=app_obj).delete()
IosUtils.clean_udid_by_app_obj(app_obj,developer_obj) IosUtils.clean_udid_by_app_obj(app_obj,developer_obj)
@staticmethod @staticmethod
def clean_app_by_developer_obj(app_obj,developer_obj): def clean_app_by_developer_obj(app_obj,developer_obj):
auth = { auth = {
@ -322,28 +324,12 @@ class IosUtils(object):
:param developer_obj: :param developer_obj:
:return: :return:
''' '''
# auth = {
# "username": developer_obj.email,
# "password": developer_obj.password,
# "certid": developer_obj.certid
# }
for APPToDeveloper_obj in APPToDeveloper.objects.filter(developerid=developer_obj): for APPToDeveloper_obj in APPToDeveloper.objects.filter(developerid=developer_obj):
app_obj=APPToDeveloper_obj.app_id app_obj=APPToDeveloper_obj.app_id
IosUtils.clean_app_by_developer_obj(app_obj, developer_obj) IosUtils.clean_app_by_developer_obj(app_obj, developer_obj)
APPToDeveloper.objects.filter(developerid=developer_obj, app_id=app_obj).delete() APPToDeveloper.objects.filter(developerid=developer_obj, app_id=app_obj).delete()
IosUtils.clean_udid_by_app_obj(app_obj, developer_obj) IosUtils.clean_udid_by_app_obj(app_obj, developer_obj)
# for SuperSignUsed_obj in APPSuperSignUsedInfo.objects.filter(developerid=developer_obj):
#
# app_obj = SuperSignUsed_obj.app_id
# app_api_obj = AppDeveloperApi(**auth)
# app_api_obj.del_profile(app_obj.bundle_id, app_obj.app_id)
# app_api_obj2 = AppDeveloperApi(**auth)
# app_api_obj2.del_app(app_obj.bundle_id,app_obj.app_id)
# APPToDeveloper.objects.filter(developerid=developer_obj, app_id=app_obj).delete()
@staticmethod @staticmethod
def active_developer(developer_obj,code=None): def active_developer(developer_obj,code=None):
''' '''

@ -169,9 +169,12 @@ class AppReleaseSerializer(serializers.ModelSerializer):
def get_icon_url(self, obj): def get_icon_url(self, obj):
icon_url="" icon_url=""
key = ''
if self.context.get("key", None) and self.context.get("key") != "undefined":
key = self.context.get("key", '')
if self.context.get("storage", None) and self.context.get("storage") != "undefined": if self.context.get("storage", None) and self.context.get("storage") != "undefined":
storage = self.context.get("storage", None) storage = self.context.get("storage", None)
icon_url = storage.get_download_url(os.path.basename(obj.icon_url),600) icon_url = storage.get_download_url(os.path.basename(obj.icon_url),600,key=key)
return icon_url return icon_url

@ -8,7 +8,7 @@ from django.core.cache import cache
from api.models import Apps,UserInfo,AppReleaseInfo,AppUDID,APPToDeveloper,APPSuperSignUsedInfo from api.models import Apps,UserInfo,AppReleaseInfo,AppUDID,APPToDeveloper,APPSuperSignUsedInfo
import time,os import time,os
from django.utils import timezone from django.utils import timezone
from fir_ser.settings import CACHE_KEY_TEMPLATE from fir_ser.settings import CACHE_KEY_TEMPLATE,SERVER_DOMAIN
from api.utils.storage.storage import Storage,LocalStorage from api.utils.storage.storage import Storage,LocalStorage
from api.utils.crontab.sync_cache import sync_download_times_by_app_id from api.utils.crontab.sync_cache import sync_download_times_by_app_id
from api.utils.crontab import run from api.utils.crontab import run
@ -16,7 +16,7 @@ from api.utils.crontab import run
def get_download_url_by_cache(app_obj, filename, limit, isdownload=True,key='',udid=None): def get_download_url_by_cache(app_obj, filename, limit, isdownload=True,key='',udid=None):
now = time.time() now = time.time()
if isdownload is None: if isdownload is None:
local_storage = LocalStorage('localhost', False) local_storage = LocalStorage(**SERVER_DOMAIN.get("IOS_PMFILE_DOWNLOAD_DOMAIN"))
download_url_type = 'plist' download_url_type = 'plist'
if not udid: if not udid:
if app_obj.get('issupersign',None): if app_obj.get('issupersign',None):
@ -28,8 +28,7 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True,key='',u
if SuperSign_obj: if SuperSign_obj:
APPToDeveloper_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"),developerid=SuperSign_obj.developerid).first() APPToDeveloper_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"),developerid=SuperSign_obj.developerid).first()
if APPToDeveloper_obj: if APPToDeveloper_obj:
filename=APPToDeveloper_obj.binary_file return local_storage.get_download_url(APPToDeveloper_obj.binary_file+"."+filename.split(".")[-1], limit, download_url_type)
return local_storage.get_download_url(filename, limit, download_url_type)
else: else:
return "" return ""
else: else:

@ -16,7 +16,7 @@ from api.utils.storage.caches import get_app_instance_by_cache,get_download_url_
import os import os
from rest_framework_extensions.cache.decorators import cache_response from rest_framework_extensions.cache.decorators import cache_response
from api.utils.serializer import AppsShortSerializer from api.utils.serializer import AppsShortSerializer
from api.models import Apps,AppReleaseInfo from api.models import Apps,AppReleaseInfo,APPToDeveloper,APPSuperSignUsedInfo
from django.http import FileResponse from django.http import FileResponse
class DownloadView(APIView): class DownloadView(APIView):
''' '''
@ -48,7 +48,12 @@ class DownloadView(APIView):
return response return response
else: else:
if ftype == 'plist': if ftype == 'plist':
release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() release_id = filename.split('.')[0]
apptodev_obj = APPToDeveloper.objects.filter(binary_file=release_id).first()
if apptodev_obj:
release_obj = AppReleaseInfo.objects.filter(is_master=True,app_id=apptodev_obj.app_id).first()
else:
release_obj = AppReleaseInfo.objects.filter(release_id=release_id).first()
if release_obj: if release_obj:
storage = Storage(release_obj.app_id.user_id) storage = Storage(release_obj.app_id.user_id)
bundle_id = release_obj.app_id.bundle_id bundle_id = release_obj.app_id.bundle_id
@ -59,6 +64,7 @@ class DownloadView(APIView):
response['Content-Type'] = "application/x-plist" response['Content-Type'] = "application/x-plist"
response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid()
return response return response
res.msg = "plist release_id error"
elif ftype == 'mobileconifg': elif ftype == 'mobileconifg':
release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first()
if release_obj: if release_obj:
@ -69,6 +75,7 @@ class DownloadView(APIView):
response['Content-Type'] = "application/x-apple-aspen-config" response['Content-Type'] = "application/x-apple-aspen-config"
response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() +'.mobileconfig' response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() +'.mobileconfig'
return response return response
res.msg = "mobileconifg release_id error"
res.code=1004 res.code=1004
res.msg="token校验失败" res.msg="token校验失败"
@ -85,13 +92,12 @@ class ShortDownloadView(APIView):
release_id = request.query_params.get("release_id", None) release_id = request.query_params.get("release_id", None)
udid = request.query_params.get("udid", None) udid = request.query_params.get("udid", None)
app_obj = Apps.objects.filter(short=short).first() app_obj = Apps.objects.filter(short=short).first()
if udid:
del_cache_response_by_short(short,app_obj.app_id,udid=udid)
if not app_obj: if not app_obj:
res.code=1003 res.code=1003
res.msg="该应用不存在" res.msg="该应用不存在"
return Response(res.dict) return Response(res.dict)
if udid:
del_cache_response_by_short(short,app_obj.app_id,udid=udid)
if not app_obj.isshow: if not app_obj.isshow:
res.code=1004 res.code=1004
res.msg="您没有权限访问该应用" res.msg="您没有权限访问该应用"

@ -250,8 +250,12 @@ SYNC_CACHE_TO_DATABASE={
} }
SERVER_DOMAIN={ SERVER_DOMAIN={
'POST_UDID_DOMAIN':'http://192.168.8.236:8000', #超级签名调试 'IOS_PMFILE_DOWNLOAD_DOMAIN':{
'REDIRECT_UDID_DOMAIN': 'http://192.168.8.236:8080', # 超级签名调试 "domain_name":'fly.harmonygames.cn',
'is_https':True,
}, # ios 描述文件和plist文件下载域名,该域名用于后端,一般为api访问域名
'POST_UDID_DOMAIN':'https://fly.harmonygames.cn', #超级签名 安装签名时 向该域名 发送udid数据,该域名用于后端,一般为 api 访问域名
'REDIRECT_UDID_DOMAIN': 'https://fly.harmonygames.cn', # 超级签名 安装完成之后,跳转域名,该域名为前端web访问域名
} }
SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_ENGINE = "django.contrib.sessions.backends.cache"

Loading…
Cancel
Save