diff --git a/fir_client/src/components/user/FirUserStorage.vue b/fir_client/src/components/user/FirUserStorage.vue index 7e9c702..ae2dae9 100644 --- a/fir_client/src/components/user/FirUserStorage.vue +++ b/fir_client/src/components/user/FirUserStorage.vue @@ -22,7 +22,7 @@ - + @@ -121,9 +121,9 @@ - - - + + + diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index 969bed5..01ed094 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -4,14 +4,13 @@ from django.db import models from api.utils.TokenManager import generate_alphanumeric_token_of_length, generate_numeric_token_of_length from api.utils.baseutils import make_random_uuid +######################################## 用户表 ######################################## +from api.utils.daobase import AESCharField # Create your models here. -######################################## 用户表 ######################################## - - class UserInfo(AbstractUser): username = models.CharField("用户名", max_length=64, unique=True) email = models.EmailField( @@ -197,7 +196,7 @@ class AppStorage(models.Model): storage_choices = ((0, '本地存储'), (1, '七牛云存储'), (2, '阿里云存储'), (3, '默认存储')) storage_type = models.SmallIntegerField(choices=storage_choices, default=3, verbose_name="存储类型") access_key = models.CharField(max_length=128, blank=True, null=True, verbose_name="存储访问key") - secret_key = models.CharField(max_length=128, blank=True, null=True, verbose_name="存储访问secret") + secret_key = AESCharField(max_length=128, blank=True, null=True, verbose_name="存储访问secret") bucket_name = models.CharField(max_length=128, blank=True, null=True, verbose_name="存储空间bucket_name") domain_name = models.CharField(max_length=128, blank=True, null=True, verbose_name="下载域名", help_text='fly-storage.dvcloud.xin,可以自定义端口') @@ -263,7 +262,8 @@ class AppIOSDeveloperInfo(models.Model): user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE) issuer_id = models.CharField(max_length=64, null=False, verbose_name="标识创建认证令牌的发放者") private_key_id = models.CharField(max_length=64, null=False, verbose_name="密钥 ID") - p8key = models.TextField(max_length=512, null=False, verbose_name="p8key") + # p8key = models.TextField(max_length=512, null=False, verbose_name="p8key") + p8key = AESCharField(max_length=512, null=False, verbose_name="p8key") is_actived = models.BooleanField(default=False, verbose_name="是否已经激活") certid = models.CharField(max_length=64, blank=True, verbose_name="超级签名自动创建证书ID", null=True) usable_number = models.IntegerField(verbose_name="可使用设备数", default=100) diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index da7ef98..68037c5 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -255,7 +255,7 @@ def get_developer_obj_by_others(user_obj, udid): return result if f_count == 0 and udid in [x.get('udid__udid__udid') for x in APPSuperSignUsedInfo.objects.filter(user_id=user_obj).values( - 'udid__udid__udid').all()]: + 'udid__udid__udid').all()]: return result return None diff --git a/fir_ser/api/utils/baseutils.py b/fir_ser/api/utils/baseutils.py index 42026c4..ad22491 100644 --- a/fir_ser/api/utils/baseutils.py +++ b/fir_ser/api/utils/baseutils.py @@ -4,13 +4,17 @@ # author: NinEveN # date: 2021/4/16 +import base64 import datetime +import hashlib import logging import os import re import time import uuid +from Crypto import Random +from Crypto.Cipher import AES from django.core.exceptions import ValidationError from django.core.validators import validate_email from django.utils import timezone @@ -21,6 +25,33 @@ from fir_ser.settings import SUPER_SIGN_ROOT, SERVER_DOMAIN logger = logging.getLogger(__name__) +class AESCipher(object): + + def __init__(self, key): + self.key = hashlib.sha256(key.encode()).digest() + + def encrypt(self, raw): + raw = self._pack_data(raw) + iv = Random.new().read(AES.block_size) + cipher = AES.new(self.key, AES.MODE_CBC, iv) + return base64.b64encode(iv + cipher.encrypt(raw)) + + def decrypt(self, enc): + enc = base64.b64decode(enc) + iv = enc[:AES.block_size] + cipher = AES.new(self.key, AES.MODE_CBC, iv) + return self._unpack_data(cipher.decrypt(enc[AES.block_size:])).decode('utf-8') + + @staticmethod + def _pack_data(s): + return s + ((AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)).encode( + 'utf-8') + + @staticmethod + def _unpack_data(s): + return s[:-ord(s[len(s) - 1:])] + + def make_from_user_uuid(userinfo): user_id = userinfo.uid random_str = uuid.uuid1().__str__().split("-")[0:-1] diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index dd46219..0333cbf 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -405,6 +405,14 @@ class StorageSerializer(serializers.ModelSerializer): download_auth_type_choices = serializers.SerializerMethodField() + # secret_key = serializers.SerializerMethodField() + # 加上此选项,会导致update获取不到值 + # def get_secret_key(self, obj): + # return '' + + # def validate_secret_key(self, secret_key): + # ... + def get_download_auth_type_choices(self, obj): return get_choices_dict(obj.download_auth_type_choices) @@ -416,6 +424,14 @@ class StorageSerializer(serializers.ModelSerializer): return storage_obj return None + def update(self, instance, validated_data): + secret_key = validated_data.get('secret_key', '') + if secret_key != "" and secret_key != instance.secret_key: + ... + else: + validated_data['secret_key'] = instance.secret_key + return super().update(instance, validated_data) + class AdminStorageSerializer(StorageSerializer): class Meta: diff --git a/fir_ser/api/views/storage.py b/fir_ser/api/views/storage.py index 957aa80..2169449 100644 --- a/fir_ser/api/views/storage.py +++ b/fir_ser/api/views/storage.py @@ -45,6 +45,7 @@ class StorageView(APIView): storage_lists = {} for storage_data in storage_data_lists: storage_type = storage_data.get("storage_type") + storage_data['secret_key'] = '' if not storage_lists.get(storage_type): storage_lists[storage_type] = [] storage_lists[storage_type].append(storage_data) diff --git a/fir_ser/cli.py b/fir_ser/cli.py index c4c36d3..e610f34 100644 --- a/fir_ser/cli.py +++ b/fir_ser/cli.py @@ -19,6 +19,7 @@ pip install oss2 pip install requests-toolbelt pip install androguard pip install qiniu +pip install requests ''' @@ -86,7 +87,6 @@ def upload_qiniuyunoss(key, token, file_path): class FLYCliSer(object): - import requests def __init__(self, fly_cli_domain, fly_cli_token): self.fly_cli_domain = fly_cli_domain @@ -97,6 +97,7 @@ class FLYCliSer(object): } def get_upload_token(self, bundleid, type): + import requests url = '%s/api/v2/fir/server/analyse' % self.fly_cli_domain data = {"bundleid": bundleid, "type": type} req = requests.post(url, json=data, headers=self._header) @@ -106,8 +107,8 @@ class FLYCliSer(object): raise AssertionError(req.text) def analyse(self, data): + import requests url = '%s/api/v2/fir/server/analyse' % self.fly_cli_domain - req = requests.put(url, json=data, headers=self._header) if req.status_code == 200: if req.json()['code'] == 1000: @@ -116,6 +117,7 @@ class FLYCliSer(object): raise AssertionError(req.text) def upload_local_storage(self, upload_key, upload_token, app_id, file_path): + import requests url = '%s/api/v2/fir/server/upload' % self.fly_cli_domain from requests_toolbelt.multipart.encoder import MultipartEncoderMonitor m = MultipartEncoderMonitor.from_fields(fields={