Ejemplo n.º 1
0
 def _parse_urlencoded(self, stream, mimetype, content_length, options):
     if self.max_form_memory_size is not None and \
        content_length > self.max_form_memory_size:
         raise RequestEntityTooLarge()
     form = url_decode_stream(stream, self.charset,
                              errors=self.errors, cls=self.cls)
     return _empty_stream, form, self.cls()
Ejemplo n.º 2
0
 def authenticate(self,
                  state,
                  requested_redirect_url: str,
                  wsgi_environ: Mapping[str, object]) -> Identity:
     logger = logging.getLogger(__name__ + '.StashTeam.authenticate')
     logger.debug('state = %r', state)
     try:
         oauth_token, oauth_token_secret = state
     except ValueError:
         raise AuthenticationError()
     req = Request(wsgi_environ, populate_request=False, shallow=True)
     args = cast(ImmutableMultiDict, req.args)
     logger.debug('req.args = %r', args)
     if args.get('oauth_token') != oauth_token:
         raise AuthenticationError()
     response = self.request(
         'POST', self.ACCESS_TOKEN_URL.format(self),
         resource_owner_key=oauth_token,
         resource_owner_secret=oauth_token_secret
     )
     access_token = url_decode_stream(response)
     logger.debug('access_token = %r', access_token)
     response.close()
     response = self.request(
         'GET', self.USER_URL.format(self),
         resource_owner_key=access_token['oauth_token'],
         resource_owner_secret=access_token['oauth_token_secret']
     )
     whoami = response.read().decode('utf-8')
     return Identity(
         type(self),
         self.USER_PROFILE_URL.format(self, whoami),
         (access_token['oauth_token'], access_token['oauth_token_secret'])
     )
Ejemplo n.º 3
0
 def authenticate(self, state, requested_redirect_url: str,
                  wsgi_environ: collections.abc.Mapping) -> Identity:
     logger = logging.getLogger(__name__ + '.StashTeam.authenticate')
     logger.debug('state = %r', state)
     try:
         oauth_token, oauth_token_secret = state
     except ValueError:
         raise AuthenticationError()
     req = Request(wsgi_environ, populate_request=False, shallow=True)
     logger.debug('req.args = %r', req.args)
     if req.args.get('oauth_token') != oauth_token:
         raise AuthenticationError()
     response = self.request('POST',
                             self.ACCESS_TOKEN_URL.format(self),
                             resource_owner_key=oauth_token,
                             resource_owner_secret=oauth_token_secret)
     access_token = url_decode_stream(response)
     logger.debug('access_token = %r', access_token)
     response.close()
     response = self.request(
         'GET',
         self.USER_URL.format(self),
         resource_owner_key=access_token['oauth_token'],
         resource_owner_secret=access_token['oauth_token_secret'])
     whoami = response.read().decode('utf-8')
     return Identity(
         type(self), self.USER_PROFILE_URL.format(self, whoami),
         (access_token['oauth_token'], access_token['oauth_token_secret']))
Ejemplo n.º 4
0
    def _perform_method_overloading(self):
        """
        Perform method and content type overloading.

        Provides support for browser PUT, PATCH, DELETE & other requests,
        by specifing a '_method' form field.

        Also provides support for browser non-form requests (eg JSON),
        by specifing '_content' and '_content_type' form fields.
        """
        self._method = super(APIRequest, self).method
        self._stream = super(APIRequest, self).stream
        self._content_type = self.headers.get('Content-Type')
        self._content_length = get_content_length(self.environ)

        if (self._method == 'POST'
                and self._content_type == 'application/x-www-form-urlencoded'):
            # Read the request data, then push it back onto the stream again.
            body = self.get_data()
            data = url_decode_stream(io.BytesIO(body))
            self._stream = io.BytesIO(body)
            if '_method' in data:
                # Support browser forms with PUT, PATCH, DELETE & other methods.
                self._method = data['_method']
            if '_content' in data and '_content_type' in data:
                # Support browser forms with non-form data, such as JSON.
                body = data['_content'].encode('utf8')
                self._stream = io.BytesIO(body)
                self._content_type = data['_content_type']
                self._content_length = len(body)
Ejemplo n.º 5
0
    def _perform_method_overloading(self):
        """
        Perform method and content type overloading.

        Provides support for browser PUT, PATCH, DELETE & other requests,
        by specifing a '_method' form field.

        Also provides support for browser non-form requests (eg JSON),
        by specifing '_content' and '_content_type' form fields.
        """
        self._method = super(APIRequest, self).method
        self._stream = super(APIRequest, self).stream
        self._content_type = self.headers.get("Content-Type")
        self._content_length = get_content_length(self.environ)

        if self._method == "POST" and self._content_type == "application/x-www-form-urlencoded":
            # Read the request data, then push it back onto the stream again.
            body = self.get_data()
            data = url_decode_stream(io.BytesIO(body))
            self._stream = io.BytesIO(body)
            if "_method" in data:
                # Support browser forms with PUT, PATCH, DELETE & other methods.
                self._method = data["_method"]
            if "_content" in data and "_content_type" in data:
                # Support browser forms with non-form data, such as JSON.
                body = data["_content"].encode("utf8")
                self._stream = io.BytesIO(body)
                self._content_type = data["_content_type"]
                self._content_length = len(body)
Ejemplo n.º 6
0
 def authenticate(
     self,
     state,
     requested_redirect_url: str,
     wsgi_environ: Mapping[str, object]
 ) -> Identity:
     logger = self.logger.getChild('authenticate')
     req = Request(wsgi_environ, populate_request=False, shallow=True)
     args = cast(ImmutableMultiDict, req.args)
     try:
         code = args['code']
         if args['state'] != state:
             raise AuthenticationError()
     except KeyError:
         raise AuthenticationError()
     data = url_encode({
         'client_id': self.client_id,
         'client_secret': self.client_secret,
         'code': code,
         'redirect_uri': requested_redirect_url,
         'grant_type': 'authorization_code',
     }).encode()
     try:
         response = urllib.request.urlopen(self.access_token_url, data)
     except urllib.error.HTTPError as e:
         logger.debug('Response of POST %s (with/ %r): %s\n%s',
                      self.access_token_url, data, e.code, e.read())
         raise
     assert isinstance(response, http.client.HTTPResponse), \
         'isinstance(response, {0.__module__}.{0.__qualname__})'.format(
             type(response))
     headers = getattr(response, 'headers')  # workaround mypy
     content_type = headers['Content-Type']
     mimetype, options = parse_options_header(content_type)
     if mimetype == 'application/x-www-form-urlencoded':
         token_data = url_decode_stream(response)
     elif mimetype == 'application/json':
         charset = options.get('charset', 'utf-8')
         token_data = json.load(
             io.TextIOWrapper(cast(IO[bytes], response), encoding=charset)
         )
     else:
         response.close()
         raise AuthenticationError(
             '{} sent unsupported content type: {}'.format(
                 self.access_token_url,
                 content_type
             )
         )
     response.close()
     identity = self.determine_identity(token_data['access_token'])
     if self.authorize(identity):
         return identity
     raise AuthenticationError(
         self.unauthorized_identity_message_format.format(
             identity=identity, team=self
         )
     )
Ejemplo n.º 7
0
 def test_streamed_url_decoding(self):
     item1 = "a" * 100000
     item2 = "b" * 400
     string = "a=%s&b=%s&c=%s" % (item1, item2, item2)
     gen = urls.url_decode_stream(StringIO(string), limit=len(string), return_iterator=True)
     self.assert_equal(gen.next(), ("a", item1))
     self.assert_equal(gen.next(), ("b", item2))
     self.assert_equal(gen.next(), ("c", item2))
     self.assert_raises(StopIteration, gen.next)
Ejemplo n.º 8
0
 def test_streamed_url_decoding(self):
     item1 = 'a' * 100000
     item2 = 'b' * 400
     string = 'a=%s&b=%s&c=%s' % (item1, item2, item2)
     gen = urls.url_decode_stream(StringIO(string), limit=len(string),
                                  return_iterator=True)
     self.assert_equal(gen.next(), ('a', item1))
     self.assert_equal(gen.next(), ('b', item2))
     self.assert_equal(gen.next(), ('c', item2))
     self.assert_raises(StopIteration, gen.next)
Ejemplo n.º 9
0
 def test_streamed_url_decoding(self):
     item1 = 'a' * 100000
     item2 = 'b' * 400
     string = 'a=%s&b=%s&c=%s' % (item1, item2, item2)
     gen = urls.url_decode_stream(StringIO(string), limit=len(string),
                                  return_iterator=True)
     self.assert_equal(gen.next(), ('a', item1))
     self.assert_equal(gen.next(), ('b', item2))
     self.assert_equal(gen.next(), ('c', item2))
     self.assert_raises(StopIteration, gen.next)
Ejemplo n.º 10
0
 def test_streamed_url_decoding(self):
     item1 = u'a' * 100000
     item2 = u'b' * 400
     string = ('a=%s&b=%s&c=%s' % (item1, item2, item2)).encode('ascii')
     gen = urls.url_decode_stream(BytesIO(string), limit=len(string),
                                  return_iterator=True)
     self.assert_strict_equal(next(gen), ('a', item1))
     self.assert_strict_equal(next(gen), ('b', item2))
     self.assert_strict_equal(next(gen), ('c', item2))
     self.assert_raises(StopIteration, lambda: next(gen))
Ejemplo n.º 11
0
def test_streamed_url_decoding():
    item1 = "a" * 100000
    item2 = "b" * 400
    string = (f"a={item1}&b={item2}&c={item2}").encode("ascii")
    gen = urls.url_decode_stream(
        io.BytesIO(string), limit=len(string), return_iterator=True
    )
    assert next(gen) == ("a", item1)
    assert next(gen) == ("b", item2)
    assert next(gen) == ("c", item2)
    pytest.raises(StopIteration, lambda: next(gen))
Ejemplo n.º 12
0
    def parse(self, stream, content_type, content_length, context=None):
        """Parse the `stream` as a URL encoded form.

        :param stream: the stream to be parsed.
        :param content_type: the content type of the request payload.
        :param content_length: the content length of the request payload.
        :param context: a dictionary containing extra context data
                        that can be useful for parsing.
        """
        data = url_decode_stream(stream)
        return data.to_dict()
Ejemplo n.º 13
0
def test_streamed_url_decoding():
    item1 = u"a" * 100000
    item2 = u"b" * 400
    string = ("a=%s&b=%s&c=%s" % (item1, item2, item2)).encode("ascii")
    gen = urls.url_decode_stream(
        BytesIO(string), limit=len(string), return_iterator=True
    )
    strict_eq(next(gen), ("a", item1))
    strict_eq(next(gen), ("b", item2))
    strict_eq(next(gen), ("c", item2))
    pytest.raises(StopIteration, lambda: next(gen))
Ejemplo n.º 14
0
 def request_authentication(
         self, redirect_url: str) -> AuthenticationContinuation:
     response = self.request('POST', self.REQUEST_TOKEN_URL.format(self))
     request_token = url_decode_stream(response)
     response.close()
     return AuthenticationContinuation(
         self.AUTHORIZE_URL.format(self) + '?' +
         url_encode({
             'oauth_token': request_token['oauth_token'],
             'oauth_callback': redirect_url
         }), (request_token['oauth_token'],
              request_token['oauth_token_secret']))
Ejemplo n.º 15
0
 def request_authentication(
     self, redirect_url: str
 ) -> AuthenticationContinuation:
     response = self.request('POST', self.REQUEST_TOKEN_URL.format(self))
     request_token = url_decode_stream(response)
     response.close()
     return AuthenticationContinuation(
         self.AUTHORIZE_URL.format(self) + '?' + url_encode({
             'oauth_token': request_token['oauth_token'],
             'oauth_callback': redirect_url
         }),
         (request_token['oauth_token'], request_token['oauth_token_secret'])
     )
Ejemplo n.º 16
0
 def authenticate(self,
                  auth_nonce: str,
                  requested_redirect_url: str,
                  wsgi_environ: collections.abc.Mapping) -> Identity:
     req = Request(wsgi_environ, populate_request=False, shallow=True)
     try:
         code = req.args['code']
         if req.args['state'] != auth_nonce:
             raise AuthenticationError()
     except KeyError:
         raise AuthenticationError()
     data = url_encode({
         'client_id': self.client_id,
         'client_secret': self.client_secret,
         'code': code,
         'redirect_uri': requested_redirect_url
     }).encode()
     response = urllib.request.urlopen(self.ACCESS_TOKEN_URL, data)
     content_type = response.headers['Content-Type']
     mimetype, options = parse_options_header(content_type)
     if mimetype == 'application/x-www-form-urlencoded':
         token_data = url_decode_stream(response)
     elif mimetype == 'application/json':
         charset = options.get('charset')
         token_data = json.load(
             io.TextIOWrapper(response, encoding=charset)
         )
     else:
         response.close()
         raise AuthenticationError(
             '{} sent unsupported content type: {}'.format(
                 self.ACCESS_TOKEN_URL,
                 content_type
             )
         )
     response.close()
     user_data = request(token_data['access_token'], self.USER_URL)
     identity = Identity(
         type(self),
         user_data['login'],
         token_data['access_token']
     )
     if self.authorize(identity):
         return identity
     raise AuthenticationError(
         '@{} user is not a member of @{} organization'.format(
             user_data['login'],
             self.org_login
         )
     )
Ejemplo n.º 17
0
 def authenticate(self, state, requested_redirect_url: str,
                  wsgi_environ: Mapping[str, object]) -> Identity:
     logger = self.logger.getChild('authenticate')
     req = Request(wsgi_environ, populate_request=False, shallow=True)
     args = cast(ImmutableMultiDict, req.args)
     try:
         code = args['code']
         if args['state'] != state:
             raise AuthenticationError()
     except KeyError:
         raise AuthenticationError()
     data = url_encode({
         'client_id': self.client_id,
         'client_secret': self.client_secret,
         'code': code,
         'redirect_uri': requested_redirect_url,
         'grant_type': 'authorization_code',
     }).encode()
     try:
         response = urllib.request.urlopen(self.access_token_url, data)
     except urllib.error.HTTPError as e:
         logger.debug('Response of POST %s (with/ %r): %s\n%s',
                      self.access_token_url, data, e.code, e.read())
         raise
     assert isinstance(response, http.client.HTTPResponse), \
         'isinstance(response, {0.__module__}.{0.__qualname__})'.format(
             type(response))
     headers = getattr(response, 'headers')  # workaround mypy
     content_type = headers['Content-Type']
     mimetype, options = parse_options_header(content_type)
     if mimetype == 'application/x-www-form-urlencoded':
         token_data = url_decode_stream(response)
     elif mimetype == 'application/json':
         charset = options.get('charset', 'utf-8')
         token_data = json.load(
             io.TextIOWrapper(cast(IO[bytes], response), encoding=charset))
     else:
         response.close()
         raise AuthenticationError(
             '{} sent unsupported content type: {}'.format(
                 self.access_token_url, content_type))
     response.close()
     identity = self.determine_identity(token_data['access_token'])
     if self.authorize(identity):
         return identity
     raise AuthenticationError(
         self.unauthorized_identity_message_format.format(identity=identity,
                                                          team=self))
Ejemplo n.º 18
0
 def authenticate(
         self, state, requested_redirect_url: str,
         wsgi_environ: typing.Mapping[str, typing.Any]) -> Identity:
     logger = self.logger.getChild('authenticate')
     req = Request(wsgi_environ, populate_request=False, shallow=True)
     try:
         code = req.args['code']
         if req.args['state'] != state:
             raise AuthenticationError()
     except KeyError:
         raise AuthenticationError()
     data = url_encode({
         'client_id': self.client_id,
         'client_secret': self.client_secret,
         'code': code,
         'redirect_uri': requested_redirect_url,
         'grant_type': 'authorization_code',
     }).encode()
     try:
         response = urllib.request.urlopen(self.access_token_url, data)
     except urllib.error.HTTPError as e:
         logger.debug('Response of POST %s (with/ %r): %s\n%s',
                      self.access_token_url, data, e.code, e.read())
         raise
     content_type = response.headers['Content-Type']
     mimetype, options = parse_options_header(content_type)
     if mimetype == 'application/x-www-form-urlencoded':
         token_data = url_decode_stream(response)
     elif mimetype == 'application/json':
         charset = options.get('charset', 'utf-8')
         token_data = json.load(io.TextIOWrapper(response,
                                                 encoding=charset))
     else:
         response.close()
         raise AuthenticationError(
             '{} sent unsupported content type: {}'.format(
                 self.access_token_url, content_type))
     response.close()
     identity = self.determine_identity(token_data['access_token'])
     if self.authorize(identity):
         return identity
     raise AuthenticationError(
         self.unauthorized_identity_message_format.format(identity=identity,
                                                          team=self))
Ejemplo n.º 19
0
 def parser(stream, **context):
     return url_decode_stream(stream)
Ejemplo n.º 20
0
 def parse(self, stream, media_type, **options):
     return url_decode_stream(stream)
Ejemplo n.º 21
0
 def parse(self, stream, media_type, **options):
     return url_decode_stream(stream)
Ejemplo n.º 22
0
 def parser(stream, **context):
     return url_decode_stream(stream)