Example #1
0
 def build_links(self, request=None):
     links = {}
     if request is not None:
         links["self"] = request.build_absolute_uri(request.path)
         page = self._current_page
         if page is not None:
             if page.has_previous():
                 u = urlparse(links["self"])
                 q = parse_qs(u.query)
                 q["page[number]"] = str(page.previous_page_number())
                 links["prev"] = ParseResult(
                     u.scheme,
                     u.netloc,
                     u.path,
                     u.params,
                     urlencode(q),
                     u.fragment,
                 ).geturl()
             if page.has_next():
                 u = urlparse(links["self"])
                 q = parse_qs(u.query)
                 q["page[number]"] = str(page.next_page_number())
                 links["next"] = ParseResult(
                     u.scheme,
                     u.netloc,
                     u.path,
                     u.params,
                     urlencode(q),
                     u.fragment,
                 ).geturl()
     return links
Example #2
0
    def test__get_request_if_http_method_is_post(self):

        attr_ = {'user_api_key': ['spam'], 'developer_api_key': ['ham']}

        for api_method, http_method in DisqusClient.METHODS.items():
            if http_method == "POST":

                url = self.client.api_url % api_method

                request_params = self.client._get_request(url,
                                                          http_method,
                                                          **self.attr)
                request_no_params = self.client._get_request(url, http_method)

                self.assertEqual(request_params.get_host(), 'disqus.com')
                self.assertEqual(request_no_params.get_host(), 'disqus.com')

                self.assertEqual(request_params.get_method(), http_method)
                self.assertEqual(request_no_params.get_method(), http_method)

                qs_params = parse_qs(request_params.data)
                qs_no_params = parse_qs(request_no_params.data)

                self.assertEqual(qs_params, attr_)
                self.assertEqual(qs_no_params, {})
Example #3
0
 def build_links(self, request=None):
     links = {}
     if request is not None:
         if hasattr(request, "build_absolute_uri"):
             links["self"] = request.build_absolute_uri(request.path)
         else:
             links["self"] = request.path
         page = self._current_page
         if page is not None:
             if page.has_previous():
                 u = urlparse(links["self"])
                 q = parse_qs(u.query)
                 q["page[number]"] = str(page.previous_page_number())
                 links["prev"] = ParseResult(
                     u.scheme,
                     u.netloc,
                     u.path,
                     u.params,
                     urlencode(q),
                     u.fragment,
                 ).geturl()
             if page.has_next():
                 u = urlparse(links["self"])
                 q = parse_qs(u.query)
                 q["page[number]"] = str(page.next_page_number())
                 links["next"] = ParseResult(
                     u.scheme,
                     u.netloc,
                     u.path,
                     u.params,
                     urlencode(q),
                     u.fragment,
                 ).geturl()
     return links
    def test_export_url_tag(self):
        template = Template('{% load django_tables2 %}{% export_url "csv" %}')
        html = template.render(Context({"request": build_request("?q=foo")}))
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs("q=foo&_export=csv")))

        # using a template context variable
        template = Template("{% load django_tables2 %}{% export_url format %}")
        html = template.render(Context({"request": build_request("?q=foo"), "format": "xls"}))
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs("q=foo&_export=xls")))
    def test_export_url_tag(self):
        template = Template('{% load django_tables2 %}{% export_url "csv" %}')
        html = template.render(Context({'request': build_request('?q=foo')}))
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs('q=foo&_export=csv')))

        # using a template context variable
        template = Template('{% load django_tables2 %}{% export_url format %}')
        html = template.render(Context({'request': build_request('?q=foo'), 'format': 'xls'}))
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs('q=foo&_export=xls')))
    def test_export_url_tag(self):
        class View(ExportMixin):
            export_trigger_param = "_do_export"

        template = Template('{% load django_tables2 %}{% export_url "csv" %}')
        html = template.render(Context({"request": build_request("?q=foo"), "view": View()}))
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs("q=foo&_do_export=csv")))

        # using a template context variable and a view
        template = Template("{% load django_tables2 %}{% export_url format %}")
        html = template.render(
            Context({"request": build_request("?q=foo"), "format": "xls", "view": View()})
        )
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs("q=foo&_do_export=xls")))

        # using a template context variable
        template = Template("{% load django_tables2 %}{% export_url format %}")
        html = template.render(Context({"request": build_request("?q=foo"), "format": "xls"}))
        self.assertEqual(dict(parse_qs(html[1:])), dict(parse_qs("q=foo&_export=xls")))

        # using a template context and change export parameter
        template = Template('{% load django_tables2 %}{% export_url "xls" "_other_export_param" %}')
        html = template.render(Context({"request": build_request("?q=foo"), "format": "xls"}))
        self.assertEqual(
            dict(parse_qs(html[1:])), dict(parse_qs("q=foo&_other_export_param=xls"))
        )
Example #7
0
    def test_login_one_idp(self):
        # monkey patch SAML configuration
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        response = self.client.get(reverse('saml2_login'))
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assert_('SAMLRequest' in params)
        self.assert_('RelayState' in params)

        saml_request = params['SAMLRequest'][0]
        if PY_VERSION < (2, 7):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
        elif PY_VERSION < (3, ):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
        else:
            expected_request = """<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""

        self.assertSAMLRequestsEquals(
            decode_base64_and_inflate(saml_request).decode('utf-8'),
            expected_request)

        # if we set a next arg in the login view, it is preserverd
        # in the RelayState argument
        next = '/another-view/'
        response = self.client.get(reverse('saml2_login'), {'next': next})
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assert_('SAMLRequest' in params)
        self.assert_('RelayState' in params)
        self.assertEquals(params['RelayState'][0], next)
Example #8
0
    def test_login_one_idp(self):
        # monkey patch SAML configuration
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        response = self.client.get(reverse('saml2_login'))
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assert_('SAMLRequest' in params)
        self.assert_('RelayState' in params)

        saml_request = params['SAMLRequest'][0]
        if PY_VERSION < (2, 7):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
        elif PY_VERSION < (3,):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""
        else:
            expected_request = """<samlp:AuthnRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://sp.example.com/saml2/acs/" Destination="https://idp.example.com/simplesaml/saml2/idp/SSOService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><samlp:NameIDPolicy AllowCreate="false" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></samlp:AuthnRequest>"""

        self.assertSAMLRequestsEquals(
            decode_base64_and_inflate(saml_request).decode('utf-8'),
            expected_request)

        # if we set a next arg in the login view, it is preserverd
        # in the RelayState argument
        next = '/another-view/'
        response = self.client.get(reverse('saml2_login'), {'next': next})
        self.assertEquals(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEquals(url.hostname, 'idp.example.com')
        self.assertEquals(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assert_('SAMLRequest' in params)
        self.assert_('RelayState' in params)
        self.assertEquals(params['RelayState'][0], next)
def assertUrisEqual(testcase, expected, actual):
  """Test that URIs are the same, up to reordering of query parameters."""
  expected = urlparse(expected)
  actual = urlparse(actual)
  testcase.assertEqual(expected.scheme, actual.scheme)
  testcase.assertEqual(expected.netloc, actual.netloc)
  testcase.assertEqual(expected.path, actual.path)
  testcase.assertEqual(expected.params, actual.params)
  testcase.assertEqual(expected.fragment, actual.fragment)
  expected_query = parse_qs(expected.query)
  actual_query = parse_qs(actual.query)
  for name in list(expected_query.keys()):
    testcase.assertEqual(expected_query[name], actual_query[name])
  for name in list(actual_query.keys()):
    testcase.assertEqual(expected_query[name], actual_query[name])
Example #10
0
        def _http_get(service, url, *args, **kwargs):
            url_parts = urlparse(url)
            path = url_parts.path
            query = parse_qs(url_parts.query)

            if path == '/api/2.0/repositories/myuser/myrepo/':
                self.assertEqual(
                    query,
                    {
                        'fields': ['mainbranch.name'],
                    })

                return get_repository_api_response, None
            elif path == '/api/2.0/repositories/myuser/myrepo/refs/branches':
                if 'page' in query:
                    self.assertEqual(
                        query,
                        {
                            'fields': ['values.name,values.target.hash,next'],
                            'pagelen': ['100'],
                            'page': ['2'],
                        })

                    return branches_api_response_2, None
                else:
                    self.assertEqual(
                        query,
                        {
                            'fields': ['values.name,values.target.hash,next'],
                            'pagelen': ['100'],
                        })

                    return branches_api_response_1, None
            else:
                self.fail('Unexpected URL %s' % url)
Example #11
0
 def process_authn_request_redirect(self, url, auth_result=True, consent=True):
     login = lasso.Login(self.server)
     login.processAuthnRequestMsg(url.split('?', 1)[1])
     # See
     # https://docs.python.org/2/library/zlib.html#zlib.decompress
     # for the -15 magic value.
     #
     # * -8 to -15: Uses the absolute value of wbits as the window size
     # logarithm. The input must be a raw stream with no header or trailer.
     #
     # it means Deflate instead of GZIP (same stream no header, no trailer)
     self.request = zlib.decompress(
         base64.b64decode(
             urlparse.parse_qs(
                 urlparse.urlparse(url).query)['SAMLRequest'][0]), -15)
     try:
         login.validateRequestMsg(auth_result, consent)
     except lasso.LoginRequestDeniedError:
         pass
     else:
         login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD,
                              "FIXME",
                              "FIXME",
                              "FIXME",
                              "FIXME")
     if login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_ART:
         login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET)
         self.artifact = login.artifact
         self.artifact_message = login.artifactMessage
     elif login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_POST:
         login.buildAuthnResponseMsg()
     else:
         raise NotImplementedError
     return login.msgUrl, login.msgBody, login.msgRelayState
Example #12
0
    def test_logout(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )
        self.do_login()

        response = self.client.get(reverse('saml2_logout'))
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path,
                         '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)

        saml_request = params['SAMLRequest'][0]
        if PY_VERSION < (3,):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        else:
            expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        self.assertSAMLRequestsEquals(decode_base64_and_inflate(saml_request).decode('utf-8'),
                                      expected_request)
Example #13
0
    def test_login_several_idps(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp1.example.com',
                       'idp2.example.com',
                       'idp3.example.com'],
            metadata_file='remote_metadata_three_idps.xml',
        )
        response = self.client.get(reverse('saml2_login'))
        # a WAYF page should be displayed
        self.assertContains(response, 'Where are you from?', status_code=200)
        for i in range(1, 4):
            link = '/login/?idp=https://idp%d.example.com/simplesaml/saml2/idp/metadata.php&next=/'
            self.assertContains(response, link % i)

        # click on the second idp
        response = self.client.get(reverse('saml2_login'), {
                'idp': 'https://idp2.example.com/simplesaml/saml2/idp/metadata.php',
                'next': '/',
                })
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp2.example.com')
        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)
        self.assertIn('RelayState', params)

        saml_request = params['SAMLRequest'][0]
        if 'AuthnRequest xmlns' not in decode_base64_and_inflate(saml_request).decode('utf-8'):
            raise Exception('Not a valid AuthnRequest')
Example #14
0
def post(url, params):
    """
    Make a POST request to the URL using the key-value pairs.  Return
    a set of key-value pairs.

    :url: URL to post to
    :params: Dict of parameters to include in post payload
    """
    payload = urlencode(params)
    start_time = time.time()
    response = requests.post(
        url,
        payload,
        headers={'content-type': 'text/namevalue; charset=utf-8'})
    if response.status_code != requests.codes.ok:
        raise exceptions.PayPalError("Unable to communicate with PayPal")

    # Convert response into a simple key-value format
    pairs = {}
    for key, values in parse_qs(response.text).items():
        pairs[force_text(key)] = force_text(values[0])
        #pairs[key] = values[0]

    # Add audit information
    pairs['_raw_request'] = payload
    pairs['_raw_response'] = response.content
    pairs['_response_time'] = (time.time() - start_time) * 1000.0

    return pairs
Example #15
0
    def _add_query_params(self, url, new_query_params):
        """Add query parameters onto the given URL.

        Args:
            url (unicode):
                The URL to add query parameters to.

            new_query_params (dict):
                The query parameters to add.

        Returns:
            unicode:
            The resulting URL.
        """
        scheme, netloc, path, query_string, fragment = urlsplit(url)
        query_params = parse_qs(query_string)
        query_params.update(new_query_params)
        new_query_string = urlencode(
            [
                (key, value)
                for key, value in sorted(six.iteritems(query_params),
                                         key=lambda i: i[0])
            ],
            doseq=True)

        return urlunsplit((scheme, netloc, path, new_query_string, fragment))
def _decode_cursor(encoded):
    """
    Given a string representing an encoded cursor, return a `Cursor` instance.
    """

    # The offset in the cursor is used in situations where we have a
    # nearly-unique index. (Eg millisecond precision creation timestamps)
    # We guard against malicious users attempting to cause expensive database
    # queries, by having a hard cap on the maximum possible size of the offset.
    OFFSET_CUTOFF = 1000

    try:
        querystring = b64decode(encoded.encode('ascii')).decode('ascii')
        tokens = urlparse.parse_qs(querystring, keep_blank_values=True)

        offset = tokens.get('o', ['0'])[0]
        offset = _positive_int(offset, cutoff=OFFSET_CUTOFF)

        reverse = tokens.get('r', ['0'])[0]
        reverse = bool(int(reverse))

        position = tokens.get('p', [None])[0]
    except (TypeError, ValueError):
        return None

    return Cursor(offset=offset, reverse=reverse, position=position)
Example #17
0
def url_replace_param(url, name, value):
    """
    Replace a GET parameter in an URL
    """
    url_components = urlparse(force_str(url))

    params = parse_qs(url_components.query)

    if value is None:
        del params[name]
    else:
        params[name] = value

    return mark_safe(
        urlunparse(
            [
                url_components.scheme,
                url_components.netloc,
                url_components.path,
                url_components.params,
                urlencode(params, doseq=True),
                url_components.fragment,
            ]
        )
    )
Example #18
0
def build_html_iframe(response, url_params=None, iframe_attrs=None):
    html = response.get('html', '')

    if url_params is None:
        url_params = {}

    if iframe_attrs is None:
        iframe_attrs = {}

    if html:
        # What follows is a pretty nasty looking "hack"
        # oEmbed hss not implemented some parameters
        # and so for these we need to add them manually to the iframe.
        html = BeautifulSoup(html).iframe

        data_url = response.get('player_url', html['src'])
        player_url = urlparse(data_url)

        queries = parse_qs(player_url.query)
        url_params.update(queries)

        url_parts = list(player_url)
        url_parts[4] = urlencode(url_params, True)

        html['src'] = urlunparse(url_parts)

        for key, value in iframe_attrs.items():
            if value:
                html[key] = value
    return str(html)
Example #19
0
    def decode_cursor(self, request):
        """
        Given a request with a cursor, return a `Cursor` instance.

        Differs from the standard CursorPagination to handle a tuple in the
        position field.
        """
        # Determine if we have a cursor, and if so then decode it.
        encoded = request.query_params.get(self.cursor_query_param)
        if encoded is None:
            return None

        try:
            querystring = b64decode(encoded.encode('ascii')).decode('ascii')
            tokens = urlparse.parse_qs(querystring, keep_blank_values=True)

            offset = tokens.get('o', ['0'])[0]
            # This was hard-coded until Django REST Framework 3.4.0.
            try:
                offset_cutoff = self.offset_cutoff
            except AttributeError:
                offset_cutoff = 1000
            offset = _positive_int(offset, cutoff=offset_cutoff)

            reverse = tokens.get('r', ['0'])[0]
            reverse = bool(int(reverse))

            # The difference. Don't get just the 0th entry: get all entries.
            position = tokens.get('p', None)
        except (TypeError, ValueError):
            raise NotFound(self.invalid_cursor_message)

        return Cursor(offset=offset, reverse=reverse, position=position)
Example #20
0
def build_html_iframe(response, url_params=None, iframe_attrs=None):
    html = response.get('html', '')

    if url_params is None:
        url_params = {}

    if iframe_attrs is None:
        iframe_attrs = {}

    if html:
        # What follows is a pretty nasty looking "hack"
        # oEmbed hss not implemented some parameters
        # and so for these we need to add them manually to the iframe.
        html = BeautifulSoup(html).iframe

        data_url = response.get('player_url', html['src'])
        player_url = urlparse(data_url)

        queries = parse_qs(player_url.query)
        url_params.update(queries)

        url_parts = list(player_url)
        url_parts[4] = urlencode(url_params, True)

        html['src'] = urlunparse(url_parts)

        for key, value in iframe_attrs.iteritems():
            if value:
                html[key] = value
    return unicode(html)
    def decode_cursor(self, request):
        """
        Given a request with a cursor, return a `Cursor` instance.
        """
        # Determine if we have a cursor, and if so then decode it.
        encoded = request.query_params.get(self.cursor_query_param)
        if encoded is None:
            return None

        # The offset in the cursor is used in situations where we have a
        # nearly-unique index. (Eg millisecond precision creation timestamps)
        # We guard against malicious users attempting to cause expensive database
        # queries, by having a hard cap on the maximum possible size of the offset.
        OFFSET_CUTOFF = 1000

        try:
            querystring = b64decode(encoded.encode('ascii')).decode('ascii')
            tokens = urlparse.parse_qs(querystring, keep_blank_values=True)

            offset = tokens.get('o', ['0'])[0]
            offset = _positive_int(offset, cutoff=OFFSET_CUTOFF)

            reverse = tokens.get('r', ['0'])[0]
            reverse = bool(int(reverse))

            position = tokens.get('p', [None])[0]
        except (TypeError, ValueError):
            raise NotFound(self.invalid_cursor_message)

        return Cursor(offset=offset, reverse=reverse, position=position)
Example #22
0
    def decode_cursor(self, request):
        """
        Given a request with a cursor, return a `Cursor` instance.
        """
        # Determine if we have a cursor, and if so then decode it.
        encoded = request.query_params.get(self.cursor_query_param)
        if encoded is None:
            return None

        # The offset in the cursor is used in situations where we have a
        # nearly-unique index. (Eg millisecond precision creation timestamps)
        # We guard against malicious users attempting to cause expensive database
        # queries, by having a hard cap on the maximum possible size of the offset.
        OFFSET_CUTOFF = 1000

        try:
            querystring = b64decode(encoded.encode('ascii')).decode('ascii')
            tokens = urlparse.parse_qs(querystring, keep_blank_values=True)

            offset = tokens.get('o', ['0'])[0]
            offset = _positive_int(offset, cutoff=OFFSET_CUTOFF)

            reverse = tokens.get('r', ['0'])[0]
            reverse = bool(int(reverse))

            position = tokens.get('p', [None])[0]
        except (TypeError, ValueError):
            raise NotFound(self.invalid_cursor_message)

        return Cursor(offset=offset, reverse=reverse, position=position)
  def test_json_build_query(self):
    model = JsonModel(data_wrapper=False)

    headers = {}
    path_params = {}
    query_params = {'foo': 1, 'bar': u'\N{COMET}',
        'baz': ['fe', 'fi', 'fo', 'fum'], # Repeated parameters
        'qux': []}
    body = {}

    headers, unused_params, query, body = model.request(
        headers, path_params, query_params, body)

    self.assertEqual(headers['accept'], 'application/json')
    self.assertEqual(headers['content-type'], 'application/json')

    query_dict = parse_qs(query[1:])
    self.assertEqual(query_dict['foo'], ['1'])
    if six.PY3:
      # Python 3, no need to encode
      self.assertEqual(query_dict['bar'], [u'\N{COMET}'])
    else:
      # Python 2, encode string
      self.assertEqual(query_dict['bar'], [u'\N{COMET}'.encode('utf-8')])
    self.assertEqual(query_dict['baz'], ['fe', 'fi', 'fo', 'fum'])
    self.assertTrue('qux' not in query_dict)
    self.assertEqual(body, '{}')
Example #24
0
    def test_logout_service_global(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        self.do_login()

        # now simulate a global logout process initiated by another SP
        subject_id = views._get_subject_id(self.client.session)
        instant = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
        saml_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_9961abbaae6d06d251226cb25e38bf8f468036e57e" Version="2.0" IssueInstant="%s" Destination="http://sp.example.com/saml2/ls/"><saml:Issuer>https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:NameID SPNameQualifier="http://sp.example.com/saml2/metadata/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">%s</saml:NameID><samlp:SessionIndex>_1837687b7bc9faad85839dbeb319627889f3021757</samlp:SessionIndex></samlp:LogoutRequest>""" % (
            instant, subject_id.text)

        response = self.client.get(
            reverse('saml2_ls'), {
                'SAMLRequest': deflate_and_base64_encode(saml_request),
            })
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path,
                         '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLResponse', params)
        saml_response = params['SAMLResponse'][0]

        if 'Response xmlns' not in decode_base64_and_inflate(
                saml_response).decode('utf-8'):
            raise Exception('Not a valid Response')
Example #25
0
    def test_logout(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )
        self.do_login()

        response = self.client.get(reverse('saml2_logout'))
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path,
                         '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)

        saml_request = params['SAMLRequest'][0]
        if PY_VERSION < (3, ):
            expected_request = """<?xml version='1.0' encoding='UTF-8'?>
<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        else:
            expected_request = """<samlp:LogoutRequest xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php" ID="XXXXXXXXXXXXXXXXXXXXXX" IssueInstant="2010-01-01T00:00:00Z" Reason="" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://sp.example.com/saml2/metadata/</saml:Issuer><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="http://sp.example.com/saml2/metadata/">58bcc81ea14700f66aeb707a0eff1360</saml:NameID><samlp:SessionIndex>a0123456789abcdef0123456789abcdef</samlp:SessionIndex></samlp:LogoutRequest>"""
        self.assertSAMLRequestsEquals(
            decode_base64_and_inflate(saml_request).decode('utf-8'),
            expected_request)
Example #26
0
def post(url, params):
    """
    Make a POST request to the URL using the key-value pairs.  Return
    a set of key-value pairs.

    :url: URL to post to
    :params: Dict of parameters to include in post payload
    """
    payload = urlencode(params)
    start_time = time.time()
    response = requests.post(
        url, payload,
        headers={'content-type': 'text/namevalue; charset=utf-8'})
    if response.status_code != requests.codes.ok:
        raise exceptions.PayPalError("Unable to communicate with PayPal")

    # Convert response into a simple key-value format
    pairs = {}
    for key, values in parse_qs(response.content).items():
        pairs[force_text(key)] = force_text(values[0])

    # Add audit information
    pairs['_raw_request'] = payload
    pairs['_raw_response'] = response.content
    pairs['_response_time'] = (time.time() - start_time) * 1000.0

    return pairs
    def get_redirect_url(self, *args, **kwargs):
        parse_result = urlparse(
            self.request.META.get('HTTP_REFERER',
                                  resolve_url(settings.LOGIN_REDIRECT_URL)))

        query_dict = parse_qs(parse_result.query)

        resolver_match = resolve(parse_result.path)

        # Default is to stay on the same view
        url = parse_result.path

        new_object = self.navigation_function()

        # Inject new_object pk in the referer's view pk or object_id kwargs
        if 'pk' in resolver_match.kwargs:
            resolver_match.kwargs['pk'] = new_object.pk
            url = reverse(resolver_match.view_name,
                          kwargs=resolver_match.kwargs)
        elif 'object_id' in resolver_match.kwargs:
            resolver_match.kwargs['object_id'] = new_object.pk
            url = reverse(resolver_match.view_name,
                          kwargs=resolver_match.kwargs)
        else:
            messages.warning(
                self.request,
                _('Unknown view keyword argument schema, unable to '
                  'redirect.'))

        return '{}?{}'.format(url, urlencode(query_dict, doseq=True))
def _decode_cursor(encoded):
    """
    Given a string representing an encoded cursor, return a `Cursor` instance.
    """

    # The offset in the cursor is used in situations where we have a
    # nearly-unique index. (Eg millisecond precision creation timestamps)
    # We guard against malicious users attempting to cause expensive database
    # queries, by having a hard cap on the maximum possible size of the offset.
    OFFSET_CUTOFF = 1000

    try:
        querystring = b64decode(encoded.encode('ascii')).decode('ascii')
        tokens = urlparse.parse_qs(querystring, keep_blank_values=True)

        offset = tokens.get('o', ['0'])[0]
        offset = _positive_int(offset, cutoff=OFFSET_CUTOFF)

        reverse = tokens.get('r', ['0'])[0]
        reverse = bool(int(reverse))

        position = tokens.get('p', [None])[0]
    except (TypeError, ValueError):
        return None

    return Cursor(offset=offset, reverse=reverse, position=position)
    def decode_cursor(self, request):
        """
        Given a request with a cursor, return a `Cursor` instance.

        Differs from the standard CursorPagination to handle a tuple in the
        position field.
        """
        # Determine if we have a cursor, and if so then decode it.
        encoded = request.query_params.get(self.cursor_query_param)
        if encoded is None:
            return None

        try:
            querystring = b64decode(encoded.encode('ascii')).decode('ascii')
            tokens = urlparse.parse_qs(querystring, keep_blank_values=True)

            offset = tokens.get('o', ['0'])[0]
            # This was hard-coded until Django REST Framework 3.4.0.
            try:
                offset_cutoff = self.offset_cutoff
            except AttributeError:
                offset_cutoff = 1000
            offset = _positive_int(offset, cutoff=offset_cutoff)

            reverse = tokens.get('r', ['0'])[0]
            reverse = bool(int(reverse))

            # The difference. Don't get just the 0th entry: get all entries.
            position = tokens.get('p', None)
        except (TypeError, ValueError):
            raise NotFound(self.invalid_cursor_message)

        return Cursor(offset=offset, reverse=reverse, position=position)
Example #30
0
    def test_logout(self):
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )
        self.do_login()

        response = self.client.get(reverse('saml2_logout'))
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path,
                         '/simplesaml/saml2/idp/SingleLogoutService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)

        saml_request = params['SAMLRequest'][0]

        if 'LogoutRequest xmlns' not in decode_base64_and_inflate(
                saml_request).decode('utf-8'):
            raise Exception('Not a valid LogoutRequest')
 def test_nested_resources(self):
   self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
   zoo = build('zoo', 'v1', http=self.http)
   self.assertTrue(getattr(zoo, 'animals'))
   request = zoo.my().favorites().list(max_results="5")
   parsed = urlparse(request.uri)
   q = parse_qs(parsed[4])
   self.assertEqual(q['max-results'], ['5'])
  def test_string_params_value_of_none_get_dropped(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.query(trace=None, fields='description')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertFalse('trace' in q)
 def test_top_level_functions(self):
   self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
   zoo = build('zoo', 'v1', http=self.http)
   self.assertTrue(getattr(zoo, 'query'))
   request = zoo.query(q="foo")
   parsed = urlparse(request.uri)
   q = parse_qs(parsed[4])
   self.assertEqual(q['q'], ['foo'])
Example #34
0
 def test_only_without(self):
     context = Context({"request": build_request("/?a=b&name=dog&c=5"), "a_var": "a"})
     template = Template(
         "{% load django_tables2 %}" '<b>{% querystring without "a" "name" %}</b>'
     )
     url = parse(template.render(context)).text
     qs = parse_qs(url[1:])  # trim the ?
     self.assertEqual(set(qs.keys()), set(["c"]))
Example #35
0
 def get_title_from_url(url):
     """Get title from url"""
     if not url:
         return
     parsed_url = urlparse(url)
     query = parse_qs(parsed_url.query)
     if 'title' in query:
         return query['title'][0]
  def test_optional_stack_query_parameters(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.query(trace='html', fields='description')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['trace'], ['html'])
    self.assertEqual(q['fields'], ['description'])
  def test_model_added_query_parameters(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.animals().get(name='Lion')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['alt'], ['json'])
    self.assertEqual(request.headers['accept'], 'application/json')
  def test_fallback_to_raw_model(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.animals().getmedia(name='Lion')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertTrue('alt' not in q)
    self.assertEqual(request.headers['accept'], '*/*')
 def test_next_successful_with_next_page_token(self):
   self.http = HttpMock(datafile('tasks.json'), {'status': '200'})
   tasks = build('tasks', 'v1', http=self.http)
   request = tasks.tasklists().list()
   next_request = tasks.tasklists().list_next(
       request, {'nextPageToken': '123abc'})
   parsed = list(urlparse(next_request.uri))
   q = parse_qs(parsed[4])
   self.assertEqual(q['pageToken'][0], '123abc')
def test_querystring_templatetag_supports_without():
    context = Context({
        'request': build_request('/?a=b&name=dog&c=5'),
        'a_var': 'a',
    })

    template = Template('{% load django_tables2 %}'
                        '<b>{% querystring "name"="Brad" without a_var %}</b>')
    url = parse(template.render(context)).text
    qs = parse_qs(url[1:])  # trim the ?
    assert set(qs.keys()) == set(['name', 'c'])

    # Try with only exclusions
    template = Template('{% load django_tables2 %}'
                        '<b>{% querystring without "a" "name" %}</b>')
    url = parse(template.render(context)).text
    qs = parse_qs(url[1:])  # trim the ?
    assert set(qs.keys()) == set(["c"])
def test_querystring_templatetag_supports_without():
    context = Context({
        "request": build_request('/?a=b&name=dog&c=5'),
        "a_var": "a",
    })

    template = Template('{% load django_tables2 %}'
                        '<b>{% querystring "name"="Brad" without a_var %}</b>')
    url = parse(template.render(context)).text
    qs = parse_qs(url[1:])  # trim the ?
    assert set(qs.keys()) == set(["name", "c"])

    # Try with only exclusions
    template = Template('{% load django_tables2 %}'
                        '<b>{% querystring without "a" "name" %}</b>')
    url = parse(template.render(context)).text
    qs = parse_qs(url[1:])  # trim the ?
    assert set(qs.keys()) == set(["c"])
 def _check_query_types(self, request):
   parsed = urlparse(request.uri)
   q = parse_qs(parsed[4])
   self.assertEqual(q['q'], ['foo'])
   self.assertEqual(q['i'], ['1'])
   self.assertEqual(q['n'], ['1.0'])
   self.assertEqual(q['b'], ['false'])
   self.assertEqual(q['a'], ['[1, 2, 3]'])
   self.assertEqual(q['o'], ['{\'a\': 1}'])
   self.assertEqual(q['e'], ['bar'])
 def test_only_without(self):
     context = Context({
         'request': build_request('/?a=b&name=dog&c=5'),
         'a_var': 'a',
     })
     template = Template('{% load django_tables2 %}'
                         '<b>{% querystring without "a" "name" %}</b>')
     url = parse(template.render(context)).text
     qs = parse_qs(url[1:])  # trim the ?
     self.assertEqual(set(qs.keys()), set(["c"]))
Example #44
0
    def test_construct_with_per_page(self):
        """Testing APIPaginator construction with per_page=<value>"""
        url = 'http://example.com/api/list/?foo=1'
        paginator = DummyAPIPaginator(None, url, per_page=10)

        parts = urlsplit(paginator.url)
        query_params = parse_qs(parts[3])

        self.assertEqual(query_params['foo'], ['1'])
        self.assertEqual(query_params['per-page'], ['10'])
Example #45
0
    def _add_query_params(self, url, new_query_params):
        """Adds query parameters onto the given URL."""
        scheme, netloc, path, query_string, fragment = urlsplit(url)
        query_params = parse_qs(query_string)
        query_params.update(new_query_params)
        new_query_string = urlencode([(key, value) for key, value in sorted(
            six.iteritems(query_params), key=lambda i: i[0])],
                                     doseq=True)

        return urlunsplit((scheme, netloc, path, new_query_string, fragment))
Example #46
0
def test_sp_initiated_login_discovery_service(private_settings, client):
    private_settings.MELLON_DISCOVERY_SERVICE_URL = 'https://disco'
    response = client.get('/login/')
    assert response.status_code == 302
    params = parse_qs(urlparse(response['Location']).query)
    assert response['Location'].startswith('https://disco?')
    assert params == {
        'return': ['http://testserver/login/?nodisco=1'],
        'entityID': ['http://testserver/metadata/']
    }
Example #47
0
def remove_query_param(url, key):
    """
    Given a URL and a key/val pair, remove an item in the query
    parameters of the URL, and return the new URL.
    """
    (scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
    query_dict = urlparse.parse_qs(query)
    query_dict.pop(key, None)
    query = urlparse.urlencode(sorted(list(query_dict.items())), doseq=True)
    return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
Example #48
0
def replace_query_param(url, key, val):
    """
    Given a URL and a key/val pair, set or replace an item in the query
    parameters of the URL, and return the new URL.
    """
    (scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
    query_dict = urlparse.parse_qs(query, keep_blank_values=True)
    query_dict[key] = [val]
    query = urlparse.urlencode(sorted(list(query_dict.items())), doseq=True)
    return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
Example #49
0
def remove_query_param(url, key):
    """
    Given a URL and a key/val pair, remove an item in the query
    parameters of the URL, and return the new URL.
    """
    (scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
    query_dict = urlparse.parse_qs(query)
    query_dict.pop(key, None)
    query = urlparse.urlencode(sorted(list(query_dict.items())), doseq=True)
    return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
  def test_full_featured(self):
    # Zoo should exercise all discovery facets
    # and should also have no future.json file.
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    self.assertTrue(getattr(zoo, 'animals'))

    request = zoo.animals().list(name='bat', projection="full")
    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['name'], ['bat'])
    self.assertEqual(q['projection'], ['full'])
Example #51
0
    def test_config_url(self):
        with override_settings(OTP_TOTP_ISSUER=None):
            url = self.device.config_url

        parsed = urlsplit(url)
        params = parse_qs(parsed.query)

        self.assertEqual(parsed.scheme, 'otpauth')
        self.assertEqual(parsed.netloc, 'totp')
        self.assertEqual(parsed.path, '/alice')
        self.assertIn('secret', params)
        self.assertNotIn('issuer', params)
Example #52
0
    def test_config_url_issuer(self):
        with override_settings(OTP_HOTP_ISSUER='example.com'):
            url = self.device.config_url

        parsed = urlsplit(url)
        params = parse_qs(parsed.query)

        self.assertEqual(parsed.scheme, 'otpauth')
        self.assertEqual(parsed.netloc, 'hotp')
        self.assertEqual(parsed.path, '/example.com%3Aalice')
        self.assertIn('secret', params)
        self.assertIn('issuer', params)
Example #53
0
    def test_login_one_idp(self):
        # monkey patch SAML configuration
        settings.SAML_CONFIG = conf.create_conf(
            sp_host='sp.example.com',
            idp_hosts=['idp.example.com'],
            metadata_file='remote_metadata_one_idp.xml',
        )

        response = self.client.get(reverse('saml2_login'))
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)
        self.assertIn('RelayState', params)

        saml_request = params['SAMLRequest'][0]
        if 'AuthnRequest xmlns' not in decode_base64_and_inflate(
                saml_request).decode('utf-8'):
            raise Exception('Not a valid AuthnRequest')

        # if we set a next arg in the login view, it is preserverd
        # in the RelayState argument
        next = '/another-view/'
        response = self.client.get(reverse('saml2_login'), {'next': next})
        self.assertEqual(response.status_code, 302)
        location = response['Location']

        url = urlparse(location)
        self.assertEqual(url.hostname, 'idp.example.com')
        self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')

        params = parse_qs(url.query)
        self.assertIn('SAMLRequest', params)
        self.assertIn('RelayState', params)
        self.assertEqual(params['RelayState'][0], next)
Example #54
0
    def test_config_url_issuer_spaces(self):
        with override_settings(OTP_TOTP_ISSUER='Very Trustworthy Source'):
            url = self.device.config_url

        parsed = urlsplit(url)
        params = parse_qs(parsed.query)

        self.assertEqual(parsed.scheme, 'otpauth')
        self.assertEqual(parsed.netloc, 'totp')
        self.assertEqual(parsed.path, '/Very%20Trustworthy%20Source%3Aalice')
        self.assertIn('secret', params)
        self.assertIn('issuer', params)
        self.assertEqual(params['issuer'][0], 'Very Trustworthy Source')
Example #55
0
 def test_email_alert_sent(self):
     root = self.create_thread_for_user(self.sender, self.recipient)
     from django.core.mail import outbox
     self.assertEqual(len(outbox), 1)
     self.assertEqual(len(outbox[0].recipients()), 1)
     self.assertEqual(outbox[0].recipients()[0], self.recipient.email)
     html_message = get_html_message(outbox[0])
     self.assertTrue(root.text in html_message)
     soup = BeautifulSoup(html_message)
     links = soup.find_all('a', attrs={'class': 'thread-link'})
     self.assertEqual(len(links), 1)
     parse_result = urlparse(links[0]['href'])
     query = parse_qs(parse_result.query.replace('&amp;', '&'))
     self.assertEqual(query['thread_id'][0], str(root.id))
Example #56
0
    def _add_query_params(self, url, new_query_params):
        """Adds query parameters onto the given URL."""
        scheme, netloc, path, query_string, fragment = urlsplit(url)
        query_params = parse_qs(query_string)
        query_params.update(new_query_params)
        new_query_string = urlencode(
            [
                (key, value)
                for key, value in sorted(six.iteritems(query_params),
                                         key=lambda i: i[0])
            ],
            doseq=True)

        return urlunsplit((scheme, netloc, path, new_query_string, fragment))
Example #57
0
def replace_query_param(url, key, val):
    """
    Given a URL and a key/val pair, set or replace an item in the query
    parameters of the URL, and return the new URL.

    Forked from rest_framework.utils.urls; overwriten here because we
    need to pass keep_blank_values=True to urlparse.parse_qs() so that
    it doesn't remove the ?filter[id__in]= blank query parameter from
    our links in the case of an empty remote to-many link.
    """
    (scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
    query_dict = urlparse.parse_qs(query, keep_blank_values=True)
    query_dict[key] = [val]
    query = urlparse.urlencode(sorted(list(query_dict.items())), doseq=True)
    return urlparse.urlunsplit((scheme, netloc, path, query, fragment))