删除超级签名,用户和密码添加方式

dependabot/npm_and_yarn/fir_admin/dns-packet-1.3.4
youngS 4 years ago
parent 2c557a5b12
commit fd56fcd88b
  1. 117
      fir_client/src/components/user/FirSuperSignBase.vue
  2. 33
      fir_ser/api/migrations/0001_initial.py
  3. 17
      fir_ser/api/migrations/0002_domaincnameinfo_is_https.py
  4. 27
      fir_ser/api/migrations/0003_auto_20210526_1645.py
  5. 31
      fir_ser/api/models.py
  6. 86
      fir_ser/api/utils/app/iossignapi.py
  7. 103
      fir_ser/api/utils/app/shellcmds.py
  8. 66
      fir_ser/api/utils/app/supersignutils.py
  9. 25
      fir_ser/api/utils/baseutils.py
  10. 2
      fir_ser/api/utils/crontab/ctasks.py
  11. 5
      fir_ser/api/utils/sendmsg/sendmsg.py
  12. 10
      fir_ser/api/utils/serializer.py
  13. 22
      fir_ser/api/utils/storage/caches.py
  14. 3
      fir_ser/api/views/receiveudids.py
  15. 64
      fir_ser/api/views/supersign.py
  16. 5
      fir_ser/api/views/uploads.py

@ -23,16 +23,6 @@
</el-form-item>
</div>
<div v-if="editdeveloperinfo.auth_type===1">
<el-form-item label-width="110px" label="APP_ID">
<el-input :disabled='isedit' v-model="editdeveloperinfo.email"/>
</el-form-item>
<el-form-item label-width="110px" label="password">
<el-input v-model="editdeveloperinfo.password" :placeholder="placeholder"/>
</el-form-item>
</div>
<el-form-item label-width="110px" label="设备数量">
<el-input v-model="editdeveloperinfo.usable_number"/>
</el-form-item>
@ -58,32 +48,13 @@
</el-form>
</el-dialog>
<el-dialog
title="请在5分钟内输入验证码"
:visible.sync="codeactiveVisible"
width="30%"
center>
<div>
<el-input
placeholder="一般为6位数字"
v-model="authcode">
</el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="codeactiveVisible = false"> </el-button>
<el-button type="primary" @click="inputcode"> </el-button>
</span>
</el-dialog>
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick" tab-position="top">
<el-tab-pane label="开发者账户" name="iosdeveloper">
<el-input
style="width: 30%;margin-right: 30px;margin-bottom: 10px"
v-model="appidseach"
clearable
placeholder="输入用户APPID"/>
placeholder="输入用户ID"/>
<el-button type="primary" icon="el-icon-search" @click="handleCurrentChange(pagination.currentPage)">
搜索
</el-button>
@ -108,8 +79,8 @@
<el-table-column
fixed
prop="email"
label="用户"
prop="issuer_id"
label="用户 issuer_id"
width="300">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
@ -120,9 +91,6 @@
?scope.row.usable_number-scope.row.developer_used_number :0 }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium" v-if="scope.row.email"><i class="el-icon-s-custom"/> {{
scope.row.email }}
</el-tag>
<el-tag size="medium" v-if="scope.row.issuer_id"><i class="el-icon-key"/> {{
scope.row.issuer_id }}
</el-tag>
@ -194,8 +162,8 @@
<el-table-column
:formatter="formatter"
prop="updated_time"
label="更新时间"
prop="cert_expire_time"
label="证书到期时间"
width="160">
</el-table-column>
<el-table-column
@ -251,17 +219,6 @@
</el-form-item>
</div>
<div v-if="editdeveloperinfo.auth_type===1">
<el-form-item label-width="110px" label="APP_ID">
<el-input :disabled='isedit' v-model="editdeveloperinfo.email"/>
</el-form-item>
<el-form-item label-width="110px" label="password">
<el-input v-model="editdeveloperinfo.password" :placeholder="placeholder"/>
</el-form-item>
</div>
<el-form-item label-width="110px" label="设备数量">
<el-input v-model="editdeveloperinfo.usable_number"/>
</el-form-item>
@ -291,7 +248,7 @@
style="width: 23%;margin-right: 30px;margin-bottom: 10px"
v-model="appidseach"
clearable
placeholder="输入用户APPID"/>
placeholder="输入用户ID"/>
<el-button type="primary" icon="el-icon-search" @click="handleCurrentChange(pagination.currentPage)">
搜索
</el-button>
@ -438,7 +395,7 @@
<script>
import {iosdeveloper, iosdevices, iosdevicesudid} from "@/restful";
import {getUserInfoFun, IsNum, removeAaary} from "@/utils";
import {getUserInfoFun, removeAaary} from "@/utils";
export default {
name: "FirSuperSignBase",
@ -456,12 +413,9 @@
editdeveloperinfo: {auth_type: 0},
isedit: false,
placeholder: "",
codeactiveVisible: false,
pagination: {"currentPage": 1, "total": 0, "pagesize": 10},
developer_used_info: {"all_usable_number": 0, "other_used_sum": 0, "all_use_number": 0},
percentage: 0,
authcode: "",
authemail: "",
apple_auth_list: [],
apple_auth_type: 0,
loadingfun: {},
@ -504,46 +458,19 @@
})
},
syncdevices() {
let data = {"email": this.editdeveloperinfo.email, "act": "syncdevice"};
if (this.editdeveloperinfo.issuer_id) {
data = {"issuer_id": this.editdeveloperinfo.issuer_id, "act": "syncdevice"};
}
this.iosdeveloperFun({
"methods": "PUT",
"data": data
"data": {"issuer_id": this.editdeveloperinfo.issuer_id, "act": "syncdevice"}
});
},
isocertcert() {
let data = {"email": this.editdeveloperinfo.email, "act": "ioscert"};
if (this.editdeveloperinfo.issuer_id) {
data = {"issuer_id": this.editdeveloperinfo.issuer_id, "act": "ioscert"};
}
this.iosdeveloperFun({
"methods": "PUT",
"data": data
"data": {"issuer_id": this.editdeveloperinfo.issuer_id, "act": "ioscert"}
});
},
inputcode() {
this.authcode = this.authcode.replace(/^\s+|\s+$/g, "");
if (this.authcode.toString().length > 5 && IsNum(this.authcode)) {
this.iosdeveloperFun({
"methods": "PUT",
"data": {"email": this.authemail, "act": "nowactive", "code": this.authcode}
});
this.authcode = "";
this.authemail = ""
}
},
activedeveloperFun(developer, act) {
if (developer.email) {
this.iosdeveloperFun({"methods": "PUT", "data": {"email": developer.email, "act": act}});
this.codeactiveVisible = true;
this.authemail = developer.email;
} else if (developer.issuer_id) {
this.iosdeveloperFun({"methods": "PUT", "data": {"issuer_id": developer.issuer_id, "act": act}});
}
// this.inputcode(developer)
this.iosdeveloperFun({"methods": "PUT", "data": {"issuer_id": developer.issuer_id, "act": act}});
},
canceledit() {
this.dialogaddDeveloperVisible = false;
@ -562,14 +489,7 @@
if (this.isedit) {
this.iosdeveloperFun({"methods": "PUT", "data": this.editdeveloperinfo})
} else {
if (this.editdeveloperinfo.auth_type === 1) {
if (this.editdeveloperinfo.email && this.editdeveloperinfo.password && this.editdeveloperinfo.usable_number) {
this.iosdeveloperFun({"methods": "POST", "data": this.editdeveloperinfo});
} else {
this.$message.warning("输入格式有误")
}
} else if (this.editdeveloperinfo.auth_type === 0) {
if (this.editdeveloperinfo.auth_type === 0) {
if (this.editdeveloperinfo.issuer_id && this.editdeveloperinfo.private_key_id && this.editdeveloperinfo.usable_number && this.editdeveloperinfo.p8key) {
this.iosdeveloperFun({"methods": "POST", "data": this.editdeveloperinfo});
} else {
@ -582,18 +502,12 @@
}
},
handleDeleteDeveloper(developer_info) {
this.$confirm('此操作会删除该苹果开发者账户下面的生成的证书等数据,可能会导致超级签包的闪退, 是否继续?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let data = {"email": developer_info.email};
if (developer_info.issuer_id) {
data = {"issuer_id": developer_info.issuer_id};
}
this.iosdeveloperFun({"methods": "DELETE", "data": data});
this.iosdeveloperFun({"methods": "DELETE", "data": {"issuer_id": developer_info.issuer_id}});
}).catch(() => {
this.$message({
type: 'info',
@ -634,7 +548,7 @@
},
// eslint-disable-next-line no-unused-vars
formatter(row, column) {
let stime = row.updated_time;
let stime = row.cert_expire_time;
if (stime) {
stime = stime.split(".")[0].split("T");
return stime[0] + " " + stime[1]
@ -682,7 +596,7 @@
this.activeName = "iosdeveloper";
this.editdeveloperinfo = {auth_type: 0};
}
if (!this.edit && (this.editdeveloperinfo.email || this.editdeveloperinfo.issuer_id)) {
if (!this.edit && this.editdeveloperinfo.issuer_id) {
this.$message.success("添加成功");
this.activeName = "iosdeveloper";
this.editdeveloperinfo = {auth_type: 0};
@ -692,9 +606,6 @@
} else {
this.$message.error("操作失败")
}
if (this.codeactiveVisible) {
this.codeactiveVisible = false;
}
if (params.methods !== 'GET') {
this.loadingfun.close();
} else {

@ -1,4 +1,4 @@
# Generated by Django 3.0.3 on 2021-05-22 11:32
# Generated by Django 3.0.3 on 2021-05-27 13:55
from django.conf import settings
import django.contrib.auth.models
@ -64,20 +64,18 @@ class Migration(migrations.Migration):
name='AppIOSDeveloperInfo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(blank=True, max_length=64, null=True, verbose_name='email address')),
('password', models.CharField(max_length=64)),
('issuer_id', models.CharField(max_length=64, verbose_name='标识创建认证令牌的发放者')),
('private_key_id', models.CharField(max_length=64, verbose_name='密钥 ID')),
('p8key', models.TextField(max_length=512, verbose_name='p8key')),
('is_actived', models.BooleanField(default=False, verbose_name='是否已经激活')),
('certid', models.CharField(blank=True, max_length=64, null=True, verbose_name='超级签名自动创建证书ID')),
('usable_number', models.IntegerField(default=100, verbose_name='可使用设备数')),
('use_number', models.IntegerField(default=0, verbose_name='已消耗设备数')),
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('cert_expire_time', models.DateTimeField(blank=True, null=True, verbose_name='证书过期时间')),
('description', models.TextField(blank=True, default='', null=True, verbose_name='备注')),
('issuer_id', models.CharField(blank=True, max_length=64, null=True, verbose_name='标识创建认证令牌的发放者')),
('private_key_id', models.CharField(blank=True, max_length=64, null=True, verbose_name='密钥 ID')),
('p8key', models.TextField(blank=True, max_length=512, null=True, verbose_name='p8key')),
('auth_type',
models.SmallIntegerField(choices=[(0, 'p8key认证'), (1, '用户名密码认证')], default=0, verbose_name='认证类型')),
('auth_type', models.SmallIntegerField(choices=[(0, 'p8key认证')], default=0, verbose_name='认证类型')),
('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL,
verbose_name='用户ID')),
],
@ -102,9 +100,9 @@ class Migration(migrations.Migration):
('password', models.CharField(blank=True, help_text='默认 没有密码', max_length=32, verbose_name='访问密码')),
('isshow', models.BooleanField(default=True, verbose_name='下载页可见')),
('issupersign', models.BooleanField(default=False, verbose_name='是否超级签名包')),
('supersign_type',
models.SmallIntegerField(choices=[(0, '普通权限'), (1, '特殊权限(包含network、vpn)')], default=0,
verbose_name='签名类型')),
('supersign_type', models.SmallIntegerField(
choices=[(0, '普通权限'), (1, '推送权限,请上传adhoc包'), (2, 'network、vpn、推送权限,请上传adhoc包'), (3, '特殊权限')],
default=1, verbose_name='签名类型')),
('new_bundle_id', models.CharField(blank=True, help_text='用于超级签某些因素下需要修改包名', max_length=64, null=True,
verbose_name='new_bundle_id')),
('supersign_limit_number', models.IntegerField(default=0, verbose_name='签名使用限额')),
@ -130,12 +128,13 @@ class Migration(migrations.Migration):
('ip_address', models.CharField(max_length=128, verbose_name='域名解析地址')),
('is_enable', models.BooleanField(default=True, verbose_name='是否启用该解析')),
('is_system', models.BooleanField(default=False, verbose_name='是否是系统自带解析')),
('is_https', models.BooleanField(default=False, verbose_name='是否支持HTTPS')),
('description', models.TextField(blank=True, default='', null=True, verbose_name='备注')),
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
],
options={
'verbose_name': '分发域名信息',
'verbose_name_plural': '分发域名信息',
'verbose_name': '系统分发域名配置',
'verbose_name_plural': '系统分发域名配置',
},
),
migrations.CreateModel(
@ -171,8 +170,8 @@ class Migration(migrations.Migration):
verbose_name='用户ID')),
],
options={
'verbose_name': '分发域名绑定',
'verbose_name_plural': '分发域名绑定',
'verbose_name': '用户分发域名绑定',
'verbose_name_plural': '用户分发域名绑定',
},
),
migrations.CreateModel(
@ -188,7 +187,7 @@ class Migration(migrations.Migration):
verbose_name='认证状态')),
('msg', models.CharField(blank=True, max_length=512, null=True, verbose_name='备注')),
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('reviewed_time', models.DateTimeField(auto_now_add=True, verbose_name='审核时间')),
('reviewed_time', models.DateTimeField(auto_now=True, verbose_name='审核时间')),
('user_id',
models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='certification',
to=settings.AUTH_USER_MODEL, verbose_name='用户ID')),
@ -525,6 +524,6 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='appiosdeveloperinfo',
unique_together={('user_id', 'issuer_id'), ('user_id', 'email')},
unique_together={('user_id', 'issuer_id')},
),
]

@ -1,17 +0,0 @@
# Generated by Django 3.0.3 on 2021-05-22 21:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='domaincnameinfo',
name='is_https',
field=models.BooleanField(default=False, verbose_name='是否支持HTTPS'),
),
]

@ -1,27 +0,0 @@
# Generated by Django 3.0.3 on 2021-05-26 16:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0002_domaincnameinfo_is_https'),
]
operations = [
migrations.AlterModelOptions(
name='domaincnameinfo',
options={'verbose_name': '系统分发域名配置', 'verbose_name_plural': '系统分发域名配置'},
),
migrations.AlterModelOptions(
name='userdomaininfo',
options={'verbose_name': '用户分发域名绑定', 'verbose_name_plural': '用户分发域名绑定'},
),
migrations.AlterField(
model_name='apps',
name='supersign_type',
field=models.SmallIntegerField(
choices=[(0, '普通权限'), (1, '推送权限,请上传adhoc包'), (2, 'network、vpn、推送权限,请上传adhoc包'), (3, '特殊权限')], default=1,
verbose_name='签名类型'),
),
]

@ -242,42 +242,27 @@ class AppUDID(models.Model):
class AppIOSDeveloperInfo(models.Model):
user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE)
email = models.EmailField(
verbose_name='email address',
max_length=64,
blank=True,
null=True
)
password = models.CharField(max_length=64, )
issuer_id = models.CharField(max_length=64, null=False, verbose_name="标识创建认证令牌的发放者")
private_key_id = models.CharField(max_length=64, null=False, verbose_name="密钥 ID")
p8key = models.TextField(max_length=512, null=False, verbose_name="p8key")
is_actived = models.BooleanField(default=False, verbose_name="是否已经激活")
certid = models.CharField(max_length=64, blank=True, verbose_name="超级签名自动创建证书ID", null=True)
usable_number = models.IntegerField(verbose_name="可使用设备数", default=100)
use_number = models.IntegerField(verbose_name="已消耗设备数", default=0)
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
cert_expire_time = models.DateTimeField(blank=True, null=True, verbose_name="证书过期时间")
description = models.TextField('备注', blank=True, null=True, default='')
issuer_id = models.CharField(max_length=64, blank=True, null=True, verbose_name="标识创建认证令牌的发放者")
private_key_id = models.CharField(max_length=64, blank=True, null=True, verbose_name="密钥 ID")
p8key = models.TextField(max_length=512, blank=True, null=True, verbose_name="p8key")
auth_type_choices = ((0, 'p8key认证'), (1, '用户名密码认证'))
auth_type_choices = ((0, 'p8key认证'),)
auth_type = models.SmallIntegerField(choices=auth_type_choices, default=0, verbose_name="认证类型")
class Meta:
verbose_name = '苹果开发者账户'
verbose_name_plural = "苹果开发者账户"
unique_together = (('user_id', 'email',), ('user_id', 'issuer_id'))
def save(self, *args, **kwargs):
if self.auth_type == 0:
if self.issuer_id and self.private_key_id and self.p8key:
return super(AppIOSDeveloperInfo, self).save(*args, **kwargs)
if self.auth_type == 1:
if self.email and self.password:
return super(AppIOSDeveloperInfo, self).save(*args, **kwargs)
raise
unique_together = (('user_id', 'issuer_id'),)
def __str__(self):
return "%s-%s" % (self.user_id, self.email)
return "%s-%s" % (self.user_id, self.issuer_id)
class APPSuperSignUsedInfo(models.Model):
@ -421,7 +406,7 @@ class UserCertificationInfo(models.Model):
status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="认证状态")
msg = models.CharField(max_length=512, null=True, blank=True, verbose_name="备注")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
reviewed_time = models.DateTimeField(auto_now_add=True, verbose_name="审核时间")
reviewed_time = models.DateTimeField(auto_now=True, verbose_name="审核时间")
class Meta:
verbose_name = '用户认证信息'

@ -5,7 +5,7 @@
# date: 2020/4/24
import OpenSSL
from api.utils.app.shellcmds import shell_command, use_user_pass, pshell_command
from api.utils.app.shellcmds import shell_command, use_user_pass
from fir_ser.settings import SUPER_SIGN_ROOT
import os
from api.utils.app.randomstrings import make_app_uuid
@ -33,88 +33,17 @@ def exec_shell(cmd, remote=False, timeout=None):
if result.get("exit_code") != 0:
err_info = result.get("err_info", None)
if err_info:
if "have access to this membership resource. Contact your team" in err_info:
result["err_info"] = "You currently don't have access to this membership resource 【您没有权限执行该操作】"
elif "Maximum number of certificates generated" in err_info:
result["err_info"] = "Maximum number of certificates generated 【开发证书数量到上限】"
else:
result["err_info"] = "Unknown Error"
logger.error("exec_shell cmd:%s failed: %s" % (cmd, err_info))
result["err_info"] = "Unknown Error"
return False, result
return True, result
class AppDeveloperApi(object):
def __init__(self, username, password, certid):
self.username = username
self.password = password
self.certid = certid
script_path = os.path.join(SUPER_SIGN_ROOT, 'scripts', 'apple_api.rb')
self.cmd = "ruby %s '%s' '%s'" % (script_path, self.username, self.password)
def active(self, user_obj):
self.cmd = self.cmd + " active "
logger.info("ios developer active cmd:%s" % (self.cmd))
result = {}
try:
result = pshell_command(self.cmd, user_obj, self.username)
logger.info("ios developer active cmd:%s result:%s" % (self.cmd, result))
if result["exit_code"] == 0:
return True, result
except Exception as e:
logger.error("ios developer active cmd:%s Failed Exception:%s" % (self.cmd, e))
return False, result
def file_format_path_name(self, user_obj):
cert_dir_name = make_app_uuid(user_obj, self.username)
cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name)
if not os.path.isdir(cert_dir_path):
os.makedirs(cert_dir_path)
return os.path.join(cert_dir_path, cert_dir_name)
def create_cert(self, user_obj):
self.cmd = self.cmd + " cert add '%s'" % (self.file_format_path_name(user_obj))
return exec_shell(self.cmd)
def get_profile(self, bundleId, app_id, device_udid, device_name, provisionName, auth=None, first_sign=None,
device_id_list=None):
self.cmd = self.cmd + " profile add '%s' '%s' '%s' '%s' '%s' '%s'" % (
bundleId, app_id, device_udid, device_name, self.certid, provisionName)
return exec_shell(self.cmd)
def del_profile(self, bundleId, app_id):
self.cmd = self.cmd + " profile del '%s' '%s'" % (bundleId, app_id)
result = exec_shell(self.cmd)
def set_device_status(self, status, device_udid):
if status == "enable":
self.cmd = self.cmd + " device enable '%s'" % (device_udid)
else:
self.cmd = self.cmd + " device disable '%s'" % (device_udid)
result = exec_shell(self.cmd)
def add_device(self, device_udid, device_name):
self.cmd = self.cmd + " device add '%s' '%s'" % (device_udid, device_name)
result = exec_shell(self.cmd)
def get_device(self, user_obj):
self.cmd = self.cmd + " device get '%s' " % (self.file_format_path_name(user_obj))
return exec_shell(self.cmd)
def create_app(self, bundleId, app_id):
self.cmd = self.cmd + " app add '%s' '%s'" % (bundleId, app_id)
result = exec_shell(self.cmd)
def del_app(self, bundleId, app_id):
self.cmd = self.cmd + " app del '%s' '%s'" % (bundleId, app_id)
result = exec_shell(self.cmd)
class ResignApp(object):
def __init__(self, my_local_key, app_dev_pem):
self.my_local_key = my_local_key
self.app_dev_pem = app_dev_pem
# script_path=os.path.join(SUPER_SIGN_ROOT,'scripts','apple_api.rb')
self.cmd = "isign -c '%s' -k '%s' " % (self.app_dev_pem, self.my_local_key)
@staticmethod
@ -143,11 +72,12 @@ class AppDeveloperApiV2(object):
self.p8key = p8key
self.certid = certid
def active(self, user_obj):
def active(self):
result = {}
try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
certificates = apple_obj.get_all_certificates()
result['data'] = certificates
logger.info("ios developer active result:%s" % certificates)
if len(certificates) > 0:
return True, result
@ -222,9 +152,7 @@ class AppDeveloperApiV2(object):
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
if developer_app_id:
pass
# bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundleId + app_id)
else:
# bundle_obj = apple_obj.list_bundle_ids_by_identifier(bundleId + app_id)
if s_type == 0:
bundle_obj = apple_obj.register_bundle_id(app_id, bundle_id + app_id)
else:
@ -254,7 +182,7 @@ class AppDeveloperApiV2(object):
result['return_info'] = "%s" % e
return False, result
def del_profile(self, bundleId, app_id):
def del_profile(self, app_id):
result = {}
try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
@ -283,7 +211,7 @@ class AppDeveloperApiV2(object):
result['return_info'] = "%s" % e
return False, result
def get_device(self, user_obj):
def get_device(self):
result = {}
try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)

@ -8,8 +8,9 @@ from subprocess import Popen, PIPE
import logging
import paramiko, json
import socket
import pexpect
from api.utils.storage.caches import developer_auth_code
# import pexpect
# from api.utils.storage.caches import developer_auth_code
logger = logging.getLogger(__file__)
@ -88,55 +89,55 @@ class SSHConnection(object):
self._client.close()
def pshell_command(cmdstrs, user_obj, developer_email, timeout=60 * 10):
result = default_result()
run = pexpect.spawn(cmdstrs, encoding='utf-8')
try:
index = run.expect(
["Two-factor Authentication", "Invalid username and password combination", pexpect.EOF, pexpect.TIMEOUT],
timeout=timeout)
if index == 0:
count = 1
if timeout == -1:
timeout = 60 * 60 * 24
while True and count < timeout / 3:
code = developer_auth_code("get", user_obj, developer_email)
if code:
run.sendline(code)
try:
err = run.expect(["Unauthorized Access", pexpect.EOF, pexpect.TIMEOUT])
if err == 0:
result['exit_code'] = 2
result['return_info'] = 'Unauthorized Access 【验证码有误】'
elif err == 1:
result['exit_code'] = 0
result['return_info'] = 'Verify Code Success'
else:
result['exit_code'] = 3
result['return_info'] = 'Verify Code TimeOut or UnKnown Error 【双重验证未知错误】'
developer_auth_code("del", user_obj, developer_email)
return result
except Exception as e:
logger.error("cmdstrs:%s developer_email:%s user_obj:%s Exception:%s" % (
cmdstrs, developer_email, user_obj, e))
developer_auth_code("del", user_obj, developer_email)
result['exit_code'] = 0
result['return_info'] = 'Success'
return result
count += 1
time.sleep(3)
elif index == 1:
result['exit_code'] = 1
result['return_info'] = 'Invalid username and password combination 【密码或者账号有误】'
elif index == 2:
result['exit_code'] = 0
result['return_info'] = 'Alreay Success'
else:
result['exit_code'] = 4
result['return_info'] = 'Code TimeOut or UnKnown Error 【验证超时】'
except Exception as e:
logger.error("cmdstrs:%s developer_email:%s user_obj:%s Exception:%s" % (cmdstrs, developer_email, user_obj, e))
return result
# def pshell_command(cmdstrs, user_obj, developer_email, timeout=60 * 10):
# result = default_result()
# run = pexpect.spawn(cmdstrs, encoding='utf-8')
# try:
# index = run.expect(
# ["Two-factor Authentication", "Invalid username and password combination", pexpect.EOF, pexpect.TIMEOUT],
# timeout=timeout)
# if index == 0:
# count = 1
# if timeout == -1:
# timeout = 60 * 60 * 24
# while True and count < timeout / 3:
# code = developer_auth_code("get", user_obj, developer_email)
# if code:
# run.sendline(code)
# try:
# err = run.expect(["Unauthorized Access", pexpect.EOF, pexpect.TIMEOUT])
# if err == 0:
# result['exit_code'] = 2
# result['return_info'] = 'Unauthorized Access 【验证码有误】'
# elif err == 1:
# result['exit_code'] = 0
# result['return_info'] = 'Verify Code Success'
# else:
# result['exit_code'] = 3
# result['return_info'] = 'Verify Code TimeOut or UnKnown Error 【双重验证未知错误】'
# developer_auth_code("del", user_obj, developer_email)
# return result
# except Exception as e:
# logger.error("cmdstrs:%s developer_email:%s user_obj:%s Exception:%s" % (
# cmdstrs, developer_email, user_obj, e))
# developer_auth_code("del", user_obj, developer_email)
# result['exit_code'] = 0
# result['return_info'] = 'Success'
# return result
# count += 1
# time.sleep(3)
# elif index == 1:
# result['exit_code'] = 1
# result['return_info'] = 'Invalid username and password combination 【密码或者账号有误】'
# elif index == 2:
# result['exit_code'] = 0
# result['return_info'] = 'Alreay Success'
# else:
# result['exit_code'] = 4
# result['return_info'] = 'Code TimeOut or UnKnown Error 【验证超时】'
# except Exception as e:
# logger.error("cmdstrs:%s developer_email:%s user_obj:%s Exception:%s" % (cmdstrs, developer_email, user_obj, e))
# return result
def shell_command(cmdstrs, timeout):

@ -6,7 +6,7 @@
import uuid, xmltodict, os, re, logging, time
from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, SERVER_DOMAIN, MOBILECONFIG_SIGN_SSL
from api.utils.app.iossignapi import AppDeveloperApi, ResignApp, AppDeveloperApiV2
from api.utils.app.iossignapi import ResignApp, AppDeveloperApiV2
from api.models import APPSuperSignUsedInfo, AppUDID, AppIOSDeveloperInfo, AppReleaseInfo, Apps, APPToDeveloper, \
UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID
from api.utils.app.randomstrings import make_app_uuid, make_from_user_uuid
@ -14,7 +14,7 @@ from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_
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 api.utils.baseutils import file_format_path, delete_app_profile_file, get_profile_full_path, get_user_domain_name, \
get_user_default_domain_name, get_min_default_domain_cname_obj
get_user_default_domain_name, get_min_default_domain_cname_obj, format_apple_date
from api.utils.storage.storage import Storage
from django.core.cache import cache
@ -157,14 +157,7 @@ def get_post_udid_url(request, short):
def get_auth_form_developer(developer_obj):
if developer_obj.email:
auth = {
"username": developer_obj.email,
"password": developer_obj.password,
"certid": developer_obj.certid
}
elif developer_obj.issuer_id:
if developer_obj.issuer_id:
auth = {
"issuer_id": developer_obj.issuer_id,
"private_key_id": developer_obj.private_key_id,
@ -177,9 +170,7 @@ def get_auth_form_developer(developer_obj):
def get_api_obj(auth):
if auth.get("username"):
app_api_obj = AppDeveloperApi(**auth)
elif auth.get("issuer_id"):
if auth.get("issuer_id"):
app_api_obj = AppDeveloperApiV2(**auth)
else:
app_api_obj = None
@ -187,7 +178,7 @@ def get_api_obj(auth):
def get_apple_udid_key(auth):
mpkey = auth.get("username")
mpkey = ''
if auth.get("issuer_id"):
mpkey = auth.get("issuer_id")
return mpkey
@ -267,9 +258,8 @@ class IosUtils(object):
if developer_udid_obj:
developer_obj = developer_udid_obj.developerid
else:
for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj,
is_actived=True, certid__isnull=False).order_by(
"created_time"):
for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True,
certid__isnull=False).order_by("created_time"):
usable_number = developer_obj.usable_number
flyapp_used = get_developer_udided(developer_obj)[1]
if flyapp_used < usable_number:
@ -283,11 +273,11 @@ class IosUtils(object):
self.auth, developer_app_id, device_id_list)
# 开启超级签直接在开发者账户创建
def create_app(self, app_obj):
bundleId = self.app_obj.bundle_id
app_id = self.app_obj.app_id
s_type = self.app_obj.supersign_type
return get_api_obj(self.auth).create_app(bundleId, app_id, s_type)
# def create_app(self, app_obj):
# bundleId = self.app_obj.bundle_id
# app_id = self.app_obj.app_id
# s_type = self.app_obj.supersign_type
# return get_api_obj(self.auth).create_app(bundleId, app_id, s_type)
@staticmethod
def modify_capability(developer_obj, app_obj, developer_app_id):
@ -537,7 +527,7 @@ class IosUtils(object):
if APPSuperSignUsedInfo.objects.filter(developerid=developer_obj, app_id_id=app_id).count() == 0:
app_api_obj = get_api_obj(auth)
app_obj = Apps.objects.filter(pk=app_id).first()
app_api_obj.del_profile(app_obj.bundle_id, app_obj.app_id)
app_api_obj.del_profile(app_obj.app_id)
app_api_obj2 = get_api_obj(auth)
app_api_obj2.del_app(app_obj.bundle_id, app_obj.app_id)
DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete()
@ -597,7 +587,7 @@ class IosUtils(object):
auth = get_auth_form_developer(developer_obj)
DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete()
app_api_obj = get_api_obj(auth)
app_api_obj.del_profile(app_obj.bundle_id, app_obj.app_id)
app_api_obj.del_profile(app_obj.app_id)
app_api_obj2 = get_api_obj(auth)
app_api_obj2.del_app(app_obj.bundle_id, app_obj.app_id)
@ -626,7 +616,7 @@ class IosUtils(object):
developer_obj, user_obj, e))
@staticmethod
def active_developer(developer_obj, user_obj):
def active_developer(developer_obj):
'''
激活开发者账户
:param developer_obj:
@ -635,8 +625,12 @@ class IosUtils(object):
'''
auth = get_auth_form_developer(developer_obj)
app_api_obj = get_api_obj(auth)
status, result = app_api_obj.active(user_obj)
status, result = app_api_obj.active()
if status:
for cert_obj in result.get('data', []):
if cert_obj.id == developer_obj.certid:
developer_obj.cert_expire_time = format_apple_date(cert_obj.expirationDate)
break
developer_obj.is_actived = True
developer_obj.save()
return status, result
@ -651,30 +645,14 @@ class IosUtils(object):
cert_id = result.id
AppIOSDeveloperInfo.objects.filter(user_id=user_obj, issuer_id=auth.get("issuer_id")).update(
is_actived=True,
certid=cert_id)
else:
file_format_path_name = file_format_path(user_obj, auth)
cert_info = None
try:
with open(file_format_path_name + '.info', "r") as f:
cert_info = f.read()
except Exception as e:
logger.error(
"create_developer_cert developer_obj:%s user_obj:%s delete file failed Exception:%s" % (
developer_obj, user_obj, e))
if cert_info:
cert_id = re.findall(r'.*\n\tid=(.*),.*', cert_info)[0].replace('"', '')
AppIOSDeveloperInfo.objects.filter(user_id=user_obj, email=auth.get("username")).update(
is_actived=True,
certid=cert_id)
certid=cert_id, cert_expire_time=format_apple_date(result.expirationDate))
return status, result
@staticmethod
def get_device_from_developer(developer_obj, user_obj):
auth = get_auth_form_developer(developer_obj)
app_api_obj = get_api_obj(auth)
status, result = app_api_obj.get_device(user_obj)
status, result = app_api_obj.get_device()
if status:
if auth.get("issuer_id"):
UDIDsyncDeveloper.objects.filter(developerid=developer_obj, platform=1).delete()

@ -7,7 +7,8 @@
import os, re, time
from django.db.models import Count
import datetime
from django.utils import timezone
from fir_ser.settings import SUPER_SIGN_ROOT
from api.models import AppReleaseInfo, UserDomainInfo, DomainCnameInfo
from api.utils.app.randomstrings import make_app_uuid
@ -27,14 +28,8 @@ def get_app_d_count_by_app_id(app_id):
return d_count
def file_format_path(user_obj, auth=None, email=None):
if email:
cert_dir_name = make_app_uuid(user_obj, email)
else:
pkey = auth.get("username")
if auth.get("issuer_id"):
pkey = auth.get("issuer_id")
cert_dir_name = make_app_uuid(user_obj, pkey)
def file_format_path(user_obj, auth=None):
cert_dir_name = make_app_uuid(user_obj, auth.get("issuer_id"))
cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name)
if not os.path.isdir(cert_dir_path):
os.makedirs(cert_dir_path)
@ -43,10 +38,7 @@ def file_format_path(user_obj, auth=None, email=None):
def get_profile_full_path(developer_obj, app_obj):
pkey = developer_obj.email
if developer_obj.issuer_id:
pkey = developer_obj.issuer_id
cert_dir_name = make_app_uuid(developer_obj.user_id, pkey)
cert_dir_name = make_app_uuid(developer_obj.user_id, developer_obj.issuer_id)
cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name, "profile")
provision_name = os.path.join(cert_dir_path, app_obj.app_id)
return provision_name + '.mobileprovision'
@ -152,3 +144,10 @@ def get_user_default_domain_name(domain_cname_obj):
def get_min_default_domain_cname_obj(is_system=True):
return min(DomainCnameInfo.objects.annotate(Count('userdomaininfo')).filter(is_enable=True, is_system=is_system),
key=lambda x: x.userdomaininfo__count)
def format_apple_date(s_date):
f_date = datetime.datetime.strptime(s_date, '%Y-%m-%dT%H:%M:%S.000+0000')
if not timezone.is_naive(f_date):
f_date = timezone.make_naive(f_date, timezone.utc)
return f_date

@ -76,7 +76,7 @@ def auto_check_ios_developer_active():
for ios_developer in all_ios_developer:
userinfo = ios_developer.user_id
if userinfo.supersign_active:
status, result = IosUtils.active_developer(ios_developer, userinfo)
status, result = IosUtils.active_developer(ios_developer)
msg = "auto_check_ios_developer_active user:%s ios.developer:%s status:%s result:%s" % (
ios_developer.user_id, ios_developer, status, result)
if status:

@ -4,13 +4,10 @@
# author: liuyu
# date: 2020/3/23
from api.models import UserInfo
from .aliyunApi import AliMsgSender
from .emailApi import EmailMsgSender
from .jiguangApi import JiGuangMsgSender
import json, time, base64
from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE
from django.core.cache import cache
from fir_ser.settings import THIRD_PART_CONFIG
import logging
logger = logging.getLogger(__file__)

@ -7,7 +7,7 @@ from api.utils.baseutils import get_user_domain_name, get_app_domain_name
from api.utils.storage.storage import Storage
from api.utils.utils import get_developer_udided, get_choices_dict, get_choices_name_from_key
from api.utils.storage.caches import get_user_free_download_times, get_user_cert_auth_status
import os, json, logging
import os, logging
logger = logging.getLogger(__file__)
@ -393,7 +393,7 @@ class DeveloperSerializer(serializers.ModelSerializer):
class Meta:
model = models.AppIOSDeveloperInfo
# depth = 1
exclude = ["password", "id", "user_id", "p8key"]
exclude = ["id", "user_id", "p8key"]
developer_used_number = serializers.SerializerMethodField()
developer_used_other_number = serializers.SerializerMethodField()
@ -408,7 +408,6 @@ class DeveloperSerializer(serializers.ModelSerializer):
class SuperSignUsedSerializer(serializers.ModelSerializer):
class Meta:
model = models.APPSuperSignUsedInfo
# depth = 1
fields = ["created_time", "device_udid", "device_name", "developer_id", "bundle_id", "bundle_name"]
device_udid = serializers.SerializerMethodField()
@ -424,10 +423,7 @@ class SuperSignUsedSerializer(serializers.ModelSerializer):
return obj.udid.product
def get_developer_id(self, obj):
developer_id = obj.developerid.email
if obj.developerid.issuer_id:
developer_id = obj.developerid.issuer_id
return developer_id
return obj.developerid.issuer_id
def get_bundle_id(self, obj):
return obj.app_id.bundle_id

@ -12,7 +12,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, file_format_path, get_app_domain_name
from api.utils.baseutils import get_app_d_count_by_app_id, get_app_domain_name # file_format_path,
import logging
from django.db.models import F
@ -229,16 +229,16 @@ def get_app_today_download_times(app_ids):
return download_times_count
def developer_auth_code(act, user_obj, developer_email, code=None):
auth_key = file_format_path(user_obj, email=developer_email)
key = "_".join([CACHE_KEY_TEMPLATE.get("developer_auth_code_key"), auth_key])
if act == "set":
cache.delete(key)
cache.set(key, code, 60 * 10)
elif act == "get":
return cache.get(key)
elif act == "del":
cache.delete(key)
# def developer_auth_code(act, user_obj, developer_issuer_id, code=None):
# auth_key = file_format_path(user_obj, email=developer_issuer_id)
# key = "_".join([CACHE_KEY_TEMPLATE.get("developer_auth_code_key"), auth_key])
# if act == "set":
# cache.delete(key)
# cache.set(key, code, 60 * 10)
# elif act == "get":
# return cache.get(key)
# elif act == "del":
# cache.delete(key)
def upload_file_tmp_name(act, filename, user_obj_id):

@ -26,9 +26,8 @@ class IosUDIDView(View):
status = True
try:
app_info = Apps.objects.filter(short=short).first()
if app_info:
server_domain = get_redirect_server_domain(request, None, get_app_domain_name(app_info))
server_domain = get_redirect_server_domain(request, app_info.user_id, get_app_domain_name(app_info))
if app_info.issupersign and app_info.user_id.supersign_active:
ios_obj = IosUtils(format_udid_info, app_info.user_id, app_info)
status, msg = ios_obj.sign()

@ -13,7 +13,6 @@ from api.utils.serializer import DeveloperSerializer, SuperSignUsedSerializer, D
from rest_framework.pagination import PageNumberPagination
from api.utils.app.supersignutils import IosUtils
from api.utils.utils import get_developer_devices, get_choices_dict
from api.utils.storage.caches import developer_auth_code
import logging
logger = logging.getLogger(__file__)
@ -38,9 +37,7 @@ class DeveloperView(APIView):
developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user)
res.use_num = get_developer_devices(developer_obj)
if appid:
developer_obj1 = developer_obj.filter(email=appid)
developer_obj2 = developer_obj.filter(issuer_id=appid)
developer_obj = developer_obj1 | developer_obj2
developer_obj = developer_obj.filter(issuer_id=appid)
page_obj = PageNumber()
app_page_serializer = page_obj.paginate_queryset(queryset=developer_obj.order_by("-updated_time"),
@ -56,11 +53,8 @@ class DeveloperView(APIView):
def put(self, request):
data = request.data
email = data.get("email", None)
issuer_id = data.get("issuer_id", None)
if email:
developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user, email=email).first()
elif issuer_id:
if issuer_id:
developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user, issuer_id=issuer_id).first()
else:
return self.get(request)
@ -71,33 +65,15 @@ class DeveloperView(APIView):
res = BaseResponse()
logger.info("user %s iosdeveloper %s act %s" % (request.user, developer_obj, act))
if act == "preactive":
if developer_obj.email:
developer_auth_code("del", request.user, developer_obj.email)
elif developer_obj.issuer_id:
developer_auth_code("del", request.user, developer_obj.issuer_id)
status, result = IosUtils.active_developer(developer_obj, request.user)
status, result = IosUtils.active_developer(developer_obj)
if status:
if not developer_obj.certid:
if developer_obj.email:
status, result = IosUtils.create_developer_cert(developer_obj, request.user)
elif developer_obj.issuer_id:
return Response(res.dict)
if status:
IosUtils.get_device_from_developer(developer_obj, request.user)
else:
res.code = 1008
res.msg = result.get("err_info")
return Response(res.dict)
IosUtils.get_device_from_developer(developer_obj, request.user)
return self.get(request)
else:
res.code = 1008
res.msg = result.get("return_info", "未知错误")
return Response(res.dict)
elif act == "nowactive":
code = data.get("code", None)
if code:
developer_auth_code("set", request.user, developer_obj.email, code)
elif act == "ioscert":
if not developer_obj.certid:
@ -110,18 +86,12 @@ class DeveloperView(APIView):
return Response(res.dict)
elif act == "syncdevice":
status, result = IosUtils.get_device_from_developer(developer_obj, request.user)
if status:
IosUtils.get_device_from_developer(developer_obj, request.user)
else:
if not status:
res.code = 1008
res.msg = result.get("err_info")
return Response(res.dict)
elif act == "checkauth":
if developer_obj.email:
developer_auth_code("del", request.user, developer_obj.email)
elif developer_obj.issuer_id:
developer_auth_code("del", request.user, developer_obj.issuer_id)
status, result = IosUtils.active_developer(developer_obj, request.user)
status, result = IosUtils.active_developer(developer_obj)
if status:
return self.get(request)
else:
@ -140,10 +110,6 @@ class DeveloperView(APIView):
logger.error("developer %s usable_number %s get failed Exception:%s" % (
developer_obj, data.get("usable_number", developer_obj.usable_number), e))
developer_obj.description = data.get("description", developer_obj.description)
password = data.get("password", developer_obj.password)
if password != "" and password != developer_obj.password:
developer_obj.password = password
developer_obj.is_actived = False
private_key_id = data.get("private_key_id", developer_obj.private_key_id)
p8key = data.get("p8key", developer_obj.p8key)
if private_key_id != "" and private_key_id != developer_obj.private_key_id:
@ -164,6 +130,7 @@ class DeveloperView(APIView):
def post(self, request):
data = request.data
datainfo = {}
if data.get("auth_type") == 0:
datainfo = {
"usable_number": data.get("usable_number", ""),
@ -173,17 +140,9 @@ class DeveloperView(APIView):
"p8key": data.get("p8key", ""),
"auth_type": 0
}
else:
datainfo = {
"usable_number": data.get("usable_number", ""),
"description": data.get("description", ""),
"password": data.get("password", ""),
"email": data.get("email", ""),
"auth_type": 1
}
try:
logger.error("user %s add new developer %s data %s" % (
request.user, data.get("email", ""), datainfo))
request.user, data.get("issuer_id", ""), datainfo))
AppIOSDeveloperInfo.objects.create(user_id=request.user, **datainfo)
except Exception as e:
logger.error("user %s create developer %s failed Exception:%s" % (
@ -196,11 +155,8 @@ class DeveloperView(APIView):
return self.get(request)
def delete(self, request):
email = request.query_params.get("email", None)
issuer_id = request.query_params.get("issuer_id", None)
if email:
developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user, email=email).first()
elif issuer_id:
if issuer_id:
developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user, issuer_id=issuer_id).first()
else:
return self.get(request)
@ -228,7 +184,7 @@ class SuperSignUsedView(APIView):
SuperSignUsed_obj = APPSuperSignUsedInfo.objects.filter(user_id=request.user, )
if developerid:
SuperSignUsed_obj = SuperSignUsed_obj.filter(developerid__email=developerid)
SuperSignUsed_obj = SuperSignUsed_obj.filter(developerid__issuer_id=developerid)
if udid:
SuperSignUsed_obj = SuperSignUsed_obj.filter(udid__udid=udid)
if bundleid:

@ -5,6 +5,7 @@
# date: 2020/3/6
from api.utils.app.apputils import get_random_short, SaveAppInfos
from api.utils.baseutils import get_app_domain_name
from api.utils.storage.storage import Storage
from api.utils.storage.caches import upload_file_tmp_name, del_cache_response_by_short
from api.models import Apps, AppReleaseInfo, UserInfo, AppScreenShot, CertificationInfo
@ -49,10 +50,12 @@ class AppAnalyseView(APIView):
is_new = False
short = app_obj.short
app_release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first()
short_domain_name = get_redirect_server_domain(request, request.user, get_app_domain_name(app_obj))
if app_release_obj:
binary_url = app_release_obj.binary_url
else:
is_new = True
short_domain_name = get_redirect_server_domain(request, request.user)
short = get_random_short()
if app_type == 'iOS':
upload_key = release_id + '.ipa' + settings.FILE_UPLOAD_TMP_KEY
@ -74,7 +77,7 @@ class AppAnalyseView(APIView):
upload_file_tmp_name("set", png_key, request.user.id)
upload_file_tmp_name("set", upload_key, request.user.id)
res.data = {"app_uuid": app_uuid, "short": short,
"short_domain_name": get_redirect_server_domain(request, request.user),
"short_domain_name": short_domain_name,
"upload_token": upload_token,
"upload_key": upload_key,
"png_token": png_token,

Loading…
Cancel
Save