#coding=utf-8 ''' ''' import json import logging import re import traceback import datetime import hashlib from django import http from django.contrib.sessions.backends.cache import SessionStore from django.core.cache import cache from django.http import HttpResponse, JsonResponse from django.shortcuts import render from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.csrf import csrf_exempt from django.core.serializers.json import DjangoJSONEncoder from common import error_info from common.models import UserInfo import common.error_info as ce logger = logging.getLogger(__name__) class CusDjangoJSONEncoder(json.JSONEncoder): """ JSONEncoder subclass that knows how to encode date/time, decimal types and UUIDs. """ def default(self, o): # See "Date Time String Format" in the ECMA-262 specification. if isinstance(o, datetime.datetime): r = datetime.datetime.strftime(o,'%Y-%m-%d %H:%M:%S') return r elif isinstance(o, datetime.date): return o.isoformat() elif isinstance(o, datetime.time): if is_aware(o): raise ValueError("JSON can't represent timezone-aware times.") r = o.isoformat() if o.microsecond: r = r[:12] return r elif isinstance(o, datetime.timedelta): return duration_iso_string(o) elif isinstance(o, decimal.Decimal): return str(o) elif isinstance(o, uuid.UUID): return str(o) elif isinstance(o, Promise): return six.text_type(o) elif isinstance(o, CallableBool): return bool(o) else: return super(DjangoJSONEncoder, self).default(o) class SignView(View): """ """ def __init__(self): self.client_id = "1088" self.client_key = "3dea5896-0a5e-453f-821e-4db555c7cdb4" def get_ip(self,request): if request.META.has_key('HTTP_X_REAL_IP'): ip = request.META['HTTP_X_REAL_IP'] elif request.META.has_key('HTTP_X_FORWARDED_FOR'): ip = request.META['HTTP_X_FORWARDED_FOR'] else: ip = request.META['REMOTE_ADDR'] return ip def gen_sign(self,params): """ """ params.pop("sign") keys = params.keys() keys.sort() signstr = "" for key in keys: signstr += u"{}={}&".format(key,params.get(key)) signstr += "key={}".format(self.client_key) md5 = hashlib.md5(signstr).hexdigest().upper() return md5 def check_auth(self,handler,request,*args,**kwargs): """鉴权 """ params = request.json sign = params.get("sign") if self.gen_sign(params) != sign: return JsonResponse({"status":"error","message":u"签名错误,sign的值错误!"}) return handler(request,*args,**kwargs) @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): """ """ if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) body = request.body if hasattr(request, "body") else "" if request.content_type == "application/x-www-form-urlencoded": info = http.QueryDict(body) elif request.content_type == "application/json": info = json.loads(body) if body else {} else: info = {} setattr(request, "json", info) else: handler = self.http_method_not_allowed return self.check_auth(handler,request,*args,**kwargs) class AuthView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): """ @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验 """ if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return api_wapper(handler, request, True, *args, **kwargs) class AdminView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): """ @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验 """ self.http_method_names.append("options") if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return admin_handler(handler, request, True, *args, **kwargs) class BaseView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): """ @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验 """ if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return api_wapper(handler, request, False, *args, **kwargs) class UploadView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): """ @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验 """ if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return upload_wapper(handler,request,True, *args, **kwargs) class InnerView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): """ @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验 """ if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) if request.META.get("HTTP_TOKEN") != "7dpHIhpweckghdoSvrXwMftcjZRIzKwJ": handler = self.http_method_not_allowed else: handler = self.http_method_not_allowed return api_wapper(handler, request, False, *args, **kwargs) def show_history(request): logined_history = cache.get("logined_history", {}) for k, v in logined_history.iteritems(): logger.info("k: %s, v: %s", str(k), str(v)) logger.info("current session: %s", str(request.session.session_key)) ss = SessionStore(request.session.session_key) for k, v in ss.iteritems(): logger.info("k: %s, v: %s", str(k), str(v)) def api_wapper(handler, request, is_vauth, *args, **kwargs): """ @attention: 调试API时使用的装饰器 """ req_path = request.META["PATH_INFO"] ip = request.META.get("HTTP_X_REAL_IP","") openid = request.META.get("HTTP_OPENID") user = UserInfo.objects.filter(openid=openid).first() #if is_vauth and not request.user.is_authenticated(): if is_vauth and not user: return HttpResponse(status=403) body = request.body if hasattr(request, "body") else "" if "x-www-form-urlencoded" in request.content_type: info = http.QueryDict(body).dict() if not info: info = request.GET.dict() elif "application/json" in request.content_type: info = json.loads(body) if body else {} if not info: info = request.GET.dict() else: try: info = json.loads(body) if body else {} if not info: info = request.GET.dict() except: info = {} print 66666666666666666666666 setattr(request, "json", info) setattr(request, "ip", get_ip(request)) setattr(request, "user", user) if request.method == "OPTIONS": return JsonResponse({}) try: ret = handler(request, *args, **kwargs) return ret except Exception as e: return to_fail(e) def admin_handler(handler, request, is_vauth, *args, **kwargs): """ 登录session校验 """ req_path = request.META["PATH_INFO"] ip = request.META.get("HTTP_X_REAL_IP","") print request.META,9999 openid = request.META.get("HTTP_OPENID") user = UserInfo.objects.filter(openid=openid).first() if is_vauth and not request.user.is_authenticated(): return HttpResponse(status=403) body = request.body if hasattr(request, "body") else "" if "x-www-form-urlencoded" in request.content_type: info = http.QueryDict(body).dict() if not info: info = request.GET.dict() elif "application/json" in request.content_type: info = json.loads(body) if body else {} if not info: info = request.GET.dict() else: try: info = json.loads(body) if body else {} if not info: info = request.GET.dict() except: info = {} setattr(request, "json", info) setattr(request, "ip", get_ip(request)) #setattr(request, "user", user) try: ret = handler(request, *args, **kwargs) return ret except Exception as e: return to_fail(e) def upload_wapper(handler,request,is_vauth, *args, **kwargs): """ @attention: 上传使用 """ logger.info("request.GET: %s", str(request.GET)) if is_vauth and (not request.user.is_authenticated()): return to_redirect("/") info = {} setattr(request, "json", info) setattr(request, "ip", get_ip(request)) try: ret = handler(request, *args, **kwargs) logger.info("ret: %s", str(ret.content)) return ret except error_info.TipException as e: return to_normal_fail(e.msg) except le.ReasonException as e: # operation log here user = request.user name = user.realname email = user.name return to_normal_fail(e.msg) except le.SpecialReasonException as e: user = request.user name = user.realname email = user.name e.inner_info.update({'reason': e.msg}) return to_normal_fail(e.msg) except: traceback.print_exc() return to_normal_fail("system error!") def to_suc(data={}): info = {} info["data"] = data info["code"] = 0 return JsonResponse(info,encoder=CusDjangoJSONEncoder) def to_suc_msg(data={},msg=""): info = {} info["data"] = data info["msg"] = msg info["status"] = "suc" return JsonResponse(info) def to_normal_fail(msg=""): info = {} info["code"] = 1000 info["message"] = msg return JsonResponse(info) def to_fail(e=None): info = {} info["code"] = 1000 if isinstance(e,ce.TipException): info["message"] = e.msg else: info["message"] = str(e) return JsonResponse(info) def to_redirect(curl): info = {} info["status"] = "red" info["url"] = curl return JsonResponse(info) def to_render(request,template,data={}): return render(request,template,data) def raw_json(data): return JsonResponse(data, safe=False) def tracefail(): traceback.print_exc() EXCEL_TYPE = "application/vnd.ms-excel" def stream_file(content, content_type, file_name): """ 输出文件 :param content: 内容 StringIO 类型 :param content_type: 类型 eg: "application/vnd.ms-excel" :param file_name: 文件名(需指定后缀) """ response = HttpResponse(content=content, content_type=content_type) response['Content-Disposition'] = 'attachment; filename={}'.format(file_name) return response def check_permission(*codes): code_set = set(codes) def function_wapper(fn): def wapper(cls, request, *args, **kargs): try: user = UserInfo.objects.filter(pk=request.user.id).first() plist = json.loads(user.role.permission_codes) if user else [] except Exception as e: plist = [] pset = set(plist) #logger.info("have permission: %s, need permission: %s", str(plist), str(code_set)) flag = True for code in code_set: res = filter(lambda item: re.match(item, code), pset) if not (code in code_set): flag = False break if flag: return fn(cls, request, *args, **kargs) else: return to_normal_fail(u"该用户没有此操作权限") return wapper return function_wapper def get_ip(request): if request.META.has_key('HTTP_X_REAL_IP'): ip = request.META['HTTP_X_REAL_IP'] elif request.META.has_key('HTTP_X_FORWARDED_FOR'): ip = request.META['HTTP_X_FORWARDED_FOR'] else: ip = request.META['REMOTE_ADDR'] return ip