增加本地存储上传域名配置

super_signature
nineven 5 years ago
parent e035f40d86
commit c0296619cc
  1. 6
      fir_client/src/components/FirAppInfosbaseinfo.vue
  2. 9
      fir_client/src/components/FirAppInfossecurity.vue
  3. 6
      fir_client/src/components/FirApps.vue
  4. 16
      fir_client/src/components/FirDownload.vue
  5. 6
      fir_client/src/components/FirUserProfileBase.vue
  6. 18
      fir_client/src/components/FirUserProfileInfo.vue
  7. 8
      fir_client/src/restful/index.js
  8. 2900
      fir_download/src/components/FirDownload.vue
  9. 2
      fir_ser/api/models.py
  10. 13
      fir_ser/api/utils/app/supersignutils.py
  11. 2
      fir_ser/api/utils/serializer.py
  12. 6
      fir_ser/api/utils/storage/caches.py
  13. 62
      fir_ser/api/views/apps.py
  14. 3
      fir_ser/api/views/download.py
  15. 18
      fir_ser/api/views/login.py
  16. 46
      fir_ser/api/views/uploads.py
  17. 11
      fir_ser/fir_ser/settings.py

@ -106,7 +106,11 @@
} else {
//
certinfo.upload_url = getuploadurl();
if (certinfo.domain_name) {
certinfo.upload_url = getuploadurl(certinfo.domain_name)
} else {
certinfo.upload_url = getuploadurl();
}
// eslint-disable-next-line no-unused-vars,no-unreachable
uploadlocalstorage(file, certinfo, this, res => {
this.updateimgs(certinfo);

@ -65,6 +65,7 @@
<el-tooltip :content="wxeasytypetip.msg" placement="top">
<el-switch
:disabled="wxeasy_disable"
@change="wxeasytypeevent"
v-model="wxeasytypetip.val"
active-color="#13ce66"
@ -73,7 +74,7 @@
inactive-value="off">
</el-switch>
</el-tooltip>
<el-link :underline="false" style="margin-left: 20px">默认开启可以最大限度避免微信内举报封停</el-link>
<el-link :underline="false" style="margin-left: 20px">默认开启可以最大限度避免微信内举报封停如果绑定域名可以关闭</el-link>
</el-form-item>
<el-form-item label-width="200px" label="微信内访问跳转第三方平台">
@ -119,7 +120,8 @@
showsupersignflag: false,
wxeasytypeflag: false,
wxredirectflag: false,
clecount: 0
clecount: 0,
wxeasy_disable:false
}
},
methods: {
@ -186,6 +188,9 @@
this.wxeasytypetip.val = 'off';
}
this.wxeasytypeflag = true;
if(!this.$store.state.userinfo.domain_name){
this.wxeasy_disable=true;
}
},
setwxredirectshow(currentapp) {
if (currentapp.wxredirect === 1) {

@ -480,7 +480,11 @@
});
} else {
//
certinfo.upload_url = getuploadurl();
if (this.analyseappinfo.domain_name) {
certinfo.upload_url = getuploadurl(this.analyseappinfo.domain_name)
} else {
certinfo.upload_url = getuploadurl();
}
certinfo.ftype = 'app';
certinfo.app_id = this.analyseappinfo.app_uuid;
// eslint-disable-next-line no-unused-vars,no-unreachable

@ -256,6 +256,19 @@
}
},
auto_redircet_url(domain_name) {
if (domain_name) {
let nurl = location.href.split("//")[1].split("/");
const user_hostname = domain_name.split("//");
if (nurl[0] === user_hostname[1]) {
return true;
} else {
nurl[0] = user_hostname[1];
window.location.href = user_hostname[0] + "//" + nurl.join("/");
return false;
}
}
},
getDownloadTokenFun() {
let params = {"short": this.$route.params.short, "time": new Date().getTime()};
if (this.$route.query.release_id) {
@ -268,6 +281,9 @@
}
getShortAppinfo(data => {
if (data.code === 1000) {
if (!this.auto_redircet_url(data.domain_name)) {
return;
}
this.udid = data.udid;
if (!data.data.master_release.release_id) {
this.$message({

@ -108,7 +108,11 @@
} else {
//
certinfo.upload_url = getuploadurl();
if (certinfo.domain_name) {
certinfo.upload_url = getuploadurl(certinfo.domain_name)
} else {
certinfo.upload_url = getuploadurl();
}
// eslint-disable-next-line no-unused-vars,no-unreachable
uploadlocalstorage(file, certinfo, this, res => {
this.updateimgs(certinfo);

@ -13,15 +13,15 @@
<el-form-item>
<el-row>
<el-col :span="18">
<el-input v-model="userinfo.qq" :readonly="editqq !== true" ref="qq"
prefix-icon="el-icon-message"
placeholder="QQ"></el-input>
<el-input v-model="userinfo.domain_name" :readonly="editdomain_name !== true" ref="domain_name"
prefix-icon="el-icon-download"
placeholder="下载页域名"></el-input>
</el-col>
<el-col :span="2">
<el-button icon="el-icon-edit" @click="changeQQValue">
</el-button>
</el-col>
<el-col :span="4" v-if="editqq === true">
<el-col :span="4" v-if="editdomain_name === true">
<el-button type="success" @click="saveQQ" plain
style="margin:0 4px;border-radius:4px;cursor:pointer;height: 36px">保存
</el-button>
@ -98,7 +98,7 @@
srccode: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
},
editphone: false,
editqq: false,
editdomain_name: false,
editposition: false
}
}, methods: {
@ -154,11 +154,11 @@
},
changeQQValue() {
this.editqq = !this.editqq;
if (this.$refs.qq.$el.children[0].style.backgroundColor) {
this.$refs.qq.$el.children[0].style.backgroundColor = ''
this.editdomain_name = !this.editdomain_name;
if (this.$refs.domain_name.$el.children[0].style.backgroundColor) {
this.$refs.domain_name.$el.children[0].style.backgroundColor = ''
} else {
this.$refs.qq.$el.children[0].style.backgroundColor = '#f6ffdc';
this.$refs.domain_name.$el.children[0].style.backgroundColor = '#f6ffdc';
}
},
getphonecode() {

@ -289,8 +289,12 @@ export function getapppicurl(app_id) {
return USERSEVER + '/apps/' + app_id
}
export function getuploadurl() {
return USERSEVER + '/upload'
export function getuploadurl(domain_name=null) {
if (domain_name) {
return domain_name + APIPATH + '/upload'
} else {
return USERSEVER + '/upload';
}
}

File diff suppressed because it is too large Load Diff

@ -38,7 +38,7 @@ class UserInfo(AbstractUser):
date_joined = models.DateTimeField(auto_now_add=True, verbose_name="注册时间")
download_times = models.IntegerField(default=100, verbose_name="下载次数")
all_download_times = models.BigIntegerField(default=0, verbose_name="总共下载次数")
domain_name = models.CharField(verbose_name="域名", blank=True, null=True, max_length=64)
domain_name = models.CharField(verbose_name="下载页面域名", blank=True, null=True, max_length=64)
history_release_limit = models.IntegerField(default=10, verbose_name="app 历史记录版本", blank=True, null=True)
storage = models.OneToOneField(to='AppStorage', related_name='app_storage',
on_delete=models.SET_NULL, verbose_name="存储", null=True, blank=True)

@ -97,8 +97,15 @@ def get_http_server_doamin(request):
return server_domain
def get_redirect_server_domain(request):
server_domain = SERVER_DOMAIN.get('REDIRECT_UDID_DOMAIN', None)
def get_redirect_server_domain(request, user_obj=None):
if user_obj:
domain_name = user_obj.domain_name
else:
domain_name = request.user.domain_name
if domain_name and len(domain_name) > 3:
server_domain = "%s://%s" % ('http', domain_name) # 第三方域名暂时不支持HTTPS
else:
server_domain = SERVER_DOMAIN.get('REDIRECT_UDID_DOMAIN', None)
if not server_domain or not server_domain.startswith("http"):
HTTP_HOST = request.META.get('HTTP_HOST')
SERVER_PROTOCOL = request.META.get('SERVER_PROTOCOL')
@ -178,7 +185,7 @@ class IosUtils(object):
status, result = self.download_profile()
if not status:
logger.error("udid %s app %s developer %s sign failed %s" % (
self.udid_info.get('udid'), self.app_obj, self.developer_obj, result))
self.udid_info.get('udid'), self.app_obj, self.developer_obj, result))
self.developer_obj.is_actived = False
self.developer_obj.save()
return

@ -16,7 +16,7 @@ class UserInfoSerializer(serializers.ModelSerializer):
model = models.UserInfo
# fields="__all__"
# exclude = ["password","is_active","user_permissions","role",]
fields = ["username", "uid", "qq", "mobile", "job", "email", "domain_name", "last_login", "first_name",
fields = ["username", "uid", "mobile", "job", "email", "domain_name", "last_login", "first_name",
'head_img']
head_img = serializers.SerializerMethodField()

@ -219,3 +219,9 @@ def login_auth_failed(act, email):
return True
elif act == "del":
cache.delete(auth_code_key)
def set_default_app_wx_easy(user_obj):
app_obj_lists = Apps.objects.filter(user_id=user_obj)
for app_obj in app_obj_lists:
del_cache_response_by_short(app_obj.app_id)

@ -182,12 +182,15 @@ class AppInfoView(APIView):
apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first()
logger.info("app_id:%s update old data:%s" % (app_id, apps_obj.__dict__))
apps_obj.description = data.get("description", apps_obj.description)
del_cache_response_by_short(apps_obj.app_id)
apps_obj.short = data.get("short", apps_obj.short)
apps_obj.name = data.get("name", apps_obj.name)
apps_obj.password = data.get("password", apps_obj.password)
apps_obj.isshow = data.get("isshow", apps_obj.isshow)
apps_obj.wxeasytype = data.get("wxeasytype", apps_obj.wxeasytype)
if request.user.domain_name and len(request.user.domain_name) > 3:
apps_obj.wxeasytype = data.get("wxeasytype", apps_obj.wxeasytype)
else:
apps_obj.wxeasytype = 1
apps_obj.wxredirect = data.get("wxredirect", apps_obj.wxredirect)
if apps_obj.type == 1:
# 为啥注释掉,就是该udid已经在该平台使用了,虽然已经没有余额,但是其他应用也是可以超级签名的
@ -206,6 +209,7 @@ class AppInfoView(APIView):
apps_obj.issupersign = data.get("issupersign", apps_obj.issupersign)
logger.info("app_id:%s update new data:%s" % (app_id, apps_obj.__dict__))
apps_obj.save()
del_cache_response_by_short(apps_obj.app_id)
except Exception as e:
logger.error("app_id:%s update Exception:%s" % (app_id, e))
res.code = 1005
@ -213,60 +217,6 @@ class AppInfoView(APIView):
return Response(res.dict)
# def post(self, request, app_id):
# res = BaseResponse()
#
# # 获取多个file
# files = request.FILES.getlist('file', None)
# for file_obj in files:
# # 将文件缓存到本地后上传
# try:
# app_type = file_obj.name.split(".")[-1]
# if app_type in ['png', 'jpeg', 'jpg']:
# # 上传图片
# pass
# else:
# raise
# except Exception as e:
# res.code = 1003
# res.msg = "错误的类型"
# return Response(res.dict)
#
# if app_id:
# apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first()
# if apps_obj:
# release_obj = AppReleaseInfo.objects.filter(app_id=apps_obj, is_master=True).first()
# if release_obj:
#
# random_file_name = make_from_user_uuid(request.user)
# old_file_name = os.path.basename(release_obj.icon_url)
# local_file = os.path.join(settings.MEDIA_ROOT, "icons",
# random_file_name + "." + old_file_name.split(".")[1])
# # 读取传入的文件
# try:
# destination = open(local_file, 'wb+')
# for chunk in file_obj.chunks():
# # 写入本地文件
# destination.write(chunk)
# destination.close()
# except Exception as e:
# res.code = 1003
# res.msg = "数据写入失败"
# return Response(res.dict)
# release_obj.icon_url = release_obj.icon_url.replace(old_file_name.split(".")[0],
# random_file_name)
# release_obj.save()
# del_cache_response_by_short(apps_obj.short, apps_obj.app_id)
#
# storage = Storage(request.user)
# storage.delete_file(old_file_name)
#
# else:
# res.code = 1003
# else:
# res.code = 1003
# return Response(res.dict)
class AppReleaseinfoView(APIView):
authentication_classes = [ExpiringTokenAuthentication, ]

@ -10,7 +10,7 @@ from fir_ser import settings
from api.utils.TokenManager import DownloadToken
from api.utils.app.randomstrings import make_random_uuid
from api.utils.app.apputils import make_resigned
from api.utils.app.supersignutils import make_udid_mobileconfig, get_post_udid_url
from api.utils.app.supersignutils import make_udid_mobileconfig, get_post_udid_url, get_redirect_server_domain
from api.utils.storage.storage import Storage
from api.utils.storage.caches import get_app_instance_by_cache, get_download_url_by_cache, set_app_download_by_cache, \
del_cache_response_by_short
@ -120,6 +120,7 @@ class ShortDownloadView(APIView):
"storage": Storage(app_obj.user_id)})
res.data = app_serializer.data
res.udid = udid
res.domain_name = get_redirect_server_domain(request, app_obj.user_id)
return Response(res.dict)
# key的设置

@ -12,7 +12,7 @@ from api.utils.auth import ExpiringTokenAuthentication
from api.utils.response import BaseResponse
from django.middleware import csrf
from fir_ser.settings import CACHE_KEY_TEMPLATE
from api.utils.storage.caches import login_auth_failed
from api.utils.storage.caches import login_auth_failed, del_cache_storage, set_default_app_wx_easy
import logging
logger = logging.getLogger(__name__)
@ -106,12 +106,10 @@ class UserInfoView(APIView):
data = request.data
logger.info("user:%s update old data:%s" % (request.user, request.user.__dict__))
logger.info("user:%s update new data:%s" % (request.user, data))
request.user.qq = data.get("qq", request.user.qq)
request.user.job = data.get("job", request.user.job)
request.user.first_name = data.get("first_name", request.user.first_name)
oldpassword = data.get("oldpassword", None)
surepassword = data.get("surepassword", None)
if oldpassword and surepassword:
user = auth.authenticate(username=request.user.username, password=oldpassword)
if user is not None:
@ -131,6 +129,18 @@ class UserInfoView(APIView):
res.code = 1004
res.msg = "老密码校验失败"
else:
# 修改个人资料
domain_name = data.get("domain_name", None)
if domain_name and len(domain_name.strip(' ')) > 3:
request.user.domain_name = domain_name.strip(' ')
set_default_app_wx_easy(request.user)
if domain_name == '':
request.user.domain_name = None
set_default_app_wx_easy(request.user)
request.user.job = data.get("job", request.user.job)
request.user.first_name = data.get("first_name", request.user.first_name)
sms_token = data.get("sms_token", None)
if sms_token:

@ -25,6 +25,11 @@ class AppAnalyseView(APIView):
authentication_classes = [ExpiringTokenAuthentication, ]
def post(self, request):
'''
应用上传前 分析数据并返回应用上传信息
:param request:
:return:
'''
res = BaseResponse()
# 1.接收 bundelid ,返回随机应用名称和短连接
bundleid = request.data.get("bundleid", None)
@ -68,7 +73,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,
"domain_name": request.user.domain_name,
"domain_name": settings.SERVER_DOMAIN.get("FILE_UPLOAD_DOMAIN", None),
"upload_token": upload_token,
"upload_key": upload_key,
"png_token": png_token,
@ -81,6 +86,11 @@ class AppAnalyseView(APIView):
return Response(res.dict)
def put(self, request):
'''
该方法就是 应用上传完成之后的回调方法更新或者创建新应用信息
:param request:
:return:
'''
res = BaseResponse()
data = request.data
appinfo = {
@ -103,7 +113,6 @@ class AppAnalyseView(APIView):
logger.info("user %s create or update app %s data:%s" % (request.user, data.get("bundleid"), data))
if SaveAppInfos(app_new_filename, request.user, appinfo,
data.get("bundleid"), png_new_filename, data.get("short"), data.get('filesize')):
pass
# 需要将tmp 文件修改为正式文件
storage.rename_file(app_tmp_filename, app_new_filename)
storage.rename_file(png_tmp_filename, png_new_filename)
@ -127,6 +136,11 @@ class UploadView(APIView):
authentication_classes = [ExpiringTokenAuthentication, ]
def get(self, request):
'''
该方法 主要是本地上传通过该方法获取上传的 应用图片或者用户头像 的上传信息
:param request:
:return:
'''
res = BaseResponse()
storage = Storage(request.user)
request_upload_key = request.query_params.get("upload_key", None)
@ -155,12 +169,14 @@ class UploadView(APIView):
upload_key = make_from_user_uuid(request.user) + '.' + app_type
upload_token = storage.get_upload_token(upload_key)
storage_type = storage.get_storage_type()
res.data = {"domain_name": request.user.domain_name,
"upload_token": upload_token,
"upload_key": upload_key,
"storage": storage_type,
"app_id": app_id,
"ftype": ftype}
res.data = {
"domain_name": settings.SERVER_DOMAIN.get("FILE_UPLOAD_DOMAIN", None),
"upload_token": upload_token,
"upload_key": upload_key,
"storage": storage_type,
"app_id": app_id,
"ftype": ftype
}
else:
res.code = 1006
res.msg = '该应用不存在'
@ -169,6 +185,11 @@ class UploadView(APIView):
return Response(res.dict)
def post(self, request):
'''
该方法 主要是本地上传文件接口负责上传 应用图片应用文件或者用户头像
:param request:
:return:
'''
res = BaseResponse()
# 获取多个file
@ -252,11 +273,12 @@ class UploadView(APIView):
return Response(res.dict)
'''
应用图片上传之后
'''
def put(self, request):
'''
该方法就是 应用图片或者用户头像上传完成之后的回调方法为了更新上传完成的信息
:param request:
:return:
'''
res = BaseResponse()
certinfo = request.data.get('certinfo', None)
if certinfo:

@ -147,7 +147,6 @@ SUPER_SIGN_ROOT = os.path.join(BASE_DIR, "supersign")
AUTH_USER_MODEL = "api.UserInfo"
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
@ -241,15 +240,15 @@ SERVER_DOMAIN = {
'is_https': True,
}, # ios 描述文件和plist文件下载域名,该域名用于后端,一般为api访问域名
'POST_UDID_DOMAIN': 'https://fly.harmonygames.cn', # 超级签名 安装签名时 向该域名 发送udid数据,该域名用于后端,一般为 api 访问域名
'REDIRECT_UDID_DOMAIN': 'https://fly.harmonygames.cn', # 超级签名 安装完成之后,跳转域名,该域名为前端web访问域名
'REDIRECT_UDID_DOMAIN': 'https://fly.harmonygames.cn', # 超级签名 安装完成之后,跳转域名,该域名为前端web访问域名,如果用户定义了自己的域名,则跳转用户域名
'FILE_UPLOAD_DOMAIN': 'https://fly.harmonygames.cn', # 本地文件上传域名,使用本地存储必须配置
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
CAPTCHA_TIMEOUT=5 # Minutes
CAPTCHA_LENGTH= 6 # Chars
CAPTCHA_TIMEOUT = 5 # Minutes
CAPTCHA_LENGTH = 6 # Chars
BASE_LOG_DIR = os.path.join(BASE_DIR, "logs")
LOGGING = {
@ -302,4 +301,4 @@ LOGGING = {
'propagate': True,
},
},
}
}

Loading…
Cancel
Save