def generateSign(request, secret): if type(request) != dict or type(secret) != str: raise Exception("type error") ret = "" stmp = sorted(request.items(), key=lambda d: d[0]) for i in stmp: ret += i[0] + "=" + str(i[1]) + "&" print(ret[:-1]) return hashlib.md5((ret[:-1] + secret).encode('utf-8')).hexdigest()
def build_xoauth_string(url, consumer, token=None): """Build an XOAUTH string for use in SMTP/IMPA authentication.""" request = Request.from_consumer_and_token(consumer, token, "GET", url) signing_method = SignatureMethod_HMAC_SHA1() request.sign_request(signing_method, consumer, token) params = [] for k, v in sorted(request.items()): if v is not None: params.append('%s="%s"' % (k, escape(v))) return "%s %s %s" % ("GET", url, ','.join(params))
def do_client_registration(self, request, client_id, ignore=None): if ignore is None: ignore = [] _cinfo = self.cdb[client_id].copy() logger.debug("_cinfo: %s" % _cinfo) for key, val in list(request.items()): if key not in ignore: _cinfo[key] = val if "redirect_uris" in request: ruri = [] for uri in request["redirect_uris"]: if urllib.parse.urlparse(uri).fragment: err = ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="redirect_uri contains fragment") return Response(err.to_json(), content="application/json", status="400 Bad Request") base, query = urllib.parse.splitquery(uri) if query: ruri.append((base, urllib.parse.parse_qs(query))) else: ruri.append((base, query)) _cinfo["redirect_uris"] = ruri if "sector_identifier_uri" in request: si_url = request["sector_identifier_uri"] try: res = self.server.http_request(si_url) except ConnectionError as err: logger.error("%s" % err) return self._error_response( "invalid_configuration_parameter", descr="Couldn't open sector_identifier_uri") if not res: return self._error_response( "invalid_configuration_parameter", descr="Couldn't open sector_identifier_uri") logger.debug("sector_identifier_uri => %s" % res.text) try: si_redirects = json.loads(res.text) except ValueError: return self._error_response( "invalid_configuration_parameter", descr="Error deserializing sector_identifier_uri content") if "redirect_uris" in request: logger.debug("redirect_uris: %s" % request["redirect_uris"]) for uri in request["redirect_uris"]: try: assert uri in si_redirects except AssertionError: return self._error_response( "invalid_configuration_parameter", descr="redirect_uri missing from sector_identifiers" ) _cinfo["si_redirects"] = si_redirects _cinfo["sector_id"] = si_url elif "redirect_uris" in request: if len(request["redirect_uris"]) > 1: # check that the hostnames are the same host = "" for url in request["redirect_uris"]: part = urllib.parse.urlparse(url) _host = part.netloc.split(":")[0] if not host: host = _host else: try: assert host == _host except AssertionError: return self._error_response( "invalid_configuration_parameter", descr= "'sector_identifier_uri' must be registered") for item in ["policy_url", "logo_url"]: if item in request: if self._verify_url(request[item], _cinfo["redirect_uris"]): _cinfo[item] = request[item] else: return self._error_response( "invalid_configuration_parameter", descr="%s pointed to illegal URL" % item) try: self.keyjar.load_keys(request, client_id) try: logger.debug("keys for %s: [%s]" % ( client_id, ",".join(["%s" % x for x in self.keyjar[client_id]]))) except KeyError: pass except Exception as err: logger.error("Failed to load client keys: %s" % request.to_dict()) err = ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="400 Bad Request") return _cinfo
def do_client_registration(self, request, client_id, ignore=None): if ignore is None: ignore = [] _cinfo = self.cdb[client_id].copy() logger.debug("_cinfo: %s" % _cinfo) for key, val in list(request.items()): if key not in ignore: _cinfo[key] = val if "redirect_uris" in request: ruri = [] for uri in request["redirect_uris"]: if urllib.parse.urlparse(uri).fragment: err = ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="redirect_uri contains fragment") return Response(err.to_json(), content="application/json", status="400 Bad Request") base, query = urllib.parse.splitquery(uri) if query: ruri.append((base, urllib.parse.parse_qs(query))) else: ruri.append((base, query)) _cinfo["redirect_uris"] = ruri if "sector_identifier_uri" in request: si_url = request["sector_identifier_uri"] try: res = self.server.http_request(si_url) except ConnectionError as err: logger.error("%s" % err) return self._error_response( "invalid_configuration_parameter", descr="Couldn't open sector_identifier_uri") if not res: return self._error_response( "invalid_configuration_parameter", descr="Couldn't open sector_identifier_uri") logger.debug("sector_identifier_uri => %s" % res.text) try: si_redirects = json.loads(res.text) except ValueError: return self._error_response( "invalid_configuration_parameter", descr="Error deserializing sector_identifier_uri content") if "redirect_uris" in request: logger.debug("redirect_uris: %s" % request["redirect_uris"]) for uri in request["redirect_uris"]: try: assert uri in si_redirects except AssertionError: return self._error_response( "invalid_configuration_parameter", descr="redirect_uri missing from sector_identifiers" ) _cinfo["si_redirects"] = si_redirects _cinfo["sector_id"] = si_url elif "redirect_uris" in request: if len(request["redirect_uris"]) > 1: # check that the hostnames are the same host = "" for url in request["redirect_uris"]: part = urllib.parse.urlparse(url) _host = part.netloc.split(":")[0] if not host: host = _host else: try: assert host == _host except AssertionError: return self._error_response( "invalid_configuration_parameter", descr= "'sector_identifier_uri' must be registered") for item in ["policy_url", "logo_url"]: if item in request: if self._verify_url(request[item], _cinfo["redirect_uris"]): _cinfo[item] = request[item] else: return self._error_response( "invalid_configuration_parameter", descr="%s pointed to illegal URL" % item) try: self.keyjar.load_keys(request, client_id) try: logger.debug("keys for %s: [%s]" % (client_id, ",".join( ["%s" % x for x in self.keyjar[client_id]]))) except KeyError: pass except Exception as err: logger.error("Failed to load client keys: %s" % request.to_dict()) err = ClientRegistrationErrorResponse( error="invalid_configuration_parameter", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="400 Bad Request") return _cinfo
def _request(self, request, auth_required=True): """ Make an HTTP(S) request to an API endpoint based on what's specified in the request object passed ## Input Required request keys: api Either REST or SOAP call Name of the SOAP method or relative path of the REST URL Optional keys: query Contents of the query string passed as a dict data Data to post. For SOAP API calls this will be the SOAP envelope. For REST API calls this will be a dict converted to JSON automatically by this method use_cookie_auth Whether or not to use an HTTP Cookie in lieu of a querystring for authorization ## Output Returns a dict: status Number HTTP status code returned by the response, if any raw The raw contents of the response, if any data A python dict representing the data contained in the response, if any """ for required_key in ['api', 'call']: if not request.has_key(required_key) and request[required_key]: self.log( "All requests are required to have a key [{}] with a value" .format(required_key), level='critical') return None url = None if request['api'] == self.API_TYPE_REST: url = "{}/{}".format(self._rest_api_endpoint, request['call'].lstrip('/')) else: url = self._soap_api_endpoint self.log("Making a request to {}".format(url), level='debug') # add the authentication parameters if auth_required: if request['api'] == self.API_TYPE_REST: if not request['use_cookie_auth']: # sID is a query string if not request['query']: request['query'] = {} request['query']['sID'] = self._sessions[ self.API_TYPE_REST] elif request['api'] == self.API_TYPE_SOAP: # sID is part of the data if not request['data']: request['data'] = {} request['data']['sID'] = self._sessions[self.API_TYPE_SOAP] # remove any blank request keys for k, v in request.items(): if not v: request[k] = None # prep the query string if request.has_key('query') and request['query']: # get with query string qs = {} for k, v in request['query'].items(): # strip out null entries if v: qs[k] = v url += '?%s' % urllib.urlencode(qs) self.log("Added query string. Full URL is now {}".format(url), level='debug') self.log("URL to request is: {}".format(url)) # Prep the SSL context ssl_context = ssl.create_default_context() if self.ignore_ssl_validation: ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE self.log( "SSL certificate validation has been disabled for this call", level='warning') # Prep the URL opener url_opener = urllib.request.build_opener( urllib.request.HTTPSHandler(context=ssl_context)) # Prep the request request_type = 'GET' headers = { 'Accept': 'application/json,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*', 'Content-Type': 'application/json', } # authentication calls don't accept the Accept header if request['call'].startswith('authentication'): del (headers['Accept']) # some rest calls use a cookie to pass the sID if request['api'] == self.API_TYPE_REST and request['use_cookie_auth']: headers['Cookie'] = 'sID="{}"'.format( self._sessions[self.API_TYPE_REST]) if request['api'] == self.API_TYPE_REST and request['call'] in [ 'apiVersion', 'status/manager/ping' ]: headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*', 'Content-Type': 'text/plain', } if request['api'] == self.API_TYPE_SOAP: # always a POST headers = { 'SOAPAction': '', 'content-type': 'application/soap+xml' } data = self._prep_data_for_soap(request['call'], request['data']) url_request = urllib.request.Request(url, data=data, headers=headers) request_type = 'POST' self.log("Making a SOAP request with headers {}".format(headers), level='debug') self.log(" and data {}".format(data), level='debug') elif request['call'] == 'authentication/logout': url_request = urllib.request.Request(url, headers=headers) setattr( url_request, 'get_method', lambda: 'DELETE') # make this request use the DELETE HTTP verb request_type = 'DELETE' self.log( "Making a REST DELETE request with headers {}".format(headers), level='debug') elif request.has_key('data') and request['data']: # POST url_request = urllib.request.Request(url, data=json.dumps( request['data']), headers=headers) request_type = 'POST' self.log( "Making a REST POST request with headers {}".format(headers), level='debug') self.log(" and data {}".format(request['data']), level='debug') else: # GET url_request = urllib.request.Request(url, headers=headers) self.log( "Making a REST GET request with headers {}".format(headers), level='debug') # Make the request response = None try: response = url_opener.open(url_request) except Exception as url_err: self.log("Failed to make {} {} call [{}]".format( request['api'].upper(), request_type, request['call'].lstrip('/')), err=url_err) # Convert the request from JSON result = { 'status': response.getcode() if response else None, 'raw': response.read() if response else None, 'headers': dict(response.headers) if response else dict(), 'data': None } bytes_of_data = len(result['raw']) if result['raw'] else 0 self.log("Call returned HTTP status {} and {} bytes of data".format( result['status'], bytes_of_data), level='debug') if response: if request['api'] == self.API_TYPE_SOAP: # XML response try: if result['raw']: full_data = xmltodict.parse(result['raw']) if full_data.has_key('soapenv:Envelope') and full_data[ 'soapenv:Envelope'].has_key('soapenv:Body'): result['data'] = full_data['soapenv:Envelope'][ 'soapenv:Body'] if result['data'].has_key('{}Response'.format( request['call'])): if result['data']['{}Response'.format( request['call'])].has_key( '{}Return'.format( request['call'])): result['data'] = result['data'][ '{}Response'.format(request['call'])][ '{}Return'.format(request['call'])] else: result['data'] = result['data'][ '{}Response'.format(request['call'])] else: result['data'] = full_data except Exception as xmltodict_err: self.log("Could not convert response from call {}".format( request['call']), err=xmltodict_err) else: # JSON response try: if result['raw'] and result['status'] != 204: result['type'] = result['headers']['content-type'] result['data'] = json.loads( result['raw'] ) if 'json' in result['type'] else None except Exception as json_err: # report the exception as 'info' because it's not fatal and the data is # still captured in result['raw'] self.log( "Could not convert response from call {} to JSON. Threw exception:\n\t{}" .format(request['call'], json_err), level='info') return result
def _get_all(self) -> Dict[int, Any]: request = self._get("/" + self.name) return { int(k): self.node(k, self.url, **v) for k, v in request.items() } # unstring the keys
def calculate(self, latitude, longitude, altitude=None, depth=None, radius=None, year=None, date=None, username=None, password=None): """ Calculate magnetic field using the API. Input: -- latitude -- The latitude where magnetic values are requested. -- longitude -- The longitude where magnetic values are requested. -- altitude -- The height above mean sea level where magnetic values are requested. -- depth -- The depth below mean sea level. -- radius -- The radial distance from the centre of the earth. -- year -- The year for which magnetic field values are requested. -- date -- The date when magnetic field values are requested. -- username -- Username for HTTP auth for protected models. -- password -- Password for HTTP auth for protected models. For more details see <http://geomag.bgs.ac.uk/web_service/GMModels/help/parameters>. Output: -- model -- Used model. -- model_revision -- Used model revision, including sub revision. -- date -- Used date. -- coordinates -- Used coordinates. -- -- latitude -- Used latitude. -- -- longitude -- Used longitude. -- -- altitude / depth / geocentric-radius -- Used height. -- field-value -- Field value. -- -- declination -- Declination. -- -- inclination -- Inclination. -- -- total-intensity -- Total intensity. -- -- north-intensity -- North intensity. -- -- east-intensity -- East intensity. -- -- vertical-intensity -- Vertical intensity. -- -- horizontal-intensity -- Horizontal intensity. -- secular-variation -- Secular variation. -- -- declination -- Declination. -- -- inclination -- Inclination. -- -- total-intensity -- Total intensity. -- -- north-intensity -- North intensity. -- -- east-intensity -- East intensity. -- -- vertical-intensity -- Vertical intensity. -- -- horizontal-intensity -- Horizontal intensity. Output is returned as dictionary. Some output properties will have `units` and `value` sub properties. Output format will depend on used input, specially for height and date. """ request = { 'latitude': latitude, 'longitude': longitude, 'altitude': altitude, 'depth': depth, 'radius': radius, 'year': year, 'date': date, 'format': 'json', } parameters = urllib.parse.urlencode( {k: v for k, v in request.items() if v is not None}) for base_url in self.custom_url, self.main_url: if base_url: try: url = base_url \ + '/' + self.model \ + '/' + self.revision \ + ('v' + self.sub_revision if self.sub_revision else '') \ + '?' + parameters request = urllib.request.Request(url) if username and password: auth = base64.b64encode(b'%s:%s' % (username, password)) request.add_header("Authorization", "Basic %s" % auth) response = urllib.request.urlopen(url).read() result = json.loads(response.decode('utf-8')) break except (URLError, ValueError) as err: error = err try: return result['geomagnetic-field-model-result'] except (NameError, KeyError): # pylint: disable=E1101 # pylint: disable=R1720 if isinstance(error, HTTPError): if error.code == 400: raise RequestError( error.read().decode('utf-8').strip('\n')) else: raise ApiError(str(error)) elif isinstance(error, URLError): raise ApiError(str(error)) elif isinstance(error, ValueError): raise RequestError(str(error)) raise ValueError( 'Can\'t get result because of wrong request or API error')