def get_authenticated_user(self, callback): """Gets the OAuth authorized user and access token on callback. This method should be called from the handler for your registered OAuth Callback URL to complete the registration process. We call callback with the authenticated user, which in addition to standard attributes like 'name' includes the 'access_key' attribute, which contains the OAuth access you can use to make authorized requests to this service on behalf of the user. """ request_key = escape.utf8(self.get_argument("oauth_token")) oauth_verifier = self.get_argument("oauth_verifier", None) request_cookie = self.get_cookie("_oauth_request_token") if not request_cookie: log.msg("Missing OAuth request token cookie") callback(None) return self.clear_cookie("_oauth_request_token") cookie_key, cookie_secret = [ base64.b64decode(escape.utf8(i)) for i in request_cookie.split("|") ] if cookie_key != request_key: log.msg("Request token does not match cookie") callback(None) return token = dict(key=cookie_key, secret=cookie_secret) if oauth_verifier: token["verifier"] = oauth_verifier d = httpclient.fetch(self._oauth_access_token_url(token)) d.addCallback(self.async_callback(self._on_access_token, callback))
def _oauth10a_signature(consumer_token, method, url, parameters={}, token=None): """Calculates the HMAC-SHA1 OAuth 1.0a signature for the given request. See http://oauth.net/core/1.0a/#signing_process """ parts = urlparse.urlparse(url) scheme, netloc, path = parts[:3] normalized_url = scheme.lower() + "://" + netloc.lower() + path base_elems = [] base_elems.append(method.upper()) base_elems.append(normalized_url) base_elems.append("&".join("%s=%s" % (k, _oauth_escape(str(v))) for k, v in sorted(parameters.items()))) base_string = "&".join(_oauth_escape(e) for e in base_elems) key_elems = [escape.utf8(urllib.quote(consumer_token["secret"], safe='~'))] key_elems.append( escape.utf8(urllib.quote(token["secret"], safe='~') if token else "")) key = "&".join(key_elems) hash = hmac.new(key, escape.utf8(base_string), hashlib.sha1) return binascii.b2a_base64(hash.digest())[:-1]
def _oauth10a_signature(consumer_token, method, url, parameters={}, token=None): """Calculates the HMAC-SHA1 OAuth 1.0a signature for the given request. See http://oauth.net/core/1.0a/#signing_process """ parts = urlparse.urlparse(url) scheme, netloc, path = parts[:3] normalized_url = scheme.lower() + "://" + netloc.lower() + path base_elems = [] base_elems.append(method.upper()) base_elems.append(normalized_url) base_elems.append("&".join("%s=%s" % (k, _oauth_escape(str(v))) for k, v in sorted(parameters.items()))) base_string = "&".join(_oauth_escape(e) for e in base_elems) key_elems = [escape.utf8( urllib.quote(consumer_token["secret"], safe='~'))] key_elems.append(escape.utf8( urllib.quote(token["secret"], safe='~') if token else "")) key = "&".join(key_elems) hash = hmac.new(key, escape.utf8(base_string), hashlib.sha1) return binascii.b2a_base64(hash.digest())[:-1]
def get_authenticated_user(self, callback): """Gets the OAuth authorized user and access token on callback. This method should be called from the handler for your registered OAuth Callback URL to complete the registration process. We call callback with the authenticated user, which in addition to standard attributes like 'name' includes the 'access_key' attribute, which contains the OAuth access you can use to make authorized requests to this service on behalf of the user. """ request_key = escape.utf8(self.get_argument("oauth_token")) oauth_verifier = self.get_argument("oauth_verifier", None) request_cookie = self.get_cookie("_oauth_request_token") if not request_cookie: log.msg("Missing OAuth request token cookie") callback(None) return self.clear_cookie("_oauth_request_token") cookie_key, cookie_secret = [base64.b64decode(escape.utf8(i)) for i in request_cookie.split("|")] if cookie_key != request_key: log.msg("Request token does not match cookie") callback(None) return token = dict(key=cookie_key, secret=cookie_secret) if oauth_verifier: token["verifier"] = oauth_verifier d = httpclient.fetch(self._oauth_access_token_url(token)) d.addCallback(self.async_callback(self._on_access_token, callback))
def render_xml(self, value): assert isinstance(value, dict) and len(value) == 1 self.set_header("Content-Type", "application/xml; charset=UTF-8") name = value.keys()[0] parts = [] parts.append('<%s xmlns="http://doc.s3.amazonaws.com/2006-03-01">' % escape.utf8(name)) self._render_parts(value.values()[0], parts) parts.append('</%s>' % escape.utf8(name)) self.finish('<?xml version="1.0" encoding="UTF-8"?>\n %s' % ''.join(parts))
def render_xml(self, value): assert isinstance(value, dict) and len(value) == 1 self.set_header("Content-Type", "application/xml; charset=UTF-8") name = value.keys()[0] parts = [] parts.append('<' + escape.utf8(name) + ' xmlns="http://doc.s3.amazonaws.com/2006-03-01">') self._render_parts(value.values()[0], parts) parts.append('</' + escape.utf8(name) + '>') self.finish('<?xml version="1.0" encoding="UTF-8"?>\n' + ''.join(parts))
def _make_request(self, method, path, data=None, *args, **kwargs): """Parse and create the request object.""" data = json.dumps(data) if data is not None else None headers = self._all_extra_headers() new_headers = kwargs.pop("headers", {}) headers.update(new_headers) if self.auth: kwargs['auth'] = self.auth if kwargs.get('params', {}): params = kwargs.get('params', {}) for key, value in params.items(): value = utf8(value) if isinstance(value, basestring) else value params[key] = value if params: kwargs['params'] = params return treq.request( method, path, headers=headers, data=data, **kwargs ).addCallbacks( self._handle_response, log.err )
def _render_parts(self, value, parts=[]): if isinstance(value, basestring): parts.append(escape.xhtml_escape(value)) elif isinstance(value, int) or isinstance(value, long): parts.append(str(value)) elif isinstance(value, datetime.datetime): parts.append(value.strftime("%Y-%m-%dT%H:%M:%S.000Z")) elif isinstance(value, dict): for name, subvalue in value.iteritems(): if not isinstance(subvalue, list): subvalue = [subvalue] for subsubvalue in subvalue: parts.append('<' + escape.utf8(name) + '>') self._render_parts(subsubvalue, parts) parts.append('</' + escape.utf8(name) + '>') else: raise Exception("Unknown S3 value type %r", value)
def _render_parts(self, value, parts=[]): if isinstance(value, basestring): parts.append(escape.xhtml_escape(value)) elif isinstance(value, int) or isinstance(value, long): parts.append(str(value)) elif isinstance(value, datetime.datetime): parts.append(value.strftime("%Y-%m-%dT%H:%M:%S.000Z")) elif isinstance(value, dict): for name, subvalue in value.iteritems(): if not isinstance(subvalue, list): subvalue = [subvalue] for subsubvalue in subvalue: parts.append('<%s>' % escape.utf8(name)) self._render_parts(subsubvalue, parts) parts.append('</%s>' % escape.utf8(name)) else: raise Exception("Unknown S3 value type %r", value)
def generate(self, writer): value = self.value # Compress lots of white space to a single character. If the whitespace # breaks a line, have it continue to break a line, but just with a # single \n character if writer.compress_whitespace and "<pre>" not in value: value = re.sub(r"([\t ]+)", " ", value) value = re.sub(r"(\s*\n\s*)", "\n", value) if value: writer.write_line('_append(%r)' % escape.utf8(value), self.line)
def fetch(url, *args, **kwargs): """A non-blocking HTTP client. Example:: d = httpclient.fetch("http://google.com") d.addCallback(on_response) By default the client does not follow redirects on HTTP 301, 302, 303 or 307. Parameters: followRedirect: Boolean, to tell the client whether to follow redirects or not. [default: False] maxRedirects: Maximum number of redirects to follow. This is to avoid infinite loops cause by misconfigured servers. postdata: Data that accompanies the request. If a request ``method`` is not set but ``postdata`` is, then it is automatically turned into a ``POST`` and the ``Content-Type`` is set to ``application/x-www-form-urlencoded``. headers: A python dictionary containing HTTP headers for this request. Note that all values must be lists:: headers={"Content-Type": ["application/json"]} The response is an object with the following attributes: code: HTTP server response code. phrase: Text that describe the response code. e.g.: 302 ``See Other`` headers: Response headers length: Content length body: The data, untouched proxy: A python tuple containing host string as first member and port string as second member; describing which proxy to use when making request """ return HTTPClient(escape.utf8(url), *args, **kwargs).fetch()
def parse_body_arguments(content_type, body, arguments, files): """Parses a form request body. Supports "application/x-www-form-urlencoded" and "multipart/form-data". The content_type parameter should be a string and body should be a byte string. The arguments and files parameters are dictionaries that will be updated with the parsed contents. """ if content_type.startswith("application/x-www-form-urlencoded"): uri_arguments = parse_qs_bytes(native_str(body)) for name, values in uri_arguments.items(): values = [v for v in values if v] if values: arguments.setdefault(name, []).extend(values) elif content_type.startswith("multipart/form-data"): fields = content_type.split(";") for field in fields: k, sep, v = field.strip().partition("=") if k == "boundary" and v: parse_multipart_form_data(utf8(v), body, arguments, files) break else: log.msg("Invalid multipart/form-data")
def _on_request_body(self, data): self._request.body = data content_type = self._request.headers.get("Content-Type", "") if self._request.method in ("POST", "PATCH", "PUT"): if content_type.startswith("application/x-www-form-urlencoded"): arguments = parse_qs_bytes(native_str(self._request.body)) for name, values in arguments.iteritems(): values = [v for v in values if v] if values: self._request.arguments.setdefault(name, []).extend(values) elif content_type.startswith("multipart/form-data"): fields = content_type.split(";") for field in fields: k, sep, v, = field.strip().partition("=") if k == "boundary" and v: httputil.parse_multipart_form_data( utf8(v), data, self._request.arguments, self._request.files) break else: log.msg("Invalid multipart/form-data") self.request_callback(self._request)
def test_utf8(self): self.assertEqual(utf8("rawr"), b"rawr") self.assertEqual(utf8(u"rawr"), b"rawr")
def test_utf8(self): self.assertEqual(utf8("rawr"), "rawr") self.assertEqual(utf8(u"rawr"), "rawr")
def fetchHeaders(url, *args, **kwargs): return HTTPClient(escape.utf8(url), *args, **kwargs).fetchHeaders()