core_views.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. #coding=utf-8
  2. '''
  3. '''
  4. import json
  5. import logging
  6. import re
  7. import traceback
  8. import datetime
  9. import hashlib
  10. from django import http
  11. from django.contrib.sessions.backends.cache import SessionStore
  12. from django.core.cache import cache
  13. from django.http import HttpResponse, JsonResponse
  14. from django.shortcuts import render
  15. from django.utils.decorators import method_decorator
  16. from django.views import View
  17. from django.views.decorators.csrf import csrf_exempt
  18. from django.core.serializers.json import DjangoJSONEncoder
  19. from common import error_info
  20. from common.models import UserInfo
  21. import common.error_info as ce
  22. logger = logging.getLogger(__name__)
  23. class CusDjangoJSONEncoder(json.JSONEncoder):
  24. """
  25. JSONEncoder subclass that knows how to encode date/time, decimal types and UUIDs.
  26. """
  27. def default(self, o):
  28. # See "Date Time String Format" in the ECMA-262 specification.
  29. if isinstance(o, datetime.datetime):
  30. r = datetime.datetime.strftime(o,'%Y-%m-%d %H:%M:%S')
  31. return r
  32. elif isinstance(o, datetime.date):
  33. return o.isoformat()
  34. elif isinstance(o, datetime.time):
  35. if is_aware(o):
  36. raise ValueError("JSON can't represent timezone-aware times.")
  37. r = o.isoformat()
  38. if o.microsecond:
  39. r = r[:12]
  40. return r
  41. elif isinstance(o, datetime.timedelta):
  42. return duration_iso_string(o)
  43. elif isinstance(o, decimal.Decimal):
  44. return str(o)
  45. elif isinstance(o, uuid.UUID):
  46. return str(o)
  47. elif isinstance(o, Promise):
  48. return six.text_type(o)
  49. elif isinstance(o, CallableBool):
  50. return bool(o)
  51. else:
  52. return super(DjangoJSONEncoder, self).default(o)
  53. class SignView(View):
  54. """
  55. """
  56. def __init__(self):
  57. self.client_id = "1088"
  58. self.client_key = "3dea5896-0a5e-453f-821e-4db555c7cdb4"
  59. def get_ip(self,request):
  60. if request.META.has_key('HTTP_X_REAL_IP'):
  61. ip = request.META['HTTP_X_REAL_IP']
  62. elif request.META.has_key('HTTP_X_FORWARDED_FOR'):
  63. ip = request.META['HTTP_X_FORWARDED_FOR']
  64. else:
  65. ip = request.META['REMOTE_ADDR']
  66. return ip
  67. def gen_sign(self,params):
  68. """
  69. """
  70. params.pop("sign")
  71. keys = params.keys()
  72. keys.sort()
  73. signstr = ""
  74. for key in keys:
  75. signstr += u"{}={}&".format(key,params.get(key))
  76. signstr += "key={}".format(self.client_key)
  77. md5 = hashlib.md5(signstr).hexdigest().upper()
  78. return md5
  79. def check_auth(self,handler,request,*args,**kwargs):
  80. """鉴权
  81. """
  82. params = request.json
  83. sign = params.get("sign")
  84. if self.gen_sign(params) != sign:
  85. return JsonResponse({"status":"error","message":u"签名错误,sign的值错误!"})
  86. return handler(request,*args,**kwargs)
  87. @method_decorator(csrf_exempt)
  88. def dispatch(self, request, *args, **kwargs):
  89. """
  90. """
  91. if request.method.lower() in self.http_method_names:
  92. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  93. body = request.body if hasattr(request, "body") else ""
  94. if request.content_type == "application/x-www-form-urlencoded":
  95. info = http.QueryDict(body)
  96. elif request.content_type == "application/json":
  97. info = json.loads(body) if body else {}
  98. else:
  99. info = {}
  100. setattr(request, "json", info)
  101. else:
  102. handler = self.http_method_not_allowed
  103. return self.check_auth(handler,request,*args,**kwargs)
  104. class AuthView(View):
  105. @method_decorator(csrf_exempt)
  106. def dispatch(self, request, *args, **kwargs):
  107. """
  108. @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
  109. """
  110. if request.method.lower() in self.http_method_names:
  111. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  112. else:
  113. handler = self.http_method_not_allowed
  114. return api_wapper(handler, request, True, *args, **kwargs)
  115. class AdminView(View):
  116. @method_decorator(csrf_exempt)
  117. def dispatch(self, request, *args, **kwargs):
  118. """
  119. @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
  120. """
  121. self.http_method_names.append("options")
  122. if request.method.lower() in self.http_method_names:
  123. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  124. else:
  125. handler = self.http_method_not_allowed
  126. return admin_handler(handler, request, True, *args, **kwargs)
  127. class BaseView(View):
  128. @method_decorator(csrf_exempt)
  129. def dispatch(self, request, *args, **kwargs):
  130. """
  131. @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
  132. """
  133. if request.method.lower() in self.http_method_names:
  134. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  135. else:
  136. handler = self.http_method_not_allowed
  137. return api_wapper(handler, request, False, *args, **kwargs)
  138. class UploadView(View):
  139. @method_decorator(csrf_exempt)
  140. def dispatch(self, request, *args, **kwargs):
  141. """
  142. @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
  143. """
  144. if request.method.lower() in self.http_method_names:
  145. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  146. else:
  147. handler = self.http_method_not_allowed
  148. return upload_wapper(handler,request,True, *args, **kwargs)
  149. class InnerView(View):
  150. @method_decorator(csrf_exempt)
  151. def dispatch(self, request, *args, **kwargs):
  152. """
  153. @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
  154. """
  155. if request.method.lower() in self.http_method_names:
  156. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  157. if request.META.get("HTTP_TOKEN") != "7dpHIhpweckghdoSvrXwMftcjZRIzKwJ":
  158. handler = self.http_method_not_allowed
  159. else:
  160. handler = self.http_method_not_allowed
  161. return api_wapper(handler, request, False, *args, **kwargs)
  162. def show_history(request):
  163. logined_history = cache.get("logined_history", {})
  164. for k, v in logined_history.iteritems():
  165. logger.info("k: %s, v: %s", str(k), str(v))
  166. logger.info("current session: %s", str(request.session.session_key))
  167. ss = SessionStore(request.session.session_key)
  168. for k, v in ss.iteritems():
  169. logger.info("k: %s, v: %s", str(k), str(v))
  170. def api_wapper(handler, request, is_vauth, *args, **kwargs):
  171. """
  172. @attention: 调试API时使用的装饰器
  173. """
  174. req_path = request.META["PATH_INFO"]
  175. ip = request.META.get("HTTP_X_REAL_IP","")
  176. openid = request.META.get("HTTP_OPENID")
  177. user = UserInfo.objects.filter(openid=openid).first()
  178. #if is_vauth and not request.user.is_authenticated():
  179. if is_vauth and not user:
  180. return HttpResponse(status=403)
  181. body = request.body if hasattr(request, "body") else ""
  182. if "x-www-form-urlencoded" in request.content_type:
  183. info = http.QueryDict(body).dict()
  184. if not info:
  185. info = request.GET.dict()
  186. elif "application/json" in request.content_type:
  187. info = json.loads(body) if body else {}
  188. if not info:
  189. info = request.GET.dict()
  190. else:
  191. try:
  192. info = json.loads(body) if body else {}
  193. if not info:
  194. info = request.GET.dict()
  195. except:
  196. info = {}
  197. print 66666666666666666666666
  198. setattr(request, "json", info)
  199. setattr(request, "ip", get_ip(request))
  200. setattr(request, "user", user)
  201. if request.method == "OPTIONS":
  202. return JsonResponse({})
  203. try:
  204. ret = handler(request, *args, **kwargs)
  205. return ret
  206. except Exception as e:
  207. return to_fail(e)
  208. def admin_handler(handler, request, is_vauth, *args, **kwargs):
  209. """
  210. 登录session校验
  211. """
  212. req_path = request.META["PATH_INFO"]
  213. ip = request.META.get("HTTP_X_REAL_IP","")
  214. print request.META,9999
  215. openid = request.META.get("HTTP_OPENID")
  216. user = UserInfo.objects.filter(openid=openid).first()
  217. if is_vauth and not request.user.is_authenticated():
  218. return HttpResponse(status=403)
  219. body = request.body if hasattr(request, "body") else ""
  220. if "x-www-form-urlencoded" in request.content_type:
  221. info = http.QueryDict(body).dict()
  222. if not info:
  223. info = request.GET.dict()
  224. elif "application/json" in request.content_type:
  225. info = json.loads(body) if body else {}
  226. if not info:
  227. info = request.GET.dict()
  228. else:
  229. try:
  230. info = json.loads(body) if body else {}
  231. if not info:
  232. info = request.GET.dict()
  233. except:
  234. info = {}
  235. setattr(request, "json", info)
  236. setattr(request, "ip", get_ip(request))
  237. #setattr(request, "user", user)
  238. try:
  239. ret = handler(request, *args, **kwargs)
  240. return ret
  241. except Exception as e:
  242. return to_fail(e)
  243. def upload_wapper(handler,request,is_vauth, *args, **kwargs):
  244. """
  245. @attention: 上传使用
  246. """
  247. logger.info("request.GET: %s", str(request.GET))
  248. if is_vauth and (not request.user.is_authenticated()):
  249. return to_redirect("/")
  250. info = {}
  251. setattr(request, "json", info)
  252. setattr(request, "ip", get_ip(request))
  253. try:
  254. ret = handler(request, *args, **kwargs)
  255. logger.info("ret: %s", str(ret.content))
  256. return ret
  257. except error_info.TipException as e:
  258. return to_normal_fail(e.msg)
  259. except le.ReasonException as e:
  260. # operation log here
  261. user = request.user
  262. name = user.realname
  263. email = user.name
  264. return to_normal_fail(e.msg)
  265. except le.SpecialReasonException as e:
  266. user = request.user
  267. name = user.realname
  268. email = user.name
  269. e.inner_info.update({'reason': e.msg})
  270. return to_normal_fail(e.msg)
  271. except:
  272. traceback.print_exc()
  273. return to_normal_fail("system error!")
  274. def to_suc(data={}):
  275. info = {}
  276. info["data"] = data
  277. info["code"] = 0
  278. return JsonResponse(info,encoder=CusDjangoJSONEncoder)
  279. def to_suc_msg(data={},msg=""):
  280. info = {}
  281. info["data"] = data
  282. info["msg"] = msg
  283. info["status"] = "suc"
  284. return JsonResponse(info)
  285. def to_normal_fail(msg=""):
  286. info = {}
  287. info["code"] = 1000
  288. info["message"] = msg
  289. return JsonResponse(info)
  290. def to_fail(e=None):
  291. info = {}
  292. info["code"] = 1000
  293. if isinstance(e,ce.TipException):
  294. info["message"] = e.msg
  295. else:
  296. info["message"] = str(e)
  297. return JsonResponse(info)
  298. def to_redirect(curl):
  299. info = {}
  300. info["status"] = "red"
  301. info["url"] = curl
  302. return JsonResponse(info)
  303. def to_render(request,template,data={}):
  304. return render(request,template,data)
  305. def raw_json(data):
  306. return JsonResponse(data, safe=False)
  307. def tracefail():
  308. traceback.print_exc()
  309. EXCEL_TYPE = "application/vnd.ms-excel"
  310. def stream_file(content, content_type, file_name):
  311. """
  312. 输出文件
  313. :param content: 内容 StringIO 类型
  314. :param content_type: 类型 eg: "application/vnd.ms-excel"
  315. :param file_name: 文件名(需指定后缀)
  316. """
  317. response = HttpResponse(content=content, content_type=content_type)
  318. response['Content-Disposition'] = 'attachment; filename={}'.format(file_name)
  319. return response
  320. def check_permission(*codes):
  321. code_set = set(codes)
  322. def function_wapper(fn):
  323. def wapper(cls, request, *args, **kargs):
  324. try:
  325. user = UserInfo.objects.filter(pk=request.user.id).first()
  326. plist = json.loads(user.role.permission_codes) if user else []
  327. except Exception as e:
  328. plist = []
  329. pset = set(plist)
  330. #logger.info("have permission: %s, need permission: %s", str(plist), str(code_set))
  331. flag = True
  332. for code in code_set:
  333. res = filter(lambda item: re.match(item, code), pset)
  334. if not (code in code_set):
  335. flag = False
  336. break
  337. if flag:
  338. return fn(cls, request, *args, **kargs)
  339. else:
  340. return to_normal_fail(u"该用户没有此操作权限")
  341. return wapper
  342. return function_wapper
  343. def get_ip(request):
  344. if request.META.has_key('HTTP_X_REAL_IP'):
  345. ip = request.META['HTTP_X_REAL_IP']
  346. elif request.META.has_key('HTTP_X_FORWARDED_FOR'):
  347. ip = request.META['HTTP_X_FORWARDED_FOR']
  348. else:
  349. ip = request.META['REMOTE_ADDR']
  350. return ip