def get_location_by_lon_and_lat(lon, lat): """ 根据经纬度查询地址 文档地址 http://lbs.amap.com/api/webservice/guide/api/georegeo/#regeo :param lon: :param lat: :return: ADCODE,省,市,县,屯,详细地址 """ if not (lon and lat): return 0, "未知", "未知", "未知", "未知", "未知" response = RequestClient.query("http://restapi.amap.com/v3/geocode/regeo", method="GET", params={ "output": "JSON", "key": AMAP_SERVER_KEY, "location": "%s,%s" % (lon, lat), "radius": 1000, "extensions": "base", "batch": "false", "roadlevel": 1, }) try: ret_json = response.json() adcode = ret_json["regeocode"]['addressComponent']['adcode'] province = ret_json["regeocode"]['addressComponent']['province'] city = ret_json["regeocode"]['addressComponent']['city'] district = ret_json["regeocode"]['addressComponent']['district'] township = ret_json["regeocode"]['addressComponent']['township'] address = ret_json["regeocode"]['formatted_address'] return adcode, province, city, district, township, address except Exception as exp: SysLogger.exception(exp) return 0, "未知", "未知", "未知", "未知", "未知"
def aes_encrypt(plaintext, key, iv=None, flag="raw"): """ AES-128bit/MODE_CBC/PKCS7Padding @ plaintext -- 明文 @ key -- 密钥 @ iv -- None时随机,[a-zA-Z0-9] returns: (cipher, iv) """ def pad(s): x = AES.block_size - len(s) % AES.block_size return s + (chr(x) * x) try: padded_plaintext = pad(plaintext) if iv is None: iv = random_str(16) cipher = AES.new(key, AES.MODE_CBC, iv) encrypted, iv_ = cipher.encrypt(padded_plaintext.encode("utf-8")), iv if "base64" == flag: encrypted = b64encode(encrypted) return encrypted, iv_ except Exception, exp: SysLogger.exception(exp) return None, ''
def process_request(self, request): try: # 1. GET参数整合到parameters request.parameters = request.GET.copy() if request.method == "POST": # 2. 处理request.body内的query_string更新到request.parameters # multipart/form-data 时不处理表单里的参数,因为没有经过nginx的参数签名校验,无法保证参数合法性 if request.META['CONTENT_TYPE'].startswith('multipart/form-data'): return None # application/x-www-form-urlencoded 时不处理request.body elif request.META['CONTENT_TYPE'] == 'application/x-www-form-urlencoded': pass # xml or json 时不处理request.body elif request.body.startswith("<") or request.body.startswith("{") or request.body.startswith("["): pass # 其他情况更新request.body内的query_string到request.parameters elif '=' in request.body: request.parameters.update(QueryDict(request.body, encoding='utf-8')) # 3. 表单参数更新到request.parameters for k in request.POST: # 使用setlist以支持类似复选控件一个name多个value的情况 request.parameters.setlist(k, request.POST.getlist(k)) # 提取用户的客户端信息 RequestInfo.DATA = { "request_ip": get_clientip(request), "user_agent": request.META.get("HTTP_USER_AGENT", "") } # 安全日志部分到此为止 return None except Exception as ex: SysLogger.exception(ex, request) response = HttpResponseBadRequest() return response
def aes_decrypt_base64_iv(ciphertext, key): '''先做base64解码,再从密文头部截断iv后做aes-cbc解密''' try: decoded = b64decode(ciphertext) iv, ciphertext = decoded[:AES.block_size], decoded[AES.block_size:] return aes_decrypt(ciphertext, key, iv) except Exception, exp: SysLogger.exception(exp) return None
def aes_encrypt_base64_iv(plaintext, key): '''iv嵌入到密文头部,再做base64编码的aes-cbc加密''' try: iv = Random.new().read(AES.block_size) ciphertext = aes_encrypt(plaintext, key, iv)[0] return b64encode(iv + ciphertext) except Exception, exp: SysLogger.exception(exp) return None
def xxtea_decrypt(cipher, key, flag="base64", is_bin=False): try: if flag == "base64": cipher = b64decode(cipher) byte_list = xxt_decrypt(cipher, key) if is_bin: return bytes(bytearray(byte_list)) else: return bytes(bytearray(byte_list[:-1])) # 去掉末位的 \0 except Exception, exp: SysLogger.exception(exp) return None
def xxtea_encrypt(plaintext, key, flag="base64", is_bin=False): try: if is_bin: pass else: cipher = xxt_encrypt(plaintext, key) if flag == "base64": cipher = b64encode(cipher) return cipher except Exception, exp: SysLogger.exception(exp) return None
def _operate_record(request, *args, **kwargs): if request.method == "POST": data = json.dumps(request.POST).decode("raw_unicode_escape") try: model.objects.create( name=request.hera_user.user_name, action=action, user_id=request.hera_user.user_id, data=data, ) except Exception as ex: SysLogger.exception(ex, request) return view_func(request, *args, **kwargs)
def query(cls, url, method="POST", params=None, data={}, files={}, timeout=3, retry=1, headers=None, add_sep_headers=False, record_params=True, stream=False, **kwargs): """ :params url: 要访问的url :param params: 参数In URL :param data: form-data数据 :param files: POST a Multipart-Encoded File :param retry: 当失败时候,重试次数 :params record_params 记录日志的时候是否需要将params/data你们的数据记录 :return response or None """ params = params if params else {} method = method.lower() times = 0 response = None # get headers default_headers = cls._get_headers(add_sep_headers, headers) # method 只是支持以下几种 if method not in ["post", "get", "put", "delete", "options", "head"]: raise RequestMethodError if method == "post" and retry > 1: SysLogger.warn("请确保POST请求可以重试.\n") while times < retry: start_time = time.time() try: if kwargs.get('cert'): # 带证书的请求使用requests session,如果两次使用不同证书,requests只使用第一次初始化时的证书, # 所以这里如果使用了证书就不使用session request_mode = requests else: request_mode = cls._request_session response = getattr(request_mode, method)(url=url, params=params, data=data, headers=default_headers, files=files, timeout=timeout, stream=stream, **kwargs) except Exception, exp: SysLogger.exception(exp) # 400以上的错误,599以下错误,需要接着访问 error_code = getattr(response, 'status_code', 599) times = times + 1 if error_code >= 400 and error_code <= 599 else times + retry AccessStatus( url=url, params=params, data=data, access_time=start_time, consuming_time=int(round((time.time() - start_time) * 1000)), # ms error_code=error_code, method=method, record_params=record_params).log()
def get_location_by_ip(ip): if not ip or ip == "127.0.0.1": return "", "", "" response = RequestClient.query("http://freeapi.ipip.net/%s" % ip, method="GET", params={}) try: ret_json = response.json() country = ret_json[0] province = ret_json[1] city = ret_json[2] return country, province, city except Exception as exp: SysLogger.exception(exp) return "", "", ""
def _check_request(request, *args, **kwargs): if method and (request.method != method.upper()): return HttpResponseNotAllowed([method.upper()]) statuscode = CommonError.UNKNOWN try: if allow_anonymous: return view_func(request, *args, **kwargs) elif not request.user.is_authenticated(): statuscode = CommonError.NOT_LOGIN elif not request.user.is_active: statuscode = CommonError.USER_DEACTIVE else: return view_func(request, *args, **kwargs) except APIError as ex: statuscode = ex.statuscode except Exception as ex: SysLogger.exception(ex, request) statuscode = APIError().statuscode return http_response(request, statuscode=statuscode)
def get_location_by_ip(ip): response = RequestClient.query( "http://restapi.amap.com/v3/ip", method="POST", data={ "ip": ip, "output": "JSON", "key": AMAP_SERVER_KEY, } ) try: ret_json = response.json() adcode = ret_json["adcode"] or 0 province = ret_json["province"] or "" city = ret_json["city"] or "" return adcode, province, city except Exception, exp: SysLogger.exception(exp) return 0, u"未知", u"未知"
def aes_decrypt(ciphertext, key, iv, flag="raw"): """ AES-128bit/MODE_CBC/PKCS7Padding @ plaintext -- 密文 @ key -- 密钥 @ iv -- iv returns: plaintext """ def unpad(s): return s[:-ord(s[-1])] try: cipher = AES.new(key, AES.MODE_CBC, iv) if "base64" == flag: ciphertext = b64decode(ciphertext) plaintext = unpad(cipher.decrypt(ciphertext)) return plaintext except Exception, exp: SysLogger.exception(exp) return None
def get_location_by_lon_and_lat(lon, lat): """ 根据经纬度查询地址 文档地址 http://lbs.amap.com/api/webservice/guide/api/georegeo/#regeo :param lon: :param lat: :return: ADCODE,省,市,县,屯,详细地址 """ if not (lon and lat): return 0, u"未知", u"未知", u"未知", u"未知", u"未知" response = RequestClient.query( "http://restapi.amap.com/v3/geocode/regeo", method="GET", params={ "output": "JSON", "key": AMAP_SERVER_KEY, "location": "%s,%s" % (lon, lat), "radius": 1000, "extensions": "base", "batch": "false", "roadlevel": 1, } ) try: ret_json = response.json() adcode = ret_json["regeocode"]['addressComponent']['adcode'] province = ret_json["regeocode"]['addressComponent']['province'] city = ret_json["regeocode"]['addressComponent']['city'] district = ret_json["regeocode"]['addressComponent']['district'] township = ret_json["regeocode"]['addressComponent']['township'] address = ret_json["regeocode"]['formatted_address'] return adcode, province, city, district, township, address except Exception, exp: SysLogger.exception(exp) return 0, u"未知", u"未知", u"未知", u"未知", u"未知"
def query(cls, url, method="POST", params=None, data={}, files={}, timeout=3, retry=1, headers=None, add_blog_headers=False, record_params=True, stream=False, **kwargs): """ :params url: 要访问的url :param params: 参数In URL :param data: form-data数据 :param files: POST a Multipart-Encoded File :param retry: 当失败时候,重试次数 :params record_params 记录日志的时候是否需要将params/data你们的数据记录 :return response or None """ params = params if params else {} method = method.lower() times = 0 response = None # get headers default_headers = cls._get_headers(add_blog_headers, headers) # method 只是支持以下几种 if method not in ["post", "get", "put", "delete", "options", "head"]: raise RequestMethodError if method == "post" and retry > 1: SysLogger.warn("请确保POST请求可以重试.\n") while times < retry: start_time = time.time() try: if kwargs.get('cert'): # 带证书的请求使用requests session,如果两次使用不同证书,requests只使用第一次初始化时的证书, # 所以这里如果使用了证书就不使用session request_mode = requests else: request_mode = cls._request_session response = getattr(request_mode, method)(url=url, params=params, data=data, headers=default_headers, files=files, timeout=timeout, stream=stream, **kwargs) except Exception, exp: SysLogger.exception(exp) # 400以上的错误,599以下错误,需要接着访问 error_code = getattr(response, 'status_code', 599) times = times + 1 if error_code >= 400 and error_code <= 599 else times + retry AccessStatus( url=url, params=params, data=data, access_time=start_time, consuming_time=int(round( (time.time() - start_time) * 1000)), # ms error_code=error_code, method=method, record_params=record_params).log()