From 870646daebf4b712c11118d01e4a29c2446073f6 Mon Sep 17 00:00:00 2001 From: nineven Date: Mon, 27 Apr 2020 21:39:55 +0800 Subject: [PATCH] fix bugs --- fir_client/src/components/FirHeader.vue | 10 +- .../src/components/FirSuperSignBase.vue | 303 ++++++++++++++++++ .../src/components/FirUserProfileBase.vue | 2 +- fir_client/src/restful/index.js | 53 ++- fir_client/src/router/index.js | 17 +- fir_ser/api/models.py | 4 +- fir_ser/api/urls.py | 5 + fir_ser/api/utils/app/supersignutils.py | 36 ++- fir_ser/api/utils/serializer.py | 49 +++ fir_ser/api/views/receiveudids.py | 2 +- fir_ser/api/views/supersign.py | 93 ++++++ fir_ser/supersign/scripts/apple_api.rb | 2 +- 12 files changed, 560 insertions(+), 16 deletions(-) create mode 100644 fir_client/src/components/FirSuperSignBase.vue create mode 100644 fir_ser/api/views/supersign.py diff --git a/fir_client/src/components/FirHeader.vue b/fir_client/src/components/FirHeader.vue index 6d5ea22..b65853f 100644 --- a/fir_client/src/components/FirHeader.vue +++ b/fir_client/src/components/FirHeader.vue @@ -25,6 +25,9 @@ 个人资料 修改密码 + 存储管理 + 超级签名 + 退出 @@ -61,7 +64,12 @@ import {logout} from '../restful' this.$router.push({name: 'FirUserProfileInfo'}) } else if (command === 'chpasswd') { this.$router.push({name: 'FirUserProfileChangePwd'}) - }else if(command === 'exit'){ + }else if (command === 'storage') { + this.$router.push({name: 'FirUserProfileStorage'}) + }else if (command === 'supersign') { + this.$router.push({name: 'FirSuperSignBase'}) + } + else if(command === 'exit'){ logout(data => { if (data.code === 1000) { this.$message.success("退出成功"); diff --git a/fir_client/src/components/FirSuperSignBase.vue b/fir_client/src/components/FirSuperSignBase.vue new file mode 100644 index 0000000..b95a57b --- /dev/null +++ b/fir_client/src/components/FirSuperSignBase.vue @@ -0,0 +1,303 @@ + + + + + diff --git a/fir_client/src/components/FirUserProfileBase.vue b/fir_client/src/components/FirUserProfileBase.vue index feafb89..048c02b 100644 --- a/fir_client/src/components/FirUserProfileBase.vue +++ b/fir_client/src/components/FirUserProfileBase.vue @@ -66,7 +66,7 @@ import {uploadaliyunoss, uploadlocalstorage, uploadqiniuoss} from "../utils"; export default { - name: "FirUserProfile", + name: "FirUserProfileBase", data() { return { imageUrl: '', diff --git a/fir_client/src/restful/index.js b/fir_client/src/restful/index.js index 4b40b10..dac8b91 100644 --- a/fir_client/src/restful/index.js +++ b/fir_client/src/restful/index.js @@ -10,9 +10,11 @@ Axios.defaults.httpsAgent = new https.Agent({ }); // Axios.defaults.baseURL=''; -const USERSEVER = 'https://fly.dvcloud.xin/api/v1/fir/server'; +const DOMAIN = 'https://fly.dvcloud.xin'; -// const USERSEVER = 'http://192.168.1.112:8000/api/v1/fir/server'; +// const DOMAIN = 'http://192.168.8.236:8000'; +const APIPATH='/api/v1/fir/server'; +let USERSEVER = DOMAIN+APIPATH; export function set_auth_token() { @@ -357,7 +359,7 @@ export function getuploadurl() { return USERSEVER + '/upload' } export function getplisturl() { - return USERSEVER + '/download' + return DOMAIN + '/download' } @@ -435,3 +437,48 @@ export function uploadimgs(callBack, params, load = true) { ); } +/**超级签名 苹果开发者信息 */ +export function iosdeveloper(callBack, params, load = true) { + getData( + params.methods, + USERSEVER + '/supersign/developer', + params.data, + data => { + callBack(data); + }, + load, + true, + true + ); +} + +/**超级签名 设备消耗信息 */ +export function iosdevices(callBack, params, load = true) { + getData( + params.methods, + USERSEVER + '/supersign/devices', + params.data, + data => { + callBack(data); + }, + load, + true, + true + ); +} + +/**超级签名 设备udid信息 */ +export function iosdevicesudid(callBack, params, load = true) { + // eslint-disable-next-line no-console + getData( + params.methods, + USERSEVER + '/supersign/udid', + params.data, + data => { + callBack(data); + }, + load, + true, + true + ); +} \ No newline at end of file diff --git a/fir_client/src/router/index.js b/fir_client/src/router/index.js index 0bc90b1..a3084e8 100644 --- a/fir_client/src/router/index.js +++ b/fir_client/src/router/index.js @@ -23,11 +23,13 @@ import FirAppInfosbaseinfo from "@/components/FirAppInfosbaseinfo"; import FirAppInfossecurity from "@/components/FirAppInfossecurity"; import FirAppInfosdevices from "@/components/FirAppInfosdevices"; import FirAppInfoscombo from "@/components/FirAppInfoscombo"; -import FirUserProfile from "@/components/FirUserProfileBase"; +import FirUserProfileBase from "@/components/FirUserProfileBase"; import FirUserProfileInfo from "@/components/FirUserProfileInfo"; import FirUserProfileChangePwd from "@/components/FirUserProfileChangePwd"; import FirUserProfileStorage from "@/components/FirUserProfileStorage"; +import FirSuperSignBase from "@/components/FirSuperSignBase"; + const router = new VueRouter({ mode:'history', routes: [ @@ -91,7 +93,7 @@ const router = new VueRouter({ children: [ { path: '', - component: FirUserProfile, + component: FirUserProfileBase, children: [ { path: 'info', @@ -116,6 +118,17 @@ const router = new VueRouter({ name: 'FirLogin', component: FirLogin }, + { + path: '/supersign', + component: FirAppBase, + children: [ + { + path: '', + name: 'FirSuperSignBase', + component: FirSuperSignBase, + } + ] + }, { path: '/register', name: 'FirRegist', diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index e91d3be..613ca1a 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -168,7 +168,7 @@ class AppStorage(models.Model): class AppUDID(models.Model): app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP") - udid = models.CharField(max_length=64, unique=True,verbose_name="udid唯一标识",db_index=True) + udid = models.CharField(max_length=64,verbose_name="udid唯一标识",db_index=True) product = models.CharField(max_length=64, verbose_name="产品", blank=True, null=True, ) serial = models.CharField(max_length=64, verbose_name="序列号", blank=True, null=True, ) version = models.CharField(max_length=64, verbose_name="型号", blank=True, null=True, ) @@ -205,6 +205,8 @@ class AppIOSDeveloperInfo(models.Model): 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="更新时间") + description = models.TextField('备注', blank=True, null=True, default='') + class Meta: verbose_name = '苹果开发者账户' verbose_name_plural = "苹果开发者账户" diff --git a/fir_ser/api/urls.py b/fir_ser/api/urls.py index 84b066e..9e8c1bd 100644 --- a/fir_ser/api/urls.py +++ b/fir_ser/api/urls.py @@ -25,6 +25,8 @@ from api.views.uploads import AppAnalyseView,UploadView from api.views.storage import StorageView from api.views.receiveudids import IosUDIDView +from api.views.supersign import DeveloperView,SuperSignUsedView,AppUDIDUsedView + # router=DefaultRouter() # router.register("apps", AppsView) @@ -43,4 +45,7 @@ urlpatterns = [ re_path("^short/(?P\w+)$", ShortDownloadView.as_view()), re_path("^udid/(?P\w+)$", IosUDIDView.as_view()), re_path("^analyse$", AppAnalyseView.as_view()), + re_path("^supersign/developer$", DeveloperView.as_view()), + re_path("^supersign/devices$", SuperSignUsedView.as_view()), + re_path("^supersign/udid$", AppUDIDUsedView.as_view()), ] diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index 15735b7..80021c8 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -104,15 +104,14 @@ def get_redirect_server_domain(request): class IosUtils(object): - def __init__(self, udid_info, app_obj): + def __init__(self, udid_info,user_obj,app_obj=None): self.udid_info = udid_info self.app_obj = app_obj - self.user_obj = app_obj.user_id + self.user_obj = user_obj self.get_developer_auth() def get_developer_auth(self): - developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True, - use_number__lte=F("usable_number")).first() + developer_obj = self.get_developer_user_by_app_udid() auth = { "username": developer_obj.email, "password": developer_obj.password, @@ -121,6 +120,17 @@ class IosUtils(object): self.developer_obj = developer_obj self.auth = auth + def get_developer_user_by_app_udid(self): + usedeviceobj = APPSuperSignUsedInfo.objects.filter(udid__udid=self.udid_info.get('udid'), app_id=self.app_obj, + user_id=self.user_obj).first() + if usedeviceobj and usedeviceobj.developer_obj.use_number < usedeviceobj.developer_obj.usable_number: + developer_obj = usedeviceobj.developerid + else: + developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True, + use_number__lt=F("usable_number")).order_by( + "created_time").first() + return developer_obj + def create_cert(self): app_api_obj = AppDeveloperApi(**self.auth) app_api_obj.create_cert(self.user_obj) @@ -179,11 +189,25 @@ class IosUtils(object): newdata = { "is_signed": True, - "binary_file": random_file_name + ".ipa" + "binary_file": random_file_name } AppUDID.objects.filter(app_id=self.app_obj, udid=self.udid_info.get('udid')).update(**newdata) APPSuperSignUsedInfo.objects.create(app_id=self.app_obj, user_id=self.user_obj, developerid=self.developer_obj, - udid=self.udid_info.get('udid')) + udid=AppUDID.objects.filter(app_id=self.app_obj,udid=self.udid_info.get('udid')).first()) AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True, use_number__lte=F("usable_number")).first().update( use_number=self.developer_obj.use_number + 1) + + @staticmethod + def disable_udid(udid_obj,app_id): + usedeviceobj=APPSuperSignUsedInfo.objects.filter(udid=udid_obj,app_id_id=app_id) + if usedeviceobj: + developer_obj = usedeviceobj.first().developerid + auth = { + "username": developer_obj.email, + "password": developer_obj.password, + "certid": developer_obj.certid + } + app_api_obj = AppDeveloperApi(**auth) + app_api_obj.set_device_status("disable",udid_obj.udid) + usedeviceobj.delete() \ No newline at end of file diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index 61abd50..363b016 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -212,3 +212,52 @@ class StorageSerializer(serializers.ModelSerializer): storage_obj = models.AppStorage.objects.create(**validated_data,user_id=user_obj,) return storage_obj return None + +class DeveloperSerializer(serializers.ModelSerializer): + class Meta: + model = models.AppIOSDeveloperInfo + # depth = 1 + exclude = ["password", "id","name","user_id"] + +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() + device_name = serializers.SerializerMethodField() + developer_id = serializers.SerializerMethodField() + bundle_id = serializers.SerializerMethodField() + bundle_name = serializers.SerializerMethodField() + + def get_device_udid(self,obj): + return obj.udid.udid + + def get_device_name(self,obj): + return obj.udid.product + + def get_developer_id(self,obj): + return obj.developerid.email + + def get_bundle_id(self, obj): + return obj.app_id.bundle_id + + def get_bundle_name(self, obj): + return obj.app_id.name + + +class DeviceUDIDSerializer(serializers.ModelSerializer): + class Meta: + model = models.AppUDID + # depth = 1 + exclude = ["binary_file","updated_time","is_signed"] + + bundle_id = serializers.SerializerMethodField() + bundle_name = serializers.SerializerMethodField() + + def get_bundle_id(self, obj): + return obj.app_id.bundle_id + + def get_bundle_name(self, obj): + return obj.app_id.name \ No newline at end of file diff --git a/fir_ser/api/views/receiveudids.py b/fir_ser/api/views/receiveudids.py index 018ecd5..62ffc59 100644 --- a/fir_ser/api/views/receiveudids.py +++ b/fir_ser/api/views/receiveudids.py @@ -20,7 +20,7 @@ class IosUDIDView(View): if app_info : if app_info.issupersign: AppUDID.objects.update_or_create(app_id=app_info,**format_udid_info,defaults={'udid':format_udid_info.get('udid')}) - ios_obj = IosUtils(format_udid_info,app_info) + ios_obj = IosUtils(format_udid_info,app_info.user_id,app_info) ios_obj.resign() else: return Http404 diff --git a/fir_ser/api/views/supersign.py b/fir_ser/api/views/supersign.py new file mode 100644 index 0000000..2af0c46 --- /dev/null +++ b/fir_ser/api/views/supersign.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# project: 3月 +# author: liuyu +# date: 2020/3/4 + +from rest_framework.views import APIView +from api.utils.response import BaseResponse +from api.utils.auth import ExpiringTokenAuthentication +from rest_framework.response import Response +from api.models import AppIOSDeveloperInfo,APPSuperSignUsedInfo,AppUDID +from api.utils.serializer import DeveloperSerializer, UserInfoSerializer,SuperSignUsedSerializer,DeviceUDIDSerializer +from rest_framework.pagination import PageNumberPagination +from api.utils.app.supersignutils import IosUtils + + + +class AppsPageNumber(PageNumberPagination): + page_size = 10 # 每页显示多少条 + page_size_query_param = 'size' # URL中每页显示条数的参数 + page_query_param = 'page' # URL中页码的参数 + max_page_size = None # 最大页码数限制 + + +class DeveloperView(APIView): + authentication_classes = [ExpiringTokenAuthentication, ] + + def get(self, request): + + res = BaseResponse() + + developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user) + + page_obj = AppsPageNumber() + app_page_serializer = page_obj.paginate_queryset(queryset=developer_obj.order_by("-updated_time"), request=request, + view=self) + + app_serializer = DeveloperSerializer(app_page_serializer, many=True,) + userserializer = UserInfoSerializer(request.user) + res.userinfo = {} + res.has_next = {} + res.userinfo = userserializer.data + res.data = app_serializer.data + res.has_next = page_obj.page.has_next() + return Response(res.dict) + +class SuperSignUsedView(APIView): + authentication_classes = [ExpiringTokenAuthentication, ] + + def get(self, request): + res = BaseResponse() + developer_obj = APPSuperSignUsedInfo.objects.filter(user_id=request.user) + page_obj = AppsPageNumber() + app_page_serializer = page_obj.paginate_queryset(queryset=developer_obj.order_by("-created_time"), request=request, + view=self) + app_serializer = SuperSignUsedSerializer(app_page_serializer, many=True, ) + res.data = app_serializer.data + res.has_next = page_obj.page.has_next() + return Response(res.dict) + +class AppUDIDUsedView(APIView): + authentication_classes = [ExpiringTokenAuthentication, ] + + def get(self, request): + res = BaseResponse() + + udid = request.query_params.get("udid", None) + bundleid = request.query_params.get("bundleid", None) + if udid and bundleid: + developer_obj = AppUDID.objects.filter(app_id__user_id_id=request.user,app_id__bundle_id=bundleid,udid=udid) + elif udid: + developer_obj = AppUDID.objects.filter(app_id__user_id_id=request.user,udid=udid) + elif bundleid: + developer_obj = AppUDID.objects.filter(app_id__user_id_id=request.user,app_id__bundle_id=bundleid) + else: + developer_obj = AppUDID.objects.filter(app_id__user_id_id=request.user) + + page_obj = AppsPageNumber() + app_page_serializer = page_obj.paginate_queryset(queryset=developer_obj.order_by("-created_time"), request=request, + view=self) + app_serializer = DeviceUDIDSerializer(app_page_serializer, many=True,) + res.data = app_serializer.data + res.has_next = page_obj.page.has_next() + return Response(res.dict) + + def delete(self,request): + res = BaseResponse() + id = request.query_params.get("id", None) + app_id = request.query_params.get("aid", None) + app_udid_obj=AppUDID.objects.filter(app_id__user_id_id=request.user,pk=id) + IosUtils.disable_udid(app_udid_obj.first(),app_id) + app_udid_obj.delete() + return self.get(request) diff --git a/fir_ser/supersign/scripts/apple_api.rb b/fir_ser/supersign/scripts/apple_api.rb index 699278c..bb25a19 100644 --- a/fir_ser/supersign/scripts/apple_api.rb +++ b/fir_ser/supersign/scripts/apple_api.rb @@ -39,7 +39,7 @@ class DevelopPortalHandle if !cert then cert = Spaceship::Portal.certificate.production.all.last end - profile = provisioningClass.create!(bundle_id: appid,certificate:cert,name:provisionName + '_dis') + profile = provisioningClass.create!(bundle_id: appid,certificate:cert,name:provisionName.split("/")[-1]) return profile end