Esempio n. 1
0
    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
Esempio n. 2
0
 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
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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
Esempio n. 6
0
    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)
Esempio n. 8
0
 def test_simple(self):
     self.assertEqual(urlencoding.compose_qs({'a': '1'}), 'a=1')
Esempio n. 9
0
 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')
Esempio n. 10
0
 def test_sorted_array(self):
     self.assertEqual(urlencoding.compose_qs({'a': ['2', '1']}, sort=True), 'a=1&a=2')
Esempio n. 11
0
 def test_array(self):
     self.assertEqual(urlencoding.compose_qs({'a': ['2', '1']}), 'a=2&a=1')
Esempio n. 12
0
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,
    }
Esempio n. 13
0
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,
    }