diff --git a/fir_client/src/components/FirAppInfossecurity.vue b/fir_client/src/components/FirAppInfossecurity.vue index 98c9da6..e2cf87a 100644 --- a/fir_client/src/components/FirAppInfossecurity.vue +++ b/fir_client/src/components/FirAppInfossecurity.vue @@ -42,7 +42,8 @@ - + 个人资料 修改密码 - 存储管理 - 超级签名 + 存储管理 + + 超级签名 + 退出 diff --git a/fir_client/src/components/FirSuperSignBase.vue b/fir_client/src/components/FirSuperSignBase.vue index fea5013..a1aa955 100644 --- a/fir_client/src/components/FirSuperSignBase.vue +++ b/fir_client/src/components/FirSuperSignBase.vue @@ -604,6 +604,7 @@ if (this.codeactiveVisible) { this.codeactiveVisible = false; } + loading.close(); }, params) }, iosdevicesudidFun(action, data) { diff --git a/fir_client/src/components/FirUserProfileBase.vue b/fir_client/src/components/FirUserProfileBase.vue index d7bd62f..049c900 100644 --- a/fir_client/src/components/FirUserProfileBase.vue +++ b/fir_client/src/components/FirUserProfileBase.vue @@ -19,7 +19,7 @@
- + - +
@@ -39,7 +39,7 @@ - +
@@ -72,6 +72,7 @@ imageUrl: '', userinfo: {}, uploadconf: {}, + tspan: 9, } }, methods: { @@ -129,7 +130,9 @@ this.$store.dispatch("doUserinfo", data.data); this.$store.dispatch('doucurrentapp', {}); this.imageUrl = data.data.head_img; - + if (this.userinfo.storage_active) { + this.tspan = 6 + } if (datainfo.data) { this.$message.success("更新成功") } diff --git a/fir_client/src/components/FirUserProfileInfo.vue b/fir_client/src/components/FirUserProfileInfo.vue index 1470e63..2ef2cc0 100644 --- a/fir_client/src/components/FirUserProfileInfo.vue +++ b/fir_client/src/components/FirUserProfileInfo.vue @@ -217,23 +217,23 @@ this.$message.error("密码至少6位"); return } - this.updateUserInfo({"methods": 'PUT', 'data': {username:this.userinfo.username}}); + this.updateUserInfo({"methods": 'PUT', 'data': {username: this.userinfo.username}}); this.changeUsernameValue() }, saveDomain() { - this.updateUserInfo({"methods": 'PUT', 'data': {domain_name:this.userinfo.domain_name}}); + this.updateUserInfo({"methods": 'PUT', 'data': {domain_name: this.userinfo.domain_name}}); this.changeDomainValue() }, savePositionValue() { - this.updateUserInfo({"methods": 'PUT', 'data': {job:this.userinfo.job}}); + this.updateUserInfo({"methods": 'PUT', 'data': {job: this.userinfo.job}}); this.changePositionValue() }, - authinfo(){ + authinfo() { return { - auth_token:this.userinfo.auth_token, - auth_key:this.userinfo.auth_key, - cptch_key:this.userinfo.cptch_key, - authcode:this.userinfo.authcode, + auth_token: this.userinfo.auth_token, + auth_key: this.userinfo.auth_key, + cptch_key: this.userinfo.cptch_key, + authcode: this.userinfo.authcode, }; }, saveemail() { @@ -283,7 +283,7 @@ }, datainfo) }, changeemailValue() { - if(this.editphone){ + if (this.editphone) { this.editphone = !this.editphone; } this.get_auth_code(); @@ -296,7 +296,7 @@ }, changePhoneValue() { - if(this.editemail){ + if (this.editemail) { this.editemail = !this.editemail; } this.get_auth_code(); diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index 0ad7365..9695e7d 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -23,6 +23,8 @@ class UserInfo(AbstractUser): mobile = models.BigIntegerField(verbose_name="手机", unique=True, help_text="用于手机验证码登录", null=True) qq = models.BigIntegerField(verbose_name="QQ", blank=True, null=True, db_index=True) is_active = models.BooleanField(default=True, verbose_name="账户状态,默认启用") + storage_active = models.BooleanField(default=False, verbose_name="配置存储,默认关闭") + supersign_active = models.BooleanField(default=False, verbose_name="配置超级签,默认关闭") job = models.TextField("职位", max_length=128, blank=True, null=True) company = models.CharField("公司", max_length=128, blank=True, null=True) @@ -36,7 +38,7 @@ class UserInfo(AbstractUser): memo = models.TextField('备注', blank=True, null=True, default=None, ) date_joined = models.DateTimeField(auto_now_add=True, verbose_name="注册时间") - download_times = models.IntegerField(default=100, 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) history_release_limit = models.IntegerField(default=10, verbose_name="app 历史记录版本", blank=True, null=True) diff --git a/fir_ser/api/utils/auth.py b/fir_ser/api/utils/auth.py index e6c871c..5d624d6 100644 --- a/fir_ser/api/utils/auth.py +++ b/fir_ser/api/utils/auth.py @@ -1,44 +1,69 @@ from django.core.cache import cache from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed -from api.models import Token, UserInfo +from api.models import UserInfo +from rest_framework.permissions import BasePermission from fir_ser.settings import CACHE_KEY_TEMPLATE import base64 +def get_user_from_auth(request): + if request.method == "OPTIONS": + return None + request_token = request.META.get("HTTP_AUTHORIZATION", request.query_params.get("token", None)) + try: + format_token = base64.b64decode(request_token).decode() + auth_token = format_token.split(":")[0] + user_name = format_token.split(":")[1] + + except Exception: + raise AuthenticationFailed({"code": 1001, "error": "token不合法"}) + + if not auth_token: + raise AuthenticationFailed({"code": 1001, "error": "缺少token"}) + + auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), auth_token]) + + cacheuserinfo = cache.get(auth_key) + if not cacheuserinfo: + raise AuthenticationFailed({"code": 1001, "error": "无效的token"}) + if user_name != cacheuserinfo.get('username', None): + raise AuthenticationFailed({"code": 1001, "error": "token校验失败"}) + + user_obj = UserInfo.objects.filter(uid=cacheuserinfo.get('uid', None), + username=cacheuserinfo.get("username")).first() + # token_obj = Token.objects.filter(access_token=auth_token).first() + if not user_obj: + raise AuthenticationFailed({"code": 1001, "error": "无效的token"}) + if user_obj.is_active: + cache.set(auth_key, cacheuserinfo, 3600 * 24 * 7) + # cache.expire(auth_key, timeout=3600 * 24 * 7) + return user_obj, auth_token + else: + raise AuthenticationFailed({"code": 1001, "error": "用户被禁用"}) + + class ExpiringTokenAuthentication(BaseAuthentication): def authenticate(self, request): - if request.method == "OPTIONS": - return None - request_token = request.META.get("HTTP_AUTHORIZATION", request.query_params.get("token", None)) - try: - format_token = base64.b64decode(request_token).decode() - auth_token = format_token.split(":")[0] - user_name = format_token.split(":")[1] - - except Exception: - raise AuthenticationFailed({"code": 1001, "error": "token不合法"}) - - if not auth_token: - raise AuthenticationFailed({"code": 1001, "error": "缺少token"}) - - auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), auth_token]) - - cacheuserinfo = cache.get(auth_key) - if not cacheuserinfo: - raise AuthenticationFailed({"code": 1001, "error": "无效的token"}) - if user_name != cacheuserinfo.get('username', None): - raise AuthenticationFailed({"code": 1001, "error": "token校验失败"}) - - user_obj = UserInfo.objects.filter(uid=cacheuserinfo.get('uid', None), - username=cacheuserinfo.get("username")).first() - # token_obj = Token.objects.filter(access_token=auth_token).first() - if not user_obj: - raise AuthenticationFailed({"code": 1001, "error": "无效的token"}) - if user_obj.is_active: - cache.set(auth_key, cacheuserinfo, 3600 * 24 * 7) - # cache.expire(auth_key, timeout=3600 * 24 * 7) - return user_obj, auth_token - else: - raise AuthenticationFailed({"code": 1001, "error": "用户被禁用"}) + return get_user_from_auth(request) + + +class StoragePermission(BasePermission): + message = "权限不足" + + def has_permission(self, request, view): + results = get_user_from_auth(request) + if results and results[0]: + return results[0].storage_active + return True + + +class SuperSignPermission(BasePermission): + message = "权限不足" + + def has_permission(self, request, view): + results = get_user_from_auth(request) + if results and results[0]: + return results[0].supersign_active + return True diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index 9d63915..64486ca 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -17,7 +17,7 @@ class UserInfoSerializer(serializers.ModelSerializer): # fields="__all__" # exclude = ["password","is_active","user_permissions","role",] fields = ["username", "uid", "mobile", "job", "email", "domain_name", "last_login", "first_name", - 'head_img'] + 'head_img', 'storage_active', 'supersign_active'] head_img = serializers.SerializerMethodField() diff --git a/fir_ser/api/utils/storage/caches.py b/fir_ser/api/utils/storage/caches.py index e7c3260..8136a5f 100644 --- a/fir_ser/api/utils/storage/caches.py +++ b/fir_ser/api/utils/storage/caches.py @@ -34,7 +34,7 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', if appudid_obj: SuperSign_obj = APPSuperSignUsedInfo.objects.filter(udid__udid=udid, app_id_id=app_obj.get("pk")).first() - if SuperSign_obj: + if SuperSign_obj and SuperSign_obj.user_id.supersign_active: APPToDeveloper_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"), developerid=SuperSign_obj.developerid).first() if APPToDeveloper_obj: diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py index c2021b6..51e21ef 100644 --- a/fir_ser/api/utils/utils.py +++ b/fir_ser/api/utils/utils.py @@ -142,7 +142,7 @@ def is_valid_email(email): return False -def get_sender_token(sender, user_id, target,action): +def get_sender_token(sender, user_id, target, action): sms_token_obj = DownloadToken() code = generateNumericTokenOfLength(6) token = sms_token_obj.make_token(code, time_limit=300, key=user_id) @@ -151,9 +151,9 @@ def get_sender_token(sender, user_id, target,action): return token, code -def get_sender_sms_token(key, phone,action): +def get_sender_sms_token(key, phone, action): sender = SendMessage('sms') - return get_sender_token(sender, key, phone,action) + return get_sender_token(sender, key, phone, action) def is_valid_sender_code(key, token, code): @@ -161,9 +161,9 @@ def is_valid_sender_code(key, token, code): return sms_token_obj.verify_token(token, code), tmpCache.get_tmp_cache(key, token) -def get_sender_email_token(key, email,action): +def get_sender_email_token(key, email, action): sender = SendMessage('email') - return get_sender_token(sender, key, email,action) + return get_sender_token(sender, key, email, action) def check_username_exists(username): diff --git a/fir_ser/api/views/login.py b/fir_ser/api/views/login.py index 5d78188..f72eb03 100644 --- a/fir_ser/api/views/login.py +++ b/fir_ser/api/views/login.py @@ -62,7 +62,7 @@ def CheckRegisterUerinfo(target, act, key): res.code = 1005 res.msg = "手机号已经存在" else: - token, code = get_sender_sms_token(act, target,'register') + token, code = get_sender_sms_token(act, target, 'register') res.data["auth_token"] = token else: res.code = 1009 @@ -79,7 +79,7 @@ def CheckRegisterUerinfo(target, act, key): res.code = 1005 res.msg = "邮箱已经存在" else: - token, code = get_sender_email_token(act, target,'register') + token, code = get_sender_email_token(act, target, 'register') res.data["auth_token"] = token else: res.code = 1009 @@ -94,7 +94,7 @@ def CheckRegisterUerinfo(target, act, key): res.code = 1005 res.msg = "用户名已经存在" else: - token, code = get_sender_email_token(act, target,'register') + token, code = get_sender_email_token(act, target, 'register') res.data["auth_token"] = token else: res.code = 1009 @@ -124,7 +124,7 @@ def CheckChangeUerinfo(target, act, key, user): res.code = 1005 res.msg = "手机号已经存在" else: - token, code = get_sender_sms_token(act, target,'change') + token, code = get_sender_sms_token(act, target, 'change') res.data["auth_token"] = token else: res.code = 1009 @@ -141,7 +141,7 @@ def CheckChangeUerinfo(target, act, key, user): res.code = 1005 res.msg = "邮箱已经存在" else: - token, code = get_sender_email_token(act, target,'change') + token, code = get_sender_email_token(act, target, 'change') res.data["auth_token"] = token else: res.code = 1009 @@ -156,7 +156,7 @@ def CheckChangeUerinfo(target, act, key, user): res.code = 1005 res.msg = "用户名已经存在" else: - token, code = get_sender_email_token(act, target,'change') + token, code = get_sender_email_token(act, target, 'change') res.data["auth_token"] = token else: res.code = 1009 diff --git a/fir_ser/api/views/receiveudids.py b/fir_ser/api/views/receiveudids.py index 8537c53..d866050 100644 --- a/fir_ser/api/views/receiveudids.py +++ b/fir_ser/api/views/receiveudids.py @@ -24,7 +24,7 @@ class IosUDIDView(View): app_info = Apps.objects.filter(short=short).first() if app_info: - if app_info.issupersign: + if app_info.issupersign and app_info.user_id.supersign_active: 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.user_id, app_info) diff --git a/fir_ser/api/views/storage.py b/fir_ser/api/views/storage.py index c1782d1..0f0103c 100644 --- a/fir_ser/api/views/storage.py +++ b/fir_ser/api/views/storage.py @@ -6,7 +6,7 @@ from rest_framework.views import APIView from api.utils.response import BaseResponse -from api.utils.auth import ExpiringTokenAuthentication +from api.utils.auth import ExpiringTokenAuthentication, StoragePermission from rest_framework.response import Response import json from api.utils.storage.caches import del_cache_storage @@ -20,6 +20,7 @@ logger = logging.getLogger(__file__) class StorageView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] + permission_classes = [StoragePermission, ] def get(self, request): res = BaseResponse() diff --git a/fir_ser/api/views/supersign.py b/fir_ser/api/views/supersign.py index 8b23785..4bebe45 100644 --- a/fir_ser/api/views/supersign.py +++ b/fir_ser/api/views/supersign.py @@ -6,7 +6,7 @@ from rest_framework.views import APIView from api.utils.response import BaseResponse -from api.utils.auth import ExpiringTokenAuthentication +from api.utils.auth import ExpiringTokenAuthentication, SuperSignPermission from rest_framework.response import Response from api.models import AppIOSDeveloperInfo, APPSuperSignUsedInfo, AppUDID from api.utils.serializer import DeveloperSerializer, SuperSignUsedSerializer, DeviceUDIDSerializer @@ -28,6 +28,7 @@ class AppsPageNumber(PageNumberPagination): class DeveloperView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] + permission_classes = [SuperSignPermission, ] def get(self, request): @@ -170,6 +171,7 @@ class DeveloperView(APIView): class SuperSignUsedView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] + permission_classes = [SuperSignPermission, ] def get(self, request): res = BaseResponse() @@ -199,6 +201,7 @@ class SuperSignUsedView(APIView): class AppUDIDUsedView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] + permission_classes = [SuperSignPermission, ] def get(self, request): res = BaseResponse()