def environ(self): environ = {} cdict = self.request ###--- CouchDB variables ---### environ['couchdb.request'] = cdict environ['couchdb.info'] = cdict['info'] if 'couchdb.document' in cdict: environ['couchdb.document'] = cdict['couchdb.document'] ###--- Environ variables from CGI ---### if cdict['body'] == 'undefined': cdict['body'] = '' environ['REQUEST_METHOD'] = cdict['method'] environ['CONTENT_LENGTH'] = len(cdict['body']) for header, value in cdict['headers'].items(): environ['HTTP_' + header.upper().replace('-', '_')] = value # Reconstruct the path and script script, path = cdict['path'][:2], cdict['path'][2:] if len(path) is not 0: path = '/' + '/'.join(path) else: path = '' script = '/' + '/'.join(script) environ['SCRIPT_NAME'] = script environ['PATH_INFO'] = path if cdict['query']: environ['QUERY_STRING'] = urlencoding.compose_qs(cdict['query']) else: environ['QUERY_STRING'] = None if environ['QUERY_STRING'] is None: environ['QUERY_STRING'] = '' # Unclear whether this works with port 80 if ':' not in environ['HTTP_HOST']: environ['HTTP_HOST'] += ':80' environ['SERVER_NAME'], environ['SERVER_PORT'] = environ[ 'HTTP_HOST'].split(':') environ['SERVER_PORT'] = int(environ['SERVER_PORT']) # Faking, version isn't specified yet environ['HTTP_VERSION'] = 'HTTP/1.1' ###--- WSGI specific variables --## environ['wsgi.version'] = (1, 0) environ['wsgi.input'] = StringIO(cdict['body']) # Faking, scheme isn't currently available environ['wsgi.url_scheme'] = 'http' environ['wsgi.errors'] = StringIO() # Not actually sure about these ones :) environ['wsgi.multithread'] = False environ['wsgi.multiprocess'] = True environ['wsgi.run_once'] = True return environ
def environ(self): environ = {} cdict = self.request ###--- CouchDB variables ---### environ['couchdb.request'] = cdict environ['couchdb.info'] = cdict['info'] if 'couchdb.document' in cdict: environ['couchdb.document'] = cdict['couchdb.document'] ###--- Environ variables from CGI ---### if cdict['body'] == 'undefined': cdict['body'] = '' environ['REQUEST_METHOD'] = cdict['method'] environ['CONTENT_LENGTH'] = len(cdict['body']) for header, value in cdict['headers'].items(): environ['HTTP_'+header.upper().replace('-','_')] = value # Reconstruct the path and script script, path = cdict['path'][:2], cdict['path'][2:] if len(path) is not 0: path = '/' + '/'.join(path) else: path = '' script = '/' + '/'.join(script) environ['SCRIPT_NAME'] = script environ['PATH_INFO'] = path if cdict['query']: environ['QUERY_STRING'] = urlencoding.compose_qs(cdict['query']) else: environ['QUERY_STRING'] = None if environ['QUERY_STRING'] is None: environ['QUERY_STRING'] = '' # Unclear whether this works with port 80 if ':' not in environ['HTTP_HOST']: environ['HTTP_HOST'] += ':80' environ['SERVER_NAME'], environ['SERVER_PORT'] = environ['HTTP_HOST'].split(':') environ['SERVER_PORT'] = int(environ['SERVER_PORT']) # Faking, version isn't specified yet environ['HTTP_VERSION'] = 'HTTP/1.1' ###--- WSGI specific variables --## environ['wsgi.version'] = (1,0) environ['wsgi.input'] = StringIO(cdict['body']) # Faking, scheme isn't currently available environ['wsgi.url_scheme'] = 'http' environ['wsgi.errors'] = StringIO() # Not actually sure about these ones :) environ['wsgi.multithread'] = False environ['wsgi.multiprocess'] = True environ['wsgi.run_once'] = True return environ
def normalized_request_params(self): """ Generates the normalized request parameters. http://oauth.net/core/1.0/#rfc.section.9.1.1 """ params = self.params.copy() params.pop('oauth_signature', None) return compose_qs(params, sort=True)
def to_postdata(self, include_oauth=False): """ Generates the POST body. Arguments: `include_oauth` Decides if *oauth_* parameters are included. This is useful if the OAuth parameters are being sent via the POST body instead of the Authorization header. """ if include_oauth: params = self.params else: params = dict([(k, v) for k, v in self.params.iteritems() if k[:6] != 'oauth_']) return compose_qs(params)
def to_header(self, realm=None): """ Generates the Authorization header with the current OAuth parameters. http://oauth.net/core/1.0/#auth_header Arguments: `realm` An optional string to use as as the realm. If missing, realm will be ommitted all together. """ auth_header = 'OAuth ' if realm: auth_header += 'realm="%s",' % realm oauth_params = dict([(k, v) for k, v in self.params.iteritems() if k[:6] == 'oauth_']) auth_header += compose_qs(oauth_params, pattern='%s="%s"', join=',') return auth_header
def need_authorization(self, request): """ The view that triggers the access token flow by sending the user to the authorization url. If you wish to show the user a message, you may provide a template named: `django_oauth_consumer/{NAME}/need_authorization.html` The template will be provided an `authorization_url` in the context. If you do not provide a template, the user will be redirected there immediately. """ response = self.make_signed_req(self.request_token_url) body = unicode(response.read(), 'utf8').strip() request_token = urlencoding.parse_qs(body) request.session[self.name + '_request_token'] = request_token qs = urlencoding.compose_qs({ 'oauth_token': request_token['oauth_token'], 'oauth_callback': request.build_absolute_uri( reverse(self.SUCCESS_VIEW_NAME, kwargs={'oauth_token': request_token['oauth_token']})), }) url = self.authorization_url if '?' in url: if url[-1] == '&': url += qs else: url += '&' + qs else: url += '?' + qs if self._has_needs_auth_template: try: return self._render('need_authorization', request, {'authorization_url': url}) except TemplateDoesNotExist: self._has_needs_auth_template = False return HttpResponseRedirect(url)
def need_authorization(self, request): """ The view that triggers the access token flow by sending the user to the authorization url. If you wish to show the user a message, you may provide a template named: `django_oauth_consumer/{NAME}/need_authorization.html` The template will be provided an `authorization_url` in the context. If you do not provide a template, the user will be redirected there immediately. """ response = self.make_signed_req(self.request_token_url) body = unicode(response.read(), "utf8").strip() request_token = urlencoding.parse_qs(body) request.session[self.name + "_request_token"] = request_token qs = urlencoding.compose_qs( { "oauth_token": request_token["oauth_token"], "oauth_callback": request.build_absolute_uri( reverse(self.SUCCESS_VIEW_NAME, kwargs={"oauth_token": request_token["oauth_token"]}) ), } ) url = self.authorization_url if "?" in url: if url[-1] == "&": url += qs else: url += "&" + qs else: url += "?" + qs if self._has_needs_auth_template: try: return self._render("need_authorization", request, {"authorization_url": url}) except TemplateDoesNotExist: self._has_needs_auth_template = False return HttpResponseRedirect(url)
def test_simple(self): self.assertEqual(urlencoding.compose_qs({'a': '1'}), 'a=1')
def test_sorted_dict(self): self.assertEqual(urlencoding.compose_qs({'a': {'b': '1', 'c': '2'}}, sort=True), 'a%5Bb%5D=1&a%5Bc%5D=2')
def test_sorted_array(self): self.assertEqual(urlencoding.compose_qs({'a': ['2', '1']}, sort=True), 'a=1&a=2')
def test_array(self): self.assertEqual(urlencoding.compose_qs({'a': ['2', '1']}), 'a=2&a=1')
def prepare_request(url, method='GET', content=None, headers={}): """ This is the generic processing logic used by the various APIs. If content is a Mapping object, parameters will be processed. In this case, query parameters from the URL will be processed and merged with the content dict. They will then be appended to the URL or sent as the body based on the method. Arguments: `url` The URL - query parameters will be parsed out. `method` The HTTP method to use. `content` A dict of key/values or string/unicode value. `headers` A dict of headers. """ # we potentially modify them headers = headers.copy() parts = urlparse(url) url = parts.path if parts.params: url += ';' + parts.params # we dont do much with the url/body unless content is a Mapping object if isinstance(content, collections.Mapping): # merge the parameters in the query string if parts.query: qs_params = parse_qs(parts.query) qs_params.update(content) content = qs_params # put the content in the url or convert to string body if content: content = compose_qs(content) if method in ('HEAD', 'GET'): url += '?' + content content = None else: if 'Content-Type' not in headers: headers['Content-Type'] = 'application/x-www-form-urlencoded' else: if parts.query: url += '?' + parts.query # add Content-Length if needed if content and 'Content-Length' not in headers: headers['Content-Length'] = len(content) return { 'scheme': parts.scheme, 'netloc': parts.netloc, 'url': url, 'method': method, 'content': content, 'headers': headers, }
def prepare_request(url, method='GET', content=None, headers={}): """ This is the generic processing logic used by the various APIs. If content is a Mapping object, parameters will be processed. In this case, query parameters from the URL will be processed and merged with the content dict. They will then be appended to the URL or sent as the body based on the method. Arguments: `url` The URL - query parameters will be parsed out. `method` The HTTP method to use. `content` A dict of key/values or string/unicode value. `headers` A dict of headers. """ # we potentially modify them headers = headers.copy() parts = urlparse(url) url = parts.path if parts.params: url += ';' + parts.params # we dont do much with the url/body unless content is a Mapping object if isinstance(content, collections.Mapping): # merge the parameters in the query string if parts.query: qs_params = parse_qs(parts.query) qs_params.update(content) content = qs_params # put the content in the url or convert to string body if content: content = compose_qs(content) if method in ('HEAD', 'GET'): url += '?' + content content = None else: if 'Content-Type' not in headers: headers[ 'Content-Type'] = 'application/x-www-form-urlencoded' else: if parts.query: url += '?' + parts.query # add Content-Length if needed if content and 'Content-Length' not in headers: headers['Content-Length'] = len(content) return { 'scheme': parts.scheme, 'netloc': parts.netloc, 'url': url, 'method': method, 'content': content, 'headers': headers, }