No Description

encrypt_views.py 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. import random
  4. import re
  5. from django.conf import settings
  6. from django.db import transaction
  7. from django_logit import logit
  8. from django_response import response
  9. from pywe_marketcode import tickettocode
  10. from pywe_storage import RedisStorage
  11. from account.models import UserInfo
  12. from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo
  13. from marketcode.models import MarketCodeInfo
  14. from mch.models import ActivityInfo, BrandInfo, ModelInfo, ConsumeShotUnbindingInfo
  15. from utils.algorithm.b64 import b64_decrypt, b64_encrypt
  16. from utils.algorithm.caesar import caesar_decrypt, caesar_encrypt
  17. from utils.algorithm.rsalg import rsa_decrypt, rsa_encrypt
  18. from utils.error.errno_utils import MarketCodeStatusCode, UserStatusCode
  19. from utils.redis.connect import r
  20. WECHAT = settings.WECHAT
  21. # CIPHER_ALGORITHM = ('CAESAR', 'B64', 'RSA')
  22. CIPHER_ALGORITHM = ('CAESAR', )
  23. CIPHER_PREFIX = {
  24. 'CAESAR': '0',
  25. 'B64': '1',
  26. 'RSA': '2',
  27. }
  28. def get_ciphertext(plaintext, optor_id, marketcode):
  29. # brand_id#model_id#distributor_id#sn#time
  30. # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224
  31. brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#')
  32. mieli, created_at = MchInfoEncryptLogInfo.objects.get_or_create(plaintext=plaintext)
  33. if marketcode:
  34. if created_at or not mieli.code:
  35. with transaction.atomic():
  36. marketcode = MarketCodeInfo.objects.select_for_update().filter(has_used=False).first()
  37. if not marketcode:
  38. return ''
  39. marketcode.has_used = True
  40. marketcode.save()
  41. mieli.application_id = marketcode.application_id
  42. mieli.code = marketcode.code
  43. mieli.code_url = marketcode.code_url
  44. mieli.brand_pk = brand_pk
  45. mieli.model_pk = model_pk
  46. mieli.distributor_pk = distributor_pk
  47. mieli.sn = sn
  48. mieli.operator_id = optor_id
  49. mieli.save()
  50. return mieli.code_url
  51. if created_at:
  52. alg = random.choice(CIPHER_ALGORITHM)
  53. if alg == 'CAESAR':
  54. ciphertext = caesar_encrypt(plaintext)
  55. elif alg == 'B64':
  56. ciphertext = b64_encrypt(plaintext)
  57. elif alg == 'RSA':
  58. ciphertext = rsa_encrypt(plaintext)
  59. else:
  60. ciphertext = plaintext
  61. mieli.alg = alg
  62. mieli.ciphertext = ciphertext
  63. mieli.brand_pk = brand_pk
  64. mieli.model_pk = model_pk
  65. mieli.distributor_pk = distributor_pk
  66. mieli.sn = sn
  67. mieli.operator_id = optor_id
  68. mieli.save()
  69. return u'{prefix}+{cipherlen}+{ciphertext}'.format(
  70. prefix=CIPHER_PREFIX.get(mieli.alg, ''),
  71. cipherlen=len(mieli.ciphertext),
  72. ciphertext=mieli.ciphertext,
  73. )
  74. @logit(res=True)
  75. def encrypt(request):
  76. plaintext = request.POST.get('plaintext', '')
  77. optor_id = request.POST.get('optor_id', '')
  78. marketcode = request.POST.get('marketcode', '')
  79. return response(200, data={
  80. 'ciphertext': get_ciphertext(plaintext, optor_id, marketcode),
  81. })
  82. @logit(res=True)
  83. def decrypt(request, v='v2'):
  84. ciphertext = request.POST.get('ciphertext', '')
  85. prefix, cipherlen, ciphertext = ciphertext.split('+', 2)
  86. ciphertext = ciphertext[:int(cipherlen)]
  87. if prefix == CIPHER_PREFIX['CAESAR']:
  88. plaintext = caesar_decrypt(ciphertext)
  89. elif prefix == CIPHER_PREFIX['B64']:
  90. plaintext = b64_decrypt(ciphertext)
  91. elif prefix == CIPHER_PREFIX['RSA']:
  92. plaintext = rsa_decrypt(ciphertext)
  93. else:
  94. plaintext = ciphertext
  95. # brand_id#model_id#distributor_id#sn#time
  96. # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224
  97. brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#')
  98. try:
  99. brand = BrandInfo.objects.get(pk=brand_pk)
  100. except BrandInfo.DoesNotExist:
  101. brand = None
  102. try:
  103. model = ModelInfo.objects.get(pk=model_pk)
  104. except ModelInfo.DoesNotExist:
  105. model = None
  106. mdli, created_at = MchInfoDecryptLogInfo.objects.get_or_create(ciphertext=ciphertext, defaults={
  107. 'brand_pk': brand_pk,
  108. 'model_pk': model_pk,
  109. 'distributor_pk': distributor_pk,
  110. 'sn': sn,
  111. 'decrypt_count': 1,
  112. })
  113. if not created_at:
  114. mdli.decrypt_count += 1
  115. mdli.save()
  116. unbound = ConsumeShotUnbindingInfo.objects.filter(model_id=model.model_id, sn=sn, status=True).exists()
  117. # 弃用老版本的劵形式,和会员系统统一
  118. if v == 'v1':
  119. has_unexpired_activity = False
  120. coupon_infos = {}
  121. else:
  122. activities = ActivityInfo.objects.filter(status=True).order_by('-pk')
  123. coupon_infos = [act.coupon_info3 for act in activities if act and act.has_unexpired_activity(model.model_uni_name)]
  124. return response(200, data={
  125. 'plaintext': plaintext,
  126. 'logo_url': brand.brand_logo_url if brand else '',
  127. 'model_imgs': model.images if model else [],
  128. 'code_version': 1,
  129. 'goodsInfo': {
  130. 'BrandID': brand_pk,
  131. 'Brand': brand.brand_name if brand else '',
  132. 'ModelID': model_pk,
  133. 'Model': (model.model_full_name or model.model_name) if model else '',
  134. 'DistributorID': distributor_pk,
  135. 'SerialNo': sn,
  136. 'img': model.imgdata1 if model else '',
  137. 'img2': model.imgdata if model else {},
  138. },
  139. 'has_unexpired_activity': False,
  140. 'coupon_infos': coupon_infos,
  141. 'unbound': unbound,
  142. })
  143. @logit(res=True)
  144. def decrypt2(request, v='v2'):
  145. code_ticket = request.POST.get('code_ticket', '')
  146. code = request.POST.get('code', '')
  147. user_id = request.POST.get('user_id', '')
  148. if code_ticket and user_id:
  149. try:
  150. user = UserInfo.objects.get(user_id=user_id)
  151. except UserInfo.DoesNotExist:
  152. return response(UserStatusCode.USER_NOT_FOUND)
  153. wxcfg = WECHAT.get('JSAPI', {})
  154. appid = wxcfg.get('appID')
  155. secret = wxcfg.get('appsecret')
  156. code_info = tickettocode(code_ticket=code_ticket, openid=user.openid_miniapp, appid=appid, secret=secret, token=None, storage=RedisStorage(r))
  157. code = code_info.get('code', '')
  158. try:
  159. mieli = MchInfoEncryptLogInfo.objects.get(code=code)
  160. except MchInfoEncryptLogInfo.DoesNotExist:
  161. return response()
  162. else:
  163. code = re.sub(r'http://|https://', '', code)
  164. try:
  165. mieli = MchInfoEncryptLogInfo.objects.get(code_url=code)
  166. except MchInfoEncryptLogInfo.DoesNotExist:
  167. return response()
  168. plaintext = mieli.plaintext
  169. # brand_id#model_id#distributor_id#sn#time
  170. # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224
  171. brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#')
  172. try:
  173. brand = BrandInfo.objects.get(pk=brand_pk)
  174. except BrandInfo.DoesNotExist:
  175. brand = None
  176. try:
  177. model = ModelInfo.objects.get(pk=model_pk)
  178. except ModelInfo.DoesNotExist:
  179. model = None
  180. mdli, created_at = MchInfoDecryptLogInfo.objects.get_or_create(
  181. application_id=mieli.application_id,
  182. code=mieli.code,
  183. code_url=mieli.code_url,
  184. defaults={
  185. 'brand_pk': brand_pk,
  186. 'model_pk': model_pk,
  187. 'distributor_pk': distributor_pk,
  188. 'sn': sn,
  189. 'decrypt_count': 1,
  190. }
  191. )
  192. if not created_at:
  193. mdli.decrypt_count += 1
  194. mdli.save()
  195. unbound = ConsumeShotUnbindingInfo.objects.filter(model_id=model.model_id, sn=sn, status=True).exists()
  196. if v == 'v1':
  197. has_unexpired_activity = False
  198. coupon_infos = {}
  199. else:
  200. activities = ActivityInfo.objects.filter(status=True).order_by('-pk')
  201. coupon_infos = [act.coupon_info3 for act in activities if act.has_unexpired_activity(model.model_uni_name)]
  202. return response(200, data={
  203. 'plaintext': plaintext,
  204. 'logo_url': brand.brand_logo_url if brand else '',
  205. 'model_imgs': model.images if model else [],
  206. 'code_version': mieli.version,
  207. 'goodsInfo': {
  208. 'BrandID': brand_pk,
  209. 'Brand': brand.brand_name if brand else '',
  210. 'ModelID': model_pk,
  211. 'Model': (model.model_full_name or model.model_name) if model else '',
  212. 'DistributorID': distributor_pk,
  213. 'SerialNo': sn,
  214. 'img': model.imgdata1 if model else '',
  215. 'img2': model.imgdata if model else {},
  216. },
  217. 'has_unexpired_activity': False,
  218. 'coupon_infos': coupon_infos,
  219. 'unbound': unbound,
  220. })