No Description

encrypt_views.py 8.9KB

    # -*- coding: utf-8 -*- from __future__ import division import random import re from django.conf import settings from django.db import transaction from django_logit import logit from django_response import response from pywe_marketcode import tickettocode from pywe_storage import RedisStorage from account.models import UserInfo from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo from marketcode.models import MarketCodeInfo from mch.models import ActivityInfo, BrandInfo, ConsumeShotUnbindingInfo, ModelInfo from sales.models import LotteryCampaignInfo from utils.algorithm.b64 import b64_decrypt, b64_encrypt from utils.algorithm.caesar import caesar_decrypt, caesar_encrypt from utils.algorithm.rsalg import rsa_decrypt, rsa_encrypt from utils.error.errno_utils import CiphertextStatusCode, MarketCodeStatusCode, UserStatusCode from utils.redis.connect import r WECHAT = settings.WECHAT # CIPHER_ALGORITHM = ('CAESAR', 'B64', 'RSA') CIPHER_ALGORITHM = ('CAESAR', ) CIPHER_PREFIX = { 'CAESAR': '0', 'B64': '1', 'RSA': '2', } def get_ciphertext(plaintext, optor_id, marketcode): # brand_id#model_id#distributor_id#sn#time # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224 brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#') mieli, created_at = MchInfoEncryptLogInfo.objects.get_or_create(plaintext=plaintext) if marketcode: if created_at or not mieli.code: with transaction.atomic(): marketcode = MarketCodeInfo.objects.select_for_update().filter(has_used=False).first() if not marketcode: return '' marketcode.has_used = True marketcode.save() mieli.application_id = marketcode.application_id mieli.code = marketcode.code mieli.code_url = marketcode.code_url mieli.brand_pk = brand_pk mieli.model_pk = model_pk mieli.distributor_pk = distributor_pk mieli.sn = sn mieli.operator_id = optor_id mieli.save() return mieli.code_url if created_at: alg = random.choice(CIPHER_ALGORITHM) if alg == 'CAESAR': ciphertext = caesar_encrypt(plaintext) elif alg == 'B64': ciphertext = b64_encrypt(plaintext) elif alg == 'RSA': ciphertext = rsa_encrypt(plaintext) else: ciphertext = plaintext mieli.alg = alg mieli.ciphertext = ciphertext mieli.brand_pk = brand_pk mieli.model_pk = model_pk mieli.distributor_pk = distributor_pk mieli.sn = sn mieli.operator_id = optor_id mieli.save() return u'{prefix}+{cipherlen}+{ciphertext}'.format( prefix=CIPHER_PREFIX.get(mieli.alg, ''), cipherlen=len(mieli.ciphertext), ciphertext=mieli.ciphertext, ) @logit(res=True) def encrypt(request): plaintext = request.POST.get('plaintext', '') optor_id = request.POST.get('optor_id', '') marketcode = request.POST.get('marketcode', '') return response(200, data={ 'ciphertext': get_ciphertext(plaintext, optor_id, marketcode), }) @logit(res=True) def decrypt(request, v='v2'): ciphertext = request.POST.get('ciphertext', '') try: prefix, cipherlen, ciphertext = ciphertext.split('+', 2) except Exception: return response(CiphertextStatusCode.CIPHERTEXT_INVALID) ciphertext = ciphertext[:int(cipherlen)] if prefix == CIPHER_PREFIX['CAESAR']: plaintext = caesar_decrypt(ciphertext) elif prefix == CIPHER_PREFIX['B64']: plaintext = b64_decrypt(ciphertext) elif prefix == CIPHER_PREFIX['RSA']: plaintext = rsa_decrypt(ciphertext) else: plaintext = ciphertext # brand_id#model_id#distributor_id#sn#time # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224 brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#') try: brand = BrandInfo.objects.get(pk=brand_pk) except BrandInfo.DoesNotExist: brand = None try: model = ModelInfo.objects.get(pk=model_pk) except ModelInfo.DoesNotExist: model = None mdli, created_at = MchInfoDecryptLogInfo.objects.get_or_create(ciphertext=ciphertext, defaults={ 'brand_pk': brand_pk, 'model_pk': model_pk, 'distributor_pk': distributor_pk, 'sn': sn, 'decrypt_count': 1, }) if not created_at: mdli.decrypt_count += 1 mdli.save() unbound = ConsumeShotUnbindingInfo.objects.filter(model_id=model.model_id, sn=sn, status=True).exists() # 弃用老版本的劵形式,和会员系统统一 if v == 'v1': has_unexpired_activity = False coupon_infos = {} else: activities = ActivityInfo.objects.filter(status=True).order_by('-pk') coupon_infos = [act.coupon_info3 for act in activities if act and act.has_unexpired_activity(model.model_name)] lotterys = LotteryCampaignInfo.objects.filter(status=True) if lotterys.exists(): active_lotterys = [lottery.data for lottery in lotterys if lottery.is_active()] else: active_lotterys = None return response(200, data={ 'plaintext': plaintext, 'lotterys': active_lotterys, 'logo_url': brand.brand_logo_url if brand else '', 'model_imgs': model.images if model else [], 'code_version': 1, 'goodsInfo': { 'BrandID': brand_pk, 'Brand': brand.brand_name if brand else '', 'ModelID': model_pk, 'Model': (model.model_full_name or model.model_name) if model else '', 'DistributorID': distributor_pk, 'SerialNo': sn, 'img': model.imgdata1 if model else '', 'img2': model.imgdata if model else {}, }, 'has_unexpired_activity': False, 'coupon_infos': coupon_infos, 'unbound': unbound, }) @logit(res=True) def decrypt2(request, v='v2'): code_ticket = request.POST.get('code_ticket', '') code = request.POST.get('code', '') user_id = request.POST.get('user_id', '') if code_ticket and user_id: try: user = UserInfo.objects.get(user_id=user_id) except UserInfo.DoesNotExist: return response(UserStatusCode.USER_NOT_FOUND) wxcfg = WECHAT.get('JSAPI', {}) appid = wxcfg.get('appID') secret = wxcfg.get('appsecret') code_info = tickettocode(code_ticket=code_ticket, openid=user.openid_miniapp, appid=appid, secret=secret, token=None, storage=RedisStorage(r)) code = code_info.get('code', '') try: mieli = MchInfoEncryptLogInfo.objects.get(code=code) except MchInfoEncryptLogInfo.DoesNotExist: return response() else: code = re.sub(r'http://|https://', '', code) try: mieli = MchInfoEncryptLogInfo.objects.get(code_url=code) except MchInfoEncryptLogInfo.DoesNotExist: return response() plaintext = mieli.plaintext # brand_id#model_id#distributor_id#sn#time # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224 brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#') try: brand = BrandInfo.objects.get(pk=brand_pk) except BrandInfo.DoesNotExist: brand = None try: model = ModelInfo.objects.get(pk=model_pk) except ModelInfo.DoesNotExist: model = None mdli, created_at = MchInfoDecryptLogInfo.objects.get_or_create( application_id=mieli.application_id, code=mieli.code, code_url=mieli.code_url, defaults={ 'brand_pk': brand_pk, 'model_pk': model_pk, 'distributor_pk': distributor_pk, 'sn': sn, 'decrypt_count': 1, } ) if not created_at: mdli.decrypt_count += 1 mdli.save() unbound = ConsumeShotUnbindingInfo.objects.filter(model_id=model.model_id, sn=sn, status=True).exists() if v == 'v1': has_unexpired_activity = False coupon_infos = {} else: activities = ActivityInfo.objects.filter(status=True).order_by('-pk') coupon_infos = [act.coupon_info3 for act in activities if act.has_unexpired_activity(model.model_name)] return response(200, data={ 'plaintext': plaintext, 'logo_url': brand.brand_logo_url if brand else '', 'model_imgs': model.images if model else [], 'code_version': mieli.version, 'goodsInfo': { 'BrandID': brand_pk, 'Brand': brand.brand_name if brand else '', 'ModelID': model_pk, 'Model': (model.model_full_name or model.model_name) if model else '', 'DistributorID': distributor_pk, 'SerialNo': sn, 'img': model.imgdata1 if model else '', 'img2': model.imgdata if model else {}, }, 'has_unexpired_activity': False, 'coupon_infos': coupon_infos, 'unbound': unbound, })