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

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> </el-form-item>
</div> </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-form-item label-width="110px" label="设备数量">
<el-input v-model="editdeveloperinfo.usable_number"/> <el-input v-model="editdeveloperinfo.usable_number"/>
</el-form-item> </el-form-item>
@ -58,32 +48,13 @@
</el-form> </el-form>
</el-dialog> </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-tabs v-model="activeName" type="border-card" @tab-click="handleClick" tab-position="top">
<el-tab-pane label="开发者账户" name="iosdeveloper"> <el-tab-pane label="开发者账户" name="iosdeveloper">
<el-input <el-input
style="width: 30%;margin-right: 30px;margin-bottom: 10px" style="width: 30%;margin-right: 30px;margin-bottom: 10px"
v-model="appidseach" v-model="appidseach"
clearable clearable
placeholder="输入用户APPID"/> placeholder="输入用户ID"/>
<el-button type="primary" icon="el-icon-search" @click="handleCurrentChange(pagination.currentPage)"> <el-button type="primary" icon="el-icon-search" @click="handleCurrentChange(pagination.currentPage)">
搜索 搜索
</el-button> </el-button>
@ -108,8 +79,8 @@
<el-table-column <el-table-column
fixed fixed
prop="email" prop="issuer_id"
label="用户" label="用户 issuer_id"
width="300"> width="300">
<template slot-scope="scope"> <template slot-scope="scope">
<el-popover trigger="hover" placement="top"> <el-popover trigger="hover" placement="top">
@ -120,9 +91,6 @@
?scope.row.usable_number-scope.row.developer_used_number :0 }}</p> ?scope.row.usable_number-scope.row.developer_used_number :0 }}</p>
<div slot="reference" class="name-wrapper"> <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"/> {{ <el-tag size="medium" v-if="scope.row.issuer_id"><i class="el-icon-key"/> {{
scope.row.issuer_id }} scope.row.issuer_id }}
</el-tag> </el-tag>
@ -194,8 +162,8 @@
<el-table-column <el-table-column
:formatter="formatter" :formatter="formatter"
prop="updated_time" prop="cert_expire_time"
label="更新时间" label="证书到期时间"
width="160"> width="160">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -251,17 +219,6 @@
</el-form-item> </el-form-item>
</div> </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-form-item label-width="110px" label="设备数量">
<el-input v-model="editdeveloperinfo.usable_number"/> <el-input v-model="editdeveloperinfo.usable_number"/>
</el-form-item> </el-form-item>
@ -291,7 +248,7 @@
style="width: 23%;margin-right: 30px;margin-bottom: 10px" style="width: 23%;margin-right: 30px;margin-bottom: 10px"
v-model="appidseach" v-model="appidseach"
clearable clearable
placeholder="输入用户APPID"/> placeholder="输入用户ID"/>
<el-button type="primary" icon="el-icon-search" @click="handleCurrentChange(pagination.currentPage)"> <el-button type="primary" icon="el-icon-search" @click="handleCurrentChange(pagination.currentPage)">
搜索 搜索
</el-button> </el-button>
@ -438,7 +395,7 @@
<script> <script>
import {iosdeveloper, iosdevices, iosdevicesudid} from "@/restful"; import {iosdeveloper, iosdevices, iosdevicesudid} from "@/restful";
import {getUserInfoFun, IsNum, removeAaary} from "@/utils"; import {getUserInfoFun, removeAaary} from "@/utils";
export default { export default {
name: "FirSuperSignBase", name: "FirSuperSignBase",
@ -456,12 +413,9 @@
editdeveloperinfo: {auth_type: 0}, editdeveloperinfo: {auth_type: 0},
isedit: false, isedit: false,
placeholder: "", placeholder: "",
codeactiveVisible: false,
pagination: {"currentPage": 1, "total": 0, "pagesize": 10}, pagination: {"currentPage": 1, "total": 0, "pagesize": 10},
developer_used_info: {"all_usable_number": 0, "other_used_sum": 0, "all_use_number": 0}, developer_used_info: {"all_usable_number": 0, "other_used_sum": 0, "all_use_number": 0},
percentage: 0, percentage: 0,
authcode: "",
authemail: "",
apple_auth_list: [], apple_auth_list: [],
apple_auth_type: 0, apple_auth_type: 0,
loadingfun: {}, loadingfun: {},
@ -504,46 +458,19 @@
}) })
}, },
syncdevices() { 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({ this.iosdeveloperFun({
"methods": "PUT", "methods": "PUT",
"data": data "data": {"issuer_id": this.editdeveloperinfo.issuer_id, "act": "syncdevice"}
}); });
}, },
isocertcert() { 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({ this.iosdeveloperFun({
"methods": "PUT", "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) { activedeveloperFun(developer, act) {
if (developer.email) { this.iosdeveloperFun({"methods": "PUT", "data": {"issuer_id": developer.issuer_id, "act": act}});
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)
}, },
canceledit() { canceledit() {
this.dialogaddDeveloperVisible = false; this.dialogaddDeveloperVisible = false;
@ -562,14 +489,7 @@
if (this.isedit) { if (this.isedit) {
this.iosdeveloperFun({"methods": "PUT", "data": this.editdeveloperinfo}) this.iosdeveloperFun({"methods": "PUT", "data": this.editdeveloperinfo})
} else { } else {
if (this.editdeveloperinfo.auth_type === 0) {
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.issuer_id && this.editdeveloperinfo.private_key_id && this.editdeveloperinfo.usable_number && this.editdeveloperinfo.p8key) { if (this.editdeveloperinfo.issuer_id && this.editdeveloperinfo.private_key_id && this.editdeveloperinfo.usable_number && this.editdeveloperinfo.p8key) {
this.iosdeveloperFun({"methods": "POST", "data": this.editdeveloperinfo}); this.iosdeveloperFun({"methods": "POST", "data": this.editdeveloperinfo});
} else { } else {
@ -582,18 +502,12 @@
} }
}, },
handleDeleteDeveloper(developer_info) { handleDeleteDeveloper(developer_info) {
this.$confirm('此操作会删除该苹果开发者账户下面的生成的证书等数据,可能会导致超级签包的闪退, 是否继续?', '警告', { this.$confirm('此操作会删除该苹果开发者账户下面的生成的证书等数据,可能会导致超级签包的闪退, 是否继续?', '警告', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
let data = {"email": developer_info.email}; this.iosdeveloperFun({"methods": "DELETE", "data": {"issuer_id": developer_info.issuer_id}});
if (developer_info.issuer_id) {
data = {"issuer_id": developer_info.issuer_id};
}
this.iosdeveloperFun({"methods": "DELETE", "data": data});
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'info', type: 'info',
@ -634,7 +548,7 @@
}, },
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
formatter(row, column) { formatter(row, column) {
let stime = row.updated_time; let stime = row.cert_expire_time;
if (stime) { if (stime) {
stime = stime.split(".")[0].split("T"); stime = stime.split(".")[0].split("T");
return stime[0] + " " + stime[1] return stime[0] + " " + stime[1]
@ -682,7 +596,7 @@
this.activeName = "iosdeveloper"; this.activeName = "iosdeveloper";
this.editdeveloperinfo = {auth_type: 0}; 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.$message.success("添加成功");
this.activeName = "iosdeveloper"; this.activeName = "iosdeveloper";
this.editdeveloperinfo = {auth_type: 0}; this.editdeveloperinfo = {auth_type: 0};
@ -692,9 +606,6 @@
} else { } else {
this.$message.error("操作失败") this.$message.error("操作失败")
} }
if (this.codeactiveVisible) {
this.codeactiveVisible = false;
}
if (params.methods !== 'GET') { if (params.methods !== 'GET') {
this.loadingfun.close(); this.loadingfun.close();
} else { } 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 from django.conf import settings
import django.contrib.auth.models import django.contrib.auth.models
@ -64,20 +64,18 @@ class Migration(migrations.Migration):
name='AppIOSDeveloperInfo', name='AppIOSDeveloperInfo',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('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')), ('issuer_id', models.CharField(max_length=64, verbose_name='标识创建认证令牌的发放者')),
('password', models.CharField(max_length=64)), ('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='是否已经激活')), ('is_actived', models.BooleanField(default=False, verbose_name='是否已经激活')),
('certid', models.CharField(blank=True, max_length=64, null=True, verbose_name='超级签名自动创建证书ID')), ('certid', models.CharField(blank=True, max_length=64, null=True, verbose_name='超级签名自动创建证书ID')),
('usable_number', models.IntegerField(default=100, verbose_name='可使用设备数')), ('usable_number', models.IntegerField(default=100, verbose_name='可使用设备数')),
('use_number', models.IntegerField(default=0, verbose_name='已消耗设备数')), ('use_number', models.IntegerField(default=0, verbose_name='已消耗设备数')),
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_time', models.DateTimeField(auto_now=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='备注')), ('description', models.TextField(blank=True, default='', null=True, verbose_name='备注')),
('issuer_id', models.CharField(blank=True, max_length=64, null=True, verbose_name='标识创建认证令牌的发放者')), ('auth_type', models.SmallIntegerField(choices=[(0, 'p8key认证')], default=0, 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='认证类型')),
('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL,
verbose_name='用户ID')), verbose_name='用户ID')),
], ],
@ -102,9 +100,9 @@ class Migration(migrations.Migration):
('password', models.CharField(blank=True, help_text='默认 没有密码', max_length=32, verbose_name='访问密码')), ('password', models.CharField(blank=True, help_text='默认 没有密码', max_length=32, verbose_name='访问密码')),
('isshow', models.BooleanField(default=True, verbose_name='下载页可见')), ('isshow', models.BooleanField(default=True, verbose_name='下载页可见')),
('issupersign', models.BooleanField(default=False, verbose_name='是否超级签名包')), ('issupersign', models.BooleanField(default=False, verbose_name='是否超级签名包')),
('supersign_type', ('supersign_type', models.SmallIntegerField(
models.SmallIntegerField(choices=[(0, '普通权限'), (1, '特殊权限(包含network、vpn)')], default=0, choices=[(0, '普通权限'), (1, '推送权限,请上传adhoc包'), (2, 'network、vpn、推送权限,请上传adhoc包'), (3, '特殊权限')],
verbose_name='签名类型')), default=1, verbose_name='签名类型')),
('new_bundle_id', models.CharField(blank=True, help_text='用于超级签某些因素下需要修改包名', max_length=64, null=True, ('new_bundle_id', models.CharField(blank=True, help_text='用于超级签某些因素下需要修改包名', max_length=64, null=True,
verbose_name='new_bundle_id')), verbose_name='new_bundle_id')),
('supersign_limit_number', models.IntegerField(default=0, verbose_name='签名使用限额')), ('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='域名解析地址')), ('ip_address', models.CharField(max_length=128, verbose_name='域名解析地址')),
('is_enable', models.BooleanField(default=True, verbose_name='是否启用该解析')), ('is_enable', models.BooleanField(default=True, verbose_name='是否启用该解析')),
('is_system', models.BooleanField(default=False, 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='备注')), ('description', models.TextField(blank=True, default='', null=True, verbose_name='备注')),
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
], ],
options={ options={
'verbose_name': '分发域名信息', 'verbose_name': '系统分发域名配置',
'verbose_name_plural': '分发域名信息', 'verbose_name_plural': '系统分发域名配置',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
@ -171,8 +170,8 @@ class Migration(migrations.Migration):
verbose_name='用户ID')), verbose_name='用户ID')),
], ],
options={ options={
'verbose_name': '分发域名绑定', 'verbose_name': '用户分发域名绑定',
'verbose_name_plural': '分发域名绑定', 'verbose_name_plural': '用户分发域名绑定',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
@ -188,7 +187,7 @@ class Migration(migrations.Migration):
verbose_name='认证状态')), verbose_name='认证状态')),
('msg', models.CharField(blank=True, max_length=512, null=True, verbose_name='备注')), ('msg', models.CharField(blank=True, max_length=512, null=True, verbose_name='备注')),
('created_time', models.DateTimeField(auto_now_add=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', ('user_id',
models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='certification', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='certification',
to=settings.AUTH_USER_MODEL, verbose_name='用户ID')), to=settings.AUTH_USER_MODEL, verbose_name='用户ID')),
@ -525,6 +524,6 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='appiosdeveloperinfo', 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): class AppIOSDeveloperInfo(models.Model):
user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE) user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE)
email = models.EmailField( issuer_id = models.CharField(max_length=64, null=False, verbose_name="标识创建认证令牌的发放者")
verbose_name='email address', private_key_id = models.CharField(max_length=64, null=False, verbose_name="密钥 ID")
max_length=64, p8key = models.TextField(max_length=512, null=False, verbose_name="p8key")
blank=True,
null=True
)
password = models.CharField(max_length=64, )
is_actived = models.BooleanField(default=False, verbose_name="是否已经激活") is_actived = models.BooleanField(default=False, verbose_name="是否已经激活")
certid = models.CharField(max_length=64, blank=True, verbose_name="超级签名自动创建证书ID", null=True) certid = models.CharField(max_length=64, blank=True, verbose_name="超级签名自动创建证书ID", null=True)
usable_number = models.IntegerField(verbose_name="可使用设备数", default=100) usable_number = models.IntegerField(verbose_name="可使用设备数", default=100)
use_number = models.IntegerField(verbose_name="已消耗设备数", default=0) use_number = models.IntegerField(verbose_name="已消耗设备数", default=0)
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_time = models.DateTimeField(auto_now=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='') description = models.TextField('备注', blank=True, null=True, default='')
issuer_id = models.CharField(max_length=64, blank=True, null=True, verbose_name="标识创建认证令牌的发放者") auth_type_choices = ((0, 'p8key认证'),)
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 = models.SmallIntegerField(choices=auth_type_choices, default=0, verbose_name="认证类型") auth_type = models.SmallIntegerField(choices=auth_type_choices, default=0, verbose_name="认证类型")
class Meta: class Meta:
verbose_name = '苹果开发者账户' verbose_name = '苹果开发者账户'
verbose_name_plural = "苹果开发者账户" verbose_name_plural = "苹果开发者账户"
unique_together = (('user_id', 'email',), ('user_id', 'issuer_id')) unique_together = (('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
def __str__(self): def __str__(self):
return "%s-%s" % (self.user_id, self.email) return "%s-%s" % (self.user_id, self.issuer_id)
class APPSuperSignUsedInfo(models.Model): class APPSuperSignUsedInfo(models.Model):
@ -421,7 +406,7 @@ class UserCertificationInfo(models.Model):
status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="认证状态") status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="认证状态")
msg = models.CharField(max_length=512, null=True, blank=True, verbose_name="备注") msg = models.CharField(max_length=512, null=True, blank=True, verbose_name="备注")
created_time = models.DateTimeField(auto_now_add=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: class Meta:
verbose_name = '用户认证信息' verbose_name = '用户认证信息'

@ -5,7 +5,7 @@
# date: 2020/4/24 # date: 2020/4/24
import OpenSSL 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 from fir_ser.settings import SUPER_SIGN_ROOT
import os import os
from api.utils.app.randomstrings import make_app_uuid 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: if result.get("exit_code") != 0:
err_info = result.get("err_info", None) err_info = result.get("err_info", None)
if err_info: if err_info:
if "have access to this membership resource. Contact your team" in err_info: logger.error("exec_shell cmd:%s failed: %s" % (cmd, err_info))
result["err_info"] = "You currently don't have access to this membership resource 【您没有权限执行该操作】" result["err_info"] = "Unknown Error"
elif "Maximum number of certificates generated" in err_info:
result["err_info"] = "Maximum number of certificates generated 【开发证书数量到上限】"
else:
result["err_info"] = "Unknown Error"
return False, result return False, result
return True, 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): class ResignApp(object):
def __init__(self, my_local_key, app_dev_pem): def __init__(self, my_local_key, app_dev_pem):
self.my_local_key = my_local_key self.my_local_key = my_local_key
self.app_dev_pem = app_dev_pem 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) self.cmd = "isign -c '%s' -k '%s' " % (self.app_dev_pem, self.my_local_key)
@staticmethod @staticmethod
@ -143,11 +72,12 @@ class AppDeveloperApiV2(object):
self.p8key = p8key self.p8key = p8key
self.certid = certid self.certid = certid
def active(self, user_obj): def active(self):
result = {} result = {}
try: try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
certificates = apple_obj.get_all_certificates() certificates = apple_obj.get_all_certificates()
result['data'] = certificates
logger.info("ios developer active result:%s" % certificates) logger.info("ios developer active result:%s" % certificates)
if len(certificates) > 0: if len(certificates) > 0:
return True, result return True, result
@ -222,9 +152,7 @@ class AppDeveloperApiV2(object):
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
if developer_app_id: if developer_app_id:
pass pass
# bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundleId + app_id)
else: else:
# bundle_obj = apple_obj.list_bundle_ids_by_identifier(bundleId + app_id)
if s_type == 0: if s_type == 0:
bundle_obj = apple_obj.register_bundle_id(app_id, bundle_id + app_id) bundle_obj = apple_obj.register_bundle_id(app_id, bundle_id + app_id)
else: else:
@ -254,7 +182,7 @@ class AppDeveloperApiV2(object):
result['return_info'] = "%s" % e result['return_info'] = "%s" % e
return False, result return False, result
def del_profile(self, bundleId, app_id): def del_profile(self, app_id):
result = {} result = {}
try: try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
@ -283,7 +211,7 @@ class AppDeveloperApiV2(object):
result['return_info'] = "%s" % e result['return_info'] = "%s" % e
return False, result return False, result
def get_device(self, user_obj): def get_device(self):
result = {} result = {}
try: try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)

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

@ -6,7 +6,7 @@
import uuid, xmltodict, os, re, logging, time import uuid, xmltodict, os, re, logging, time
from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, SERVER_DOMAIN, MOBILECONFIG_SIGN_SSL 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, \ from api.models import APPSuperSignUsedInfo, AppUDID, AppIOSDeveloperInfo, AppReleaseInfo, Apps, APPToDeveloper, \
UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID
from api.utils.app.randomstrings import make_app_uuid, make_from_user_uuid 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, \ 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 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, \ 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 api.utils.storage.storage import Storage
from django.core.cache import cache from django.core.cache import cache
@ -157,14 +157,7 @@ def get_post_udid_url(request, short):
def get_auth_form_developer(developer_obj): def get_auth_form_developer(developer_obj):
if developer_obj.email: if developer_obj.issuer_id:
auth = {
"username": developer_obj.email,
"password": developer_obj.password,
"certid": developer_obj.certid
}
elif developer_obj.issuer_id:
auth = { auth = {
"issuer_id": developer_obj.issuer_id, "issuer_id": developer_obj.issuer_id,
"private_key_id": developer_obj.private_key_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): def get_api_obj(auth):
if auth.get("username"): if auth.get("issuer_id"):
app_api_obj = AppDeveloperApi(**auth)
elif auth.get("issuer_id"):
app_api_obj = AppDeveloperApiV2(**auth) app_api_obj = AppDeveloperApiV2(**auth)
else: else:
app_api_obj = None app_api_obj = None
@ -187,7 +178,7 @@ def get_api_obj(auth):
def get_apple_udid_key(auth): def get_apple_udid_key(auth):
mpkey = auth.get("username") mpkey = ''
if auth.get("issuer_id"): if auth.get("issuer_id"):
mpkey = auth.get("issuer_id") mpkey = auth.get("issuer_id")
return mpkey return mpkey
@ -267,9 +258,8 @@ class IosUtils(object):
if developer_udid_obj: if developer_udid_obj:
developer_obj = developer_udid_obj.developerid developer_obj = developer_udid_obj.developerid
else: else:
for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True,
is_actived=True, certid__isnull=False).order_by( certid__isnull=False).order_by("created_time"):
"created_time"):
usable_number = developer_obj.usable_number usable_number = developer_obj.usable_number
flyapp_used = get_developer_udided(developer_obj)[1] flyapp_used = get_developer_udided(developer_obj)[1]
if flyapp_used < usable_number: if flyapp_used < usable_number:
@ -283,11 +273,11 @@ class IosUtils(object):
self.auth, developer_app_id, device_id_list) self.auth, developer_app_id, device_id_list)
# 开启超级签直接在开发者账户创建 # 开启超级签直接在开发者账户创建
def create_app(self, app_obj): # def create_app(self, app_obj):
bundleId = self.app_obj.bundle_id # bundleId = self.app_obj.bundle_id
app_id = self.app_obj.app_id # app_id = self.app_obj.app_id
s_type = self.app_obj.supersign_type # s_type = self.app_obj.supersign_type
return get_api_obj(self.auth).create_app(bundleId, app_id, s_type) # return get_api_obj(self.auth).create_app(bundleId, app_id, s_type)
@staticmethod @staticmethod
def modify_capability(developer_obj, app_obj, developer_app_id): 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: if APPSuperSignUsedInfo.objects.filter(developerid=developer_obj, app_id_id=app_id).count() == 0:
app_api_obj = get_api_obj(auth) app_api_obj = get_api_obj(auth)
app_obj = Apps.objects.filter(pk=app_id).first() 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 = get_api_obj(auth)
app_api_obj2.del_app(app_obj.bundle_id, app_obj.app_id) app_api_obj2.del_app(app_obj.bundle_id, app_obj.app_id)
DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete() 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) auth = get_auth_form_developer(developer_obj)
DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete() DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete()
app_api_obj = get_api_obj(auth) 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 = get_api_obj(auth)
app_api_obj2.del_app(app_obj.bundle_id, app_obj.app_id) 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)) developer_obj, user_obj, e))
@staticmethod @staticmethod
def active_developer(developer_obj, user_obj): def active_developer(developer_obj):
''' '''
激活开发者账户 激活开发者账户
:param developer_obj: :param developer_obj:
@ -635,8 +625,12 @@ class IosUtils(object):
''' '''
auth = get_auth_form_developer(developer_obj) auth = get_auth_form_developer(developer_obj)
app_api_obj = get_api_obj(auth) app_api_obj = get_api_obj(auth)
status, result = app_api_obj.active(user_obj) status, result = app_api_obj.active()
if status: 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.is_actived = True
developer_obj.save() developer_obj.save()
return status, result return status, result
@ -651,30 +645,14 @@ class IosUtils(object):
cert_id = result.id cert_id = result.id
AppIOSDeveloperInfo.objects.filter(user_id=user_obj, issuer_id=auth.get("issuer_id")).update( AppIOSDeveloperInfo.objects.filter(user_id=user_obj, issuer_id=auth.get("issuer_id")).update(
is_actived=True, is_actived=True,
certid=cert_id) certid=cert_id, cert_expire_time=format_apple_date(result.expirationDate))
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)
return status, result return status, result
@staticmethod @staticmethod
def get_device_from_developer(developer_obj, user_obj): def get_device_from_developer(developer_obj, user_obj):
auth = get_auth_form_developer(developer_obj) auth = get_auth_form_developer(developer_obj)
app_api_obj = get_api_obj(auth) 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 status:
if auth.get("issuer_id"): if auth.get("issuer_id"):
UDIDsyncDeveloper.objects.filter(developerid=developer_obj, platform=1).delete() UDIDsyncDeveloper.objects.filter(developerid=developer_obj, platform=1).delete()

@ -7,7 +7,8 @@
import os, re, time import os, re, time
from django.db.models import Count from django.db.models import Count
import datetime
from django.utils import timezone
from fir_ser.settings import SUPER_SIGN_ROOT from fir_ser.settings import SUPER_SIGN_ROOT
from api.models import AppReleaseInfo, UserDomainInfo, DomainCnameInfo from api.models import AppReleaseInfo, UserDomainInfo, DomainCnameInfo
from api.utils.app.randomstrings import make_app_uuid 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 return d_count
def file_format_path(user_obj, auth=None, email=None): def file_format_path(user_obj, auth=None):
if email: cert_dir_name = make_app_uuid(user_obj, auth.get("issuer_id"))
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)
cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name) cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name)
if not os.path.isdir(cert_dir_path): if not os.path.isdir(cert_dir_path):
os.makedirs(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): def get_profile_full_path(developer_obj, app_obj):
pkey = developer_obj.email cert_dir_name = make_app_uuid(developer_obj.user_id, developer_obj.issuer_id)
if developer_obj.issuer_id:
pkey = developer_obj.issuer_id
cert_dir_name = make_app_uuid(developer_obj.user_id, pkey)
cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name, "profile") 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) provision_name = os.path.join(cert_dir_path, app_obj.app_id)
return provision_name + '.mobileprovision' 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): 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), return min(DomainCnameInfo.objects.annotate(Count('userdomaininfo')).filter(is_enable=True, is_system=is_system),
key=lambda x: x.userdomaininfo__count) 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: for ios_developer in all_ios_developer:
userinfo = ios_developer.user_id userinfo = ios_developer.user_id
if userinfo.supersign_active: 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" % ( msg = "auto_check_ios_developer_active user:%s ios.developer:%s status:%s result:%s" % (
ios_developer.user_id, ios_developer, status, result) ios_developer.user_id, ios_developer, status, result)
if status: if status:

@ -4,13 +4,10 @@
# author: liuyu # author: liuyu
# date: 2020/3/23 # date: 2020/3/23
from api.models import UserInfo
from .aliyunApi import AliMsgSender from .aliyunApi import AliMsgSender
from .emailApi import EmailMsgSender from .emailApi import EmailMsgSender
from .jiguangApi import JiGuangMsgSender from .jiguangApi import JiGuangMsgSender
import json, time, base64 from fir_ser.settings import THIRD_PART_CONFIG
from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE
from django.core.cache import cache
import logging import logging
logger = logging.getLogger(__file__) 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.storage.storage import Storage
from api.utils.utils import get_developer_udided, get_choices_dict, get_choices_name_from_key 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 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__) logger = logging.getLogger(__file__)
@ -393,7 +393,7 @@ class DeveloperSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.AppIOSDeveloperInfo model = models.AppIOSDeveloperInfo
# depth = 1 # depth = 1
exclude = ["password", "id", "user_id", "p8key"] exclude = ["id", "user_id", "p8key"]
developer_used_number = serializers.SerializerMethodField() developer_used_number = serializers.SerializerMethodField()
developer_used_other_number = serializers.SerializerMethodField() developer_used_other_number = serializers.SerializerMethodField()
@ -408,7 +408,6 @@ class DeveloperSerializer(serializers.ModelSerializer):
class SuperSignUsedSerializer(serializers.ModelSerializer): class SuperSignUsedSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.APPSuperSignUsedInfo model = models.APPSuperSignUsedInfo
# depth = 1
fields = ["created_time", "device_udid", "device_name", "developer_id", "bundle_id", "bundle_name"] fields = ["created_time", "device_udid", "device_name", "developer_id", "bundle_id", "bundle_name"]
device_udid = serializers.SerializerMethodField() device_udid = serializers.SerializerMethodField()
@ -424,10 +423,7 @@ class SuperSignUsedSerializer(serializers.ModelSerializer):
return obj.udid.product return obj.udid.product
def get_developer_id(self, obj): def get_developer_id(self, obj):
developer_id = obj.developerid.email return obj.developerid.issuer_id
if obj.developerid.issuer_id:
developer_id = obj.developerid.issuer_id
return developer_id
def get_bundle_id(self, obj): def get_bundle_id(self, obj):
return obj.app_id.bundle_id 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, \ 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 USER_FREE_DOWNLOAD_TIMES, AUTH_USER_FREE_DOWNLOAD_TIMES
from api.utils.storage.storage import Storage, LocalStorage 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 import logging
from django.db.models import F from django.db.models import F
@ -229,16 +229,16 @@ def get_app_today_download_times(app_ids):
return download_times_count return download_times_count
def developer_auth_code(act, user_obj, developer_email, code=None): # def developer_auth_code(act, user_obj, developer_issuer_id, code=None):
auth_key = file_format_path(user_obj, email=developer_email) # auth_key = file_format_path(user_obj, email=developer_issuer_id)
key = "_".join([CACHE_KEY_TEMPLATE.get("developer_auth_code_key"), auth_key]) # key = "_".join([CACHE_KEY_TEMPLATE.get("developer_auth_code_key"), auth_key])
if act == "set": # if act == "set":
cache.delete(key) # cache.delete(key)
cache.set(key, code, 60 * 10) # cache.set(key, code, 60 * 10)
elif act == "get": # elif act == "get":
return cache.get(key) # return cache.get(key)
elif act == "del": # elif act == "del":
cache.delete(key) # cache.delete(key)
def upload_file_tmp_name(act, filename, user_obj_id): def upload_file_tmp_name(act, filename, user_obj_id):

@ -26,9 +26,8 @@ class IosUDIDView(View):
status = True status = True
try: try:
app_info = Apps.objects.filter(short=short).first() app_info = Apps.objects.filter(short=short).first()
if app_info: 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: if app_info.issupersign and app_info.user_id.supersign_active:
ios_obj = IosUtils(format_udid_info, app_info.user_id, app_info) ios_obj = IosUtils(format_udid_info, app_info.user_id, app_info)
status, msg = ios_obj.sign() status, msg = ios_obj.sign()

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

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

Loading…
Cancel
Save